Spring in Action 笔记(II)

Spring in Action 笔记 (II)

今天来看看使用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.java

package  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.java

package  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.java

package  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.java

package  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.java

package  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());
   }
#ffffff
分享到:
评论
icess
  • 浏览: 167854 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

你可能感兴趣的:(java,spring,sql,jdbc,Derby)