本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7594903
建立时间:2006年5月29日




[Spring]Spring in Action笔记(II)--Derby(JavaDB)数据库
软件技术

lhwork 发表于 2006/7/14 10:21:08

    今天来看看使用JDBC来操作数据: 使用的是Derby(JavaDB)数据库,关于JavaDB的介绍请点击这里:   http://blog.matrix.org.cn/page/icess?catname=%2FJavaDB    。 下面建立一个DatabaseUtils.java的工具类,来操作数据库 。该类在上面的连接的文章中有讲述。package  test.jdbc;import  java.io.File;import  java.io.IOException;import  java.io.InputStream;import  java.sql.Connection;import  java.sql.DriverManager;import  java.sql.PreparedStatement;import  java.sql.ResultSet;import  java.sql.SQLException;import  java.sql.Statement;import  java.util.Properties;import  java.util.logging.Logger;public class  DatabaseUtils {   private static final  String DB_PROPERTIES_FILE =  "jdbc.properties" ;   private static final  String DB_OPPOSITE_LOCATION =  "/.test" ;   static  Logger logger = Logger.getLogger(DatabaseUtils. class .getName());   private  Connection dbConnection;   private  Properties dbProperties;   private boolean  isConnected;   // database name   private  String dbName;   private static final  String strCreateTestClobTeble =  "CREATE TABLE APP.test (id INT, name VARCHAR(30),text CLOB(64 K))" ;   private static final  String strInsertIntoTestTeble =  "INSERT INTO APP.test (id, name)  VALUES (?, ?)" ;   public static final  String strGetTest =  "SELECT * FROM APP.test WHERE ID = ?" ;   private static final  String strCreateCourseTable =  "create table APP.Course ("       +  "    ID          INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),"       +  "    name    VARCHAR(30), "       +  "    description  VARCHAR(30), "       +  "    startDate  DATE, "  +  "    endDate     DATE "  +  ")" ;   private static final  String strCreateStudentTable =  "create table APP.ADDRESS ("       +  "    ID          INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),"       +  "    LASTNAME    VARCHAR(30), "       +  "    FIRSTNAME   VARCHAR(30), "       +  "    MIDDLENAME  VARCHAR(30), "       +  "    PHONE       VARCHAR(20), "       +  "    EMAIL       VARCHAR(30), "       +  "    ADDRESS1    VARCHAR(30), "       +  "    ADDRESS2    VARCHAR(30), "       +  "    CITY        VARCHAR(30), "       +  "    STATE       VARCHAR(30), "  +  ")" ;   public  DatabaseUtils() {     this ( "test" );   }   public  DatabaseUtils(String dbName) {     this .dbName = dbName;     setDBSystemDir();     dbProperties = loadDBProperties();     String driverName = dbProperties.getProperty( "db.driver" );     loadDatabaseDriver(driverName);     if  (!dbExists()) {       createDatabase();     }   }   private  Properties loadDBProperties() {     InputStream dbPropInputStream =  null ;     dbPropInputStream = DatabaseUtils. class         .getResourceAsStream(DB_PROPERTIES_FILE);     dbProperties =  new  Properties();     try  {       dbProperties.load(dbPropInputStream);     }  catch  (IOException e) {       e.printStackTrace();     }     return  dbProperties;   }   private void  setDBSystemDir() {     String userDir = System.getProperty( "user.dir" ,  "." );     String systemDir = userDir + DB_OPPOSITE_LOCATION;     System.setProperty( "derby.system.home" , systemDir);     // create the db System dir     File fileSystemDir =  new  File(systemDir);     fileSystemDir.mkdir();   }   private void  loadDatabaseDriver(String driverName) {     try  {       Class.forName(driverName);     }  catch  (ClassNotFoundException e) {       e.printStackTrace();     }   }   private boolean  dbExists() {     boolean  bExists =  false ;     String dbLocation = getDatabaseLocation();     File dbFileDir =  new  File(dbLocation);     if  (dbFileDir.exists()) {       bExists =  true ;     }     return  bExists;   }   private boolean  createDatabase() {     boolean  bCreated =  false ;     Connection dbConnection =  null ;     String dbUrl = getDatabaseUrl();     dbProperties.put( "create" ,  "true" );     try  {       dbConnection = DriverManager.getConnection(dbUrl, dbProperties);       bCreated = createTables(dbConnection, strCreateTestClobTeble);     }  catch  (SQLException e) {       e.printStackTrace();     }     dbProperties.remove( "create" );     return  bCreated;   }   private boolean  createTables(Connection dbConnection, String creatTableSql) {     boolean  bCreatedTables =  false ;     Statement statement =  null ;     try  {       statement = dbConnection.createStatement();       statement.execute(creatTableSql);       bCreatedTables =  true ;     }  catch  (SQLException e) {       e.printStackTrace();     }     return  bCreatedTables;   }   public  String getDatabaseUrl() {     return  dbProperties.getProperty( "db.url" ) + dbName;   }   public  String getDatabaseLocation() {     String dbLocation = System.getProperty( "derby.system.home" ) +  "/"         + dbName;     return  dbLocation;   }   public boolean  connect() {     String dbUrl = getDatabaseUrl();     try  {       logger.info( "DBUrl: "  + dbUrl);       dbConnection = DriverManager.getConnection(dbUrl, dbProperties);       isConnected = dbConnection !=  null ;     }  catch  (SQLException e) {       // TODO Auto-generated catch block       e.printStackTrace();       isConnected =  false ;       logger.info( "create connection if failed!" );     }     return  isConnected;   }   public  Connection getConnection() {     return  dbConnection;   }   public void  disconnect() {     if  (isConnected) {       String dbUrl = getDatabaseUrl();       dbProperties.put( "shutdown" ,  "true" );       try  {         System.out.println( "断开数据库连接????????????????" );         DriverManager.getConnection(dbUrl, dbProperties);         System.out.println( "????????????????" );       }  catch  (SQLException e) {         // e.printStackTrace();         logger.info( "disconnect the connection Successful!" );       }       isConnected =  false ;     }   }   /**    *  @param  args    */   public static void  main(String[] args) {     // TODO Auto-generated method stub     DatabaseUtils testdb =  new  DatabaseUtils();     logger.info(testdb.getDatabaseLocation());     logger.info(testdb.getDatabaseUrl());     testdb.connect();     Connection c = testdb.getConnection();     PreparedStatement ps =  null ;     try  {       ps = c.prepareStatement(DatabaseUtils.strInsertIntoTestTeble, Statement.RETURN_GENERATED_KEYS);       ps.setInt( 1 ,  1 );       ps.setString( 2 ,  "test Icerain" );       int  i =ps.executeUpdate();       System.out.println(i);       ps.close();             ps = c.prepareStatement(DatabaseUtils.strGetTest);       ps.setInt( 1 ,  1 );       ResultSet rs = ps.executeQuery();       if (rs.next()) {         String name = rs.getString( 2 );         System.out.println(name);       }       ps.close();     }  catch  (SQLException e) {       // TODO Auto-generated catch block       e.printStackTrace();     }     testdb.disconnect();   }} 下面是一个插入数据的类 InsertData.javapackage  test.jdbc;import  java.sql.Types;import  javax.sql.DataSource;import  org.springframework.jdbc.core.SqlParameter;import  org.springframework.jdbc.object.SqlUpdate;public class  InsertData  extends  SqlUpdate {   // 需要注入一个DataSource...   public  InsertData(DataSource ds) {     setDataSource(ds);   // TODO 注意 设置数据源     setSql( "INSERT INTO APP.test (id, name)  VALUES (?, ?)" );     declareParameter( new  SqlParameter(Types.INTEGER));     declareParameter( new  SqlParameter(Types.VARCHAR));         compile(); // TODO 注意 , 要编译以后才可以使用   }     // 覆盖insert方法   public int  insert(TestData data) {     Object[] params =  new  Object[] {data.id,data.name};     return  update(params);   // 执行插入操作....   }}很简单, 并带有详细注释.下面是一个查询的类 QueryDataById.javapackage  test.jdbc;import  java.sql.ResultSet;import  java.sql.SQLException;import  java.sql.Types;import  javax.sql.DataSource;import  org.springframework.jdbc.core.SqlParameter;import  org.springframework.jdbc.object.MappingSqlQuery;public class  QueryDataById  extends  MappingSqlQuery{   private static final  String sql =  "SELECT * FROM APP.test WHERE ID = ?" ;   public  QueryDataById(DataSource ds) {     super (ds,sql);     declareParameter( new  SqlParameter( "id" ,Types.INTEGER));     compile();   }   // 覆盖mapRow方法   @Override   protected  Object mapRow(ResultSet rs,  int  index)  throws  SQLException {     // TODO Auto-generated method stub     TestData tdata =  new  TestData();     tdata.id = rs.getInt( 1 );     tdata.name = rs.getString( 2 );         return  tdata;   }  } 也很简单.注意: 以上两个类都实现了Spring简化Jdbc操作的一些接口, 关于接口的信息请查考文档, 这里不在详细讲述. 下面是一个很简单的测试(数据)实体类.TestData.javapackage  test.jdbc;public class  TestData {   public int  id;   public  String name;   public  TestData( int  id, String name) {     this .id = id;     this .name = name;   }   public  TestData() {}}下面是一个测试数据源是否注入正确的类:TestDataSource.javapackage  test.jdbc;import  java.sql.Connection;import  java.sql.PreparedStatement;import  java.sql.ResultSet;import  javax.sql.DataSource;public class  TestDataSource {   private  DataSource dataSource; // 注入数据源   public void  setDataSource(DataSource dataSource) {     this .dataSource = dataSource;   } //测试数据源   public void  testDataSource() {     try  {       System.out.println( "Test DataSource!!!" );       Connection connection = dataSource.getConnection();       if  (connection !=  null )         System.out.println( "test ok!" );             PreparedStatement ps =  null ;       ps = connection.prepareStatement(DatabaseUtils.strGetTest);       ps.setInt( 1 ,  1 );       ResultSet rs = ps.executeQuery();       if (rs.next()) {         String name = rs.getString( 2 );         System.out.println( "测试数据源配置:"  + name);       }       ps.close();     }  catch  (Exception e) {       e.printStackTrace();     }   }}下面是测试Spring提高的Jdbc功能的主要测试类, 测试了一些使用JDBC操作数据的常用功能, 其他没有测试的请查看其Doc,TestJdbcTemplate.javapackage  test.jdbc;import  java.sql.CallableStatement;import  java.sql.PreparedStatement;import  java.sql.ResultSet;import  java.sql.SQLException;import  java.sql.Types;import  java.util.List;import  org.springframework.dao.DataAccessException;import  org.springframework.jdbc.core.BatchPreparedStatementSetter;import  org.springframework.jdbc.core.CallableStatementCallback;import  org.springframework.jdbc.core.JdbcTemplate;import  org.springframework.jdbc.core.RowCallbackHandler;import  org.springframework.jdbc.core.RowMapper;import  org.springframework.jdbc.core.RowMapperResultSetExtractor;public class  TestJdbcTemplate {   public static final  String strGetTest =  "SELECT * FROM APP.test WHERE ID = ?" ;   private static final  String strInsertIntoTestTeble =  "INSERT INTO APP.test (id, name)  VALUES (?, ?)" ;     private  JdbcTemplate jdbcTemplate;     public  TestJdbcTemplate() {}   public  TestJdbcTemplate(JdbcTemplate jdbcTemplate) {     this .jdbcTemplate = jdbcTemplate;   }   public  JdbcTemplate getJdbcTemplate() {     return  jdbcTemplate;   }   public void  setJdbcTemplate(JdbcTemplate jdbcTemplate) {     this .jdbcTemplate = jdbcTemplate;   }     /**  测试 插入数据*/   public void  insertTestData( int  id,String name) {     Object[] params =  new  Object[] {id,name};     jdbcTemplate.update(strInsertIntoTestTeble, params);     System.out.println( "插入数据成功!" );   }   /**  测试 插入数据*/   public void  insertTestDataWithTypeChecked( int  id,String name) {     Object[] params =  new  Object[] {id,name};     int [] types =  new int [] {Types.INTEGER,Types.VARCHAR};     jdbcTemplate.update(strInsertIntoTestTeble, params, types);     System.out.println( "插入数据成功(with Types checked)!" );   }   /**  测试 批量插入数据*/   public void  insertTestDataByBatchInsert( final  List<TestData> datas) {     //构造 BatchPreparedStatementSetter     BatchPreparedStatementSetter setter =  new  BatchPreparedStatementSetter() {       public int  getBatchSize() {         return  datas.size();       }       public void  setValues(PreparedStatement ps,  int  index) {         TestData data = datas.get(index);         try  {           ps.setInt( 1 , data.id);    // 从1 开始......           ps.setString( 2 , data.name);         }  catch  (SQLException e) {           // TODO Auto-generated catch block           e.printStackTrace();         }       }     };     jdbcTemplate.batchUpdate(strInsertIntoTestTeble, setter);     System.out.println( "批量插入数据成功!" );   }   /**    * 测试 JdbcTemplate    *  @param  id    */   public void  getTestData( final int  id) {     final  Object[] params =  new  Object[] {id};         jdbcTemplate.query(strGetTest, params,  new  RowCallbackHandler() {       public void  processRow(ResultSet rs)  throws  SQLException {         // TODO Auto-generated method stub         System.out.println( "测试JdbcTemplate:: name:"  + rs.getString( 2 ));       }           });   }     /** 测试RowMapper 和 RowMapperResultReader 接口*/   public void  getDataUsingRowMapper( int  id) {     List datas = jdbcTemplate.query( "SELECT * FROM APP.test WHERE ID = "  + id,  new  RowMapper() {       // 实现RowMapper接口, 来映射每一行数据       public  Object mapRow(ResultSet rs,  int  index)  throws  SQLException {         // TODO Auto-generated method stub         System.out.println( "测试RowMapper 接口: name "  + rs.getString( 2 ));         return null ;       }           });     //datas 中保存查询结果     System.out.println(datas.size());   }     public  TestData getDataUsingRowMapperResultReader( final int  id) {     final  Object[] params =  new  Object[] {id};     // TODO 有问题.......     TestData data =  (TestData) jdbcTemplate.query(strGetTest,params,new RowMapperResultSetExtractor( new  RowMapper() {       public  Object mapRow(ResultSet rs,int index)  throws  SQLException {         TestData tdata =  new  TestData();         tdata.id = rs.getInt( 1 );         tdata.name = rs.getString( 2 );         return  tdata;       }     }));         return  data;   }     /** 测试调用存储过程..*/   public void  testCallableStatement() {     // 使用 CallableStatementCallback 回调接口 调用存储过程.     CallableStatementCallback cb =  new  CallableStatementCallback() {       public  Object doInCallableStatement(CallableStatement cs)  throws  SQLException, DataAccessException {         cs.execute();         return null ;       }     };     // GET_DATA 为存储过程名     jdbcTemplate.execute( "{ GET_DATA}" , cb);   }       // 用对象操作数据, 使用SqlUpdate接口. 见 InsertData 类,,,,,   // 有容器注入 InsertData.   private  InsertData insertData ;   public int  insertTestData(TestData data) {     return  insertData.insert(data);   }   public  InsertData getInsertData() {     return  insertData;   }   public void  setInsertData(InsertData insertData) {     this .insertData = insertData;   }   //测试插入数据   public void  insertDataUsingSqlUpdate(TestData data) {     insertData.insert(data);     System.out.println( "使用SqlUpdate接口插入数据 成功....." );   }     /** 和上面使用SqlUpdate接口一样 把操作创建为对象来操作*/   private  QueryDataById queryDataById;   public void  setQueryDataById(QueryDataById queryDataById) {     this .queryDataById = queryDataById;   }   //测试   public  TestData getDataUsingMappingSqlQuery( int  id) {     Object[] params =  new  Object[] {id};     return  (TestData) queryDataById.execute(params).get( 0 );   }   //使用上面两种方法来插入和查询数据,不用和JDBC API交互, 有Spring提供了   //中间代理层  }下面是函有main函数的 主类. TestApp.javapackage  test.jdbc;import  java.util.ArrayList;import  java.util.List;import  org.springframework.context.ApplicationContext;import  org.springframework.context.support.ClassPathXmlApplicationContext;public class  TestApp {   /**    *  @param  args    */   public static void  main(String[] args) {     DatabaseUtils dataUtils =  new  DatabaseUtils();     dataUtils.connect();     System.out.println( "Open database:!" );     // TODO Auto-generated method stub     //测试连接数据源 ......     ApplicationContext context =  new  ClassPathXmlApplicationContext( "test/jdbc/spring-traning.xml" );     /* 测试 DataSource 配置*/     TestDataSource ds = (TestDataSource) context.getBean( "dataBean" );     ds.testDataSource();     /* 测试JdbcTemplate 配置*/         TestJdbcTemplate tjt = (TestJdbcTemplate) context.getBean( "testJdbcTemplate" );     tjt.insertTestData( 2 ,  "test name2" );     tjt.insertTestDataWithTypeChecked( 3 ,  "test name 3" );     List<TestData> datas =  new  ArrayList<TestData>();     datas.add( new  TestData( 4 , "test name 4" ));     datas.add( new  TestData( 5 , "test name 5" ));     datas.add( new  TestData( 6 , "test name 6" ));     tjt.insertTestDataByBatchInsert(datas);     tjt.getTestData( 1 );     tjt.getTestData( 2 );     tjt.getTestData( 5 );     tjt.getDataUsingRowMapper( 5 );//TODO 类型转换错误.    TestData data = tjt.getDataUsingRowMapperResultReader(1);//    System.out.println("测试使用 RowMapperResultSetExtractor 读取一行数据: " + data.id + "::: name " + data.name);     TestData tdata =  new  TestData( 9 , "TestSqlUpdate." );     tjt.insertDataUsingSqlUpdate(tdata);   // 插入数据         tjt.getDataUsingRowMapper( 9 );  // 测试上面插入的数据是否成功             dataUtils.disconnect();   }} JDBC配置文件:jdbc.properties# Sample ResourceBundle properties filedb.username=addressuserdb.password=addressuserdb.driver=org.apache.derby.jdbc.EmbeddedDriverdb.url=jdbc : derby:db.table=testdb.schema=APPdb.urlName=jdbc : derby:test 最后是最重要的配置文件: spring-traning.xml<?xml version = "1.0" encoding = "UTF-8" ?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "spring-beans.dtd" ><beans >< bean id = "propertyConfigurer" class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >< property name = "location" >< value > test/jdbc/jdbc.properties </ value ></ property ></ bean ><!-- get dataSource,配置dataSource --><!-- 从JNDI得到DataSource --><!-- bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"><property name="jndiName"><value>java:comp/env/jdbc/myDataSource</value></property></bean> --><!-- 使用Spring中的 DriverManagerDataSource --><!-- bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName"><value>${db.driver}</value></property><property name="url"><value>${db.urlName}</value></property><property name="username"><value>${db.username}</value></property><property name="password"><value>${db.password}</value></property></bean --><!-- 使用DBCP dataSource -->< bean id = "dataSource" class = "org.apache.commons.dbcp.BasicDataSource" >< property name = "driverClassName" >< value > ${db.driver} </ value ></ property >< property name = "url" >< value > ${db.urlName} </ value ></ property >< property name = "username" >< value > ${db.username} </ value ></ property >< property name = "password" >< value > ${db.password} </ value ></ property ></ bean >< bean id = "dataBean" class = "test.jdbc.TestDataSource" >< property name = "dataSource" >< ref bean = "dataSource" /></ property ></ bean ><!-- ################################################################# --><!-- 配合DataSource测试JdbcTemplate -->< bean id = "jdbcTemplate" class = "org.springframework.jdbc.core.JdbcTemplate" >< property name = "dataSource" >< ref bean = "dataSource" /></ property ></ bean >< bean id = "testJdbcTemplate" class = "test.jdbc.TestJdbcTemplate" >< constructor-arg >< ref bean = "jdbcTemplate" /></ constructor-arg ><!-- 测试 SqlUpdate 接口... -->< property name = "insertData" >< ref bean = "insertDataUsingSqlUptate" /></ property ></ bean ><!-- 测试SqlUpdate......接口 -->< bean id = "insertDataUsingSqlUptate" class = "test.jdbc.InsertData" >< constructor-arg >< ref bean = "dataSource" /></ constructor-arg ></ bean ></beans > ok, Jdbc测试的代码就结束了.在这里主要学习了,Spring提高的使用Jdbc的一些包装类和接口, 来更方便的使用Jdbc操作数据, 不用些那么一些烦人的 try ... catch...... finally.....感觉使用Sprig效率是很好,代码看起来也很优美哦. 呵呵:ok ,今天就终结完了, 下一次看看在Spring中如何高效使用Hibernate吧, 下次见啦:


阅读全文(2519) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.344 second(s), page refreshed 144765023 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号