• 优化JDBC开发


    一、元数据

    元数据:数据库、表、列的定义信息

    1、DataBaseMetaData对象

    getURL():返回一个String类对象,代表数据库的URL

    getUserName():返回连接当前数据库管理系统的用户名。

    getDatabaseProductName():返回数据库的产品名称。

    getDatabaseProductVersion():返回数据库的版本号。

    getDriverName():返回驱动驱动程序的名称。

    getDriverVersion():返回驱动程序的版本号。

    isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。

     

     

     1 /**
     2      * 获取数据库的元数据
     3      * @throws SQLException 
     4      */
     5     @Test
     6     public void test1() throws SQLException{
     7         Connection con = JdbcUtils_DBCP.getConnection();
     8         
     9         //获取数据库的元数据
    10         DatabaseMetaData meta = con.getMetaData();
    11         //获取数据库的版本
    12         System.out.println(meta.getDatabaseMajorVersion());
    13         //获取数据库的产品名称
    14         System.out.println(meta.getDatabaseProductName());
    15         //获取数据库默认的隔离级别
    16         System.out.println(meta.getDefaultTransactionIsolation());
    17         
    18         /**
    19          * 结果:
    20          *     5
    21             MySQL
    22             2
    23          * 
    24          */
    25     }

     

     

    2、 ParameterMetaData对象

    PreparedStatement . getParameterMetaData()

    获得代表PreparedStatement元数据的ParameterMetaData对象。

    Select * from user where name=? And password=?

        ParameterMetaData对象

    getParameterCount()

    获得指定参数的个数

    getParameterType(int param)

     

    获得指定参数的sql类型

     1 /**
     2      * 获取参数元数据
     3      * @throws SQLException 
     4      */
     5     @Test
     6     public void test2() throws SQLException{
     7         Connection con = JdbcUtils_DBCP.getConnection();
     8         String sql = "insert into account(name,money) values(?,?)";
     9         //预编译sql语句
    10         PreparedStatement ps = con.prepareStatement(sql);
    11         //获取参数元数据
    12         ParameterMetaData meta = ps.getParameterMetaData();
    13         
    14         //获取参数的个数  结果:2
    15         System.out.println(meta.getParameterCount());
    16         
    17         //获取参数的类型
    18         System.out.println(meta.getParameterType(1));
    19     }
    20     

     

     

    3、ResultSetMetaData对象

    ResultSet. getMetaData()

    获得代表ResultSet对象元数据的ResultSetMetaData对象。

    ResultSetMetaData对象

    getColumnCount()

    返回resultset对象的列数

    getColumnName(int column)

    获得指定列的名称

    getColumnTypeName(int column)

     

    获得指定列的类型 

     

     

     1 /*
     2      * 获取结果集元数据
     3      */
     4     
     5     @Test
     6     public void test3() throws SQLException{
     7         Connection con = JdbcUtils_DBCP.getConnection();
     8         String sql = "select * from account";
     9         //预编译sql语句
    10         PreparedStatement ps = con.prepareStatement(sql);
    11         ResultSet rs = ps.executeQuery();
    12         
    13         //获取元数据
    14         ResultSetMetaData meta = rs.getMetaData();
    15         System.out.println(meta.getColumnCount());
    16         System.out.println(meta.getColumnName(1));
    17         System.out.println(meta.getColumnName(2));
    18         System.out.println(meta.getColumnName(3));
    19         
    20         //结果:id name money
    21     }

     

     

     二、对JDBC进行优化

    1、对增、删、改进行优化

    所有实体的CUD操作代码基本相同,仅仅发送给数据库的SQL语句不同而已,因此可以把CUD操作的所有相同代码抽取到工具类的一个update方法中,并定义参数接收变化的SQL语句。

     1 //优化JDBC的增、删、改
     2         /**
     3          * 
     4          * @param sql 接受参数
     5          * @param params 参数  替换掉sql语句的?号
     6          * @throws SQLException 
     7          */
     8         public static void create_delete_update(String sql,Object params[]) throws SQLException{
     9             Connection con = null;
    10             PreparedStatement st = null;
    11             ResultSet result = null;
    12             
    13             try{
    14                 con = getConnection();
    15                 st = con.prepareStatement(sql);
    16                 
    17                 //把sql的?号替换掉
    18                 for(int i=0;i<params.length;i++){
    19                     
    20                     //因为不清楚表的列数据是什么类型,所以用Object
    21                     st.setObject(i+1,params[i]);
    22                 }
    23                 
    24                 st.executeUpdate();
    25                 
    26             }finally{
    27                 release(con, st, result);
    28             }
    29         }

     

     

    2、对查找进行优化

      1     //优化sql查询
      2         public  static Object query(String sql,Object params[],ResultSetHandler handler) throws SQLException{
      3             Connection con = null;
      4             PreparedStatement st = null;
      5             ResultSet rs = null;
      6             try{
      7                 con = getConnection();
      8                 st = con.prepareStatement(sql);
      9                 //替代问号
     10                 for(int i=0;i<params.length;i++){
     11                     st.setObject(i+1, params[i]);
     12                 }
     13                 
     14                 //执行
     15                 rs = st.executeQuery();
     16                 
     17                 //由于不知道调用者怎么处理结果集,所有由调用者调用时传入一个处理器对象,调用处理器对象的处理方法
     18                 return handler.handler(rs);
     19             }finally{
     20                 release(con, st, rs);
     21             }
     22         }
     23         
     24 }
     25 
     26 
     27 //暴露接口
     28 interface ResultSetHandler{
     29     public Object handler(ResultSet rs);
     30 }
     31 
     32 //实现把结果封装到bean里面,适用于查找一条数据
     33 class BeanHandler implements ResultSetHandler{
     34     Class clazz;
     35     public BeanHandler(Class clazz){
     36         this.clazz  = clazz;
     37     }
     38     
     39     //处理方法,把数据封装到javabean
     40     public Object handler(ResultSet rs) {
     41         try {
     42             if(!rs.next()){
     43                 return null;
     44             }
     45             
     46             //创建封装结果的bean对象
     47             Object bean  = clazz.newInstance();
     48             
     49             //得到结果集数的元数据,已获取结果集的信息
     50             ResultSetMetaData meta = rs.getMetaData();
     51             
     52             //得到结果集的列数
     53             int count = meta.getColumnCount();
     54             
     55             //for循环赋值给bean对象
     56             for(int i=0;i<count;i++){
     57                 String name = meta.getColumnName(i+1);
     58                 Object value = rs.getObject(name);
     59                 
     60                 //反射出bean上与列名相应的属性
     61                 Field f = bean.getClass().getDeclaredField(name);
     62                 //由于属性是私有的,要把属性设置成可见的
     63                 f.setAccessible(true);
     64                 //设置属性
     65                 f.set(bean, value);
     66             }
     67             
     68             return bean;
     69         } catch (Exception e) {
     70             throw new RuntimeException(e);
     71         }
     72     }
     73 }
     74 
     75 //把结果封装到一个集合里面去
     76 class BeanListHandler implements ResultSetHandler{
     77     Class clazz;
     78     public BeanListHandler(Class clazz){
     79         this.clazz = clazz;
     80     }
     81     
     82     public Object handler(ResultSet rs){ 
     83         List list  = new ArrayList();
     84         try{
     85             while(rs.next()){
     86                 //创建bean对象
     87                 Object bean = clazz.newInstance();
     88                 ResultSetMetaData meta = rs.getMetaData();
     89                 
     90                 //获取列数
     91                 int count = meta.getColumnCount();
     92                 for(int i=0;i<count;i++){
     93                     //列名
     94                     String name = meta.getColumnName(i+1);
     95                     Object value = rs.getObject(name);
     96                     Field f = bean.getClass().getDeclaredField(name);
     97                     f.setAccessible(true);
     98                     f.set(bean, value);
     99                 }
    100                 list.add(bean);
    101             }
    102         }catch(Exception e){
    103             throw new RuntimeException(e);
    104         }
    105         return list;
    106     }
    107 }

     

     

     3、完整代码

      1 package com.utils;
      2 import java.io.InputStream;
      3 import java.lang.reflect.Field;
      4 import java.sql.Connection;
      5 import java.sql.DriverManager;
      6 import java.sql.PreparedStatement;
      7 import java.sql.ResultSet;
      8 import java.sql.ResultSetMetaData;
      9 import java.sql.SQLException;
     10 import java.sql.Statement;
     11 import java.util.ArrayList;
     12 import java.util.List;
     13 import java.util.Properties;
     14 import javax.sql.DataSource;
     15 import org.apache.commons.dbcp.BasicDataSourceFactory;
     16 
     17 public class DButils {
     18     
     19     //数据库连接池
     20         private static DataSource ds = null;
     21         static{
     22             try{
     23                 //读取配置文件
     24                 InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
     25                 Properties prop = new Properties();
     26                 prop.load(in);
     27                 BasicDataSourceFactory factory = new BasicDataSourceFactory();
     28                 //创建连接池
     29                 ds = factory.createDataSource(prop);
     30             }catch(Exception e){
     31                 throw new ExceptionInInitializerError(e);
     32             }
     33         }
     34         
     35         
     36         //获取连接
     37         public static Connection getConnection() throws SQLException{
     38             
     39             return ds.getConnection();
     40         }
     41         
     42         //释放资源
     43         public static void release(Connection con,Statement st,ResultSet result){
     44             if(result!=null){
     45                 try {
     46                     result.close();
     47                 } catch (Exception e) {
     48                     e.printStackTrace();
     49                 }
     50                 result = null;
     51             }
     52             
     53             if(st!=null){
     54                 try {
     55                     st.close();
     56                 } catch (Exception e) {
     57                     e.printStackTrace();
     58                 }
     59                 st = null;
     60             }
     61             
     62             if(con!=null){
     63                 try {
     64                     con.close();
     65                 } catch (Exception e) {
     66                     e.printStackTrace();
     67                 }
     68                 
     69             }
     70         }
     71         
     72         
     73         //优化JDBC的增、删、改
     74         /**
     75          * 
     76          * @param sql 接受参数
     77          * @param params 参数  替换掉sql语句的?号
     78          * @throws SQLException 
     79          */
     80         public static void create_delete_update(String sql,Object params[]) throws SQLException{
     81             Connection con = null;
     82             PreparedStatement st = null;
     83             ResultSet result = null;
     84             
     85             try{
     86                 con = getConnection();
     87                 st = con.prepareStatement(sql);
     88                 
     89                 //把sql的?号替换掉
     90                 for(int i=0;i<params.length;i++){
     91                     
     92                     //因为不清楚表的列数据是什么类型,所以用Object
     93                     st.setObject(i+1,params[i]);
     94                 }
     95                 
     96                 st.executeUpdate();
     97                 
     98             }finally{
     99                 release(con, st, result);
    100             }
    101         }
    102         
    103         
    104         //优化sql查询
    105         public  static Object query(String sql,Object params[],ResultSetHandler handler) throws SQLException{
    106             Connection con = null;
    107             PreparedStatement st = null;
    108             ResultSet rs = null;
    109             try{
    110                 con = getConnection();
    111                 st = con.prepareStatement(sql);
    112                 //替代问号
    113                 for(int i=0;i<params.length;i++){
    114                     st.setObject(i+1, params[i]);
    115                 }
    116                 
    117                 //执行
    118                 rs = st.executeQuery();
    119                 
    120                 //由于不知道调用者怎么处理结果集,所有由调用者调用时传入一个处理器对象,调用处理器对象的处理方法
    121                 return handler.handler(rs);
    122             }finally{
    123                 release(con, st, rs);
    124             }
    125         }
    126         
    127 }
    128 
    129 
    130 //暴露接口
    131 interface ResultSetHandler{
    132     public Object handler(ResultSet rs);
    133 }
    134 
    135 //实现把结果封装到bean里面,适用于查找一条数据
    136 class BeanHandler implements ResultSetHandler{
    137     Class clazz;
    138     public BeanHandler(Class clazz){
    139         this.clazz  = clazz;
    140     }
    141     
    142     //处理方法,把数据封装到javabean
    143     public Object handler(ResultSet rs) {
    144         try {
    145             if(!rs.next()){
    146                 return null;
    147             }
    148             
    149             //创建封装结果的bean对象
    150             Object bean  = clazz.newInstance();
    151             
    152             //得到结果集数的元数据,已获取结果集的信息
    153             ResultSetMetaData meta = rs.getMetaData();
    154             
    155             //得到结果集的列数
    156             int count = meta.getColumnCount();
    157             
    158             //for循环赋值给bean对象
    159             for(int i=0;i<count;i++){
    160                 String name = meta.getColumnName(i+1);
    161                 Object value = rs.getObject(name);
    162                 
    163                 //反射出bean上与列名相应的属性
    164                 Field f = bean.getClass().getDeclaredField(name);
    165                 //由于属性是私有的,要把属性设置成可见的
    166                 f.setAccessible(true);
    167                 //设置属性
    168                 f.set(bean, value);
    169             }
    170             
    171             return bean;
    172         } catch (Exception e) {
    173             throw new RuntimeException(e);
    174         }
    175     }
    176 }
    177 
    178 //把结果封装到一个集合里面去
    179 class BeanListHandler implements ResultSetHandler{
    180     Class clazz;
    181     public BeanListHandler(Class clazz){
    182         this.clazz = clazz;
    183     }
    184     
    185     public Object handler(ResultSet rs){ 
    186         List list  = new ArrayList();
    187         try{
    188             while(rs.next()){
    189                 //创建bean对象
    190                 Object bean = clazz.newInstance();
    191                 ResultSetMetaData meta = rs.getMetaData();
    192                 
    193                 //获取列数
    194                 int count = meta.getColumnCount();
    195                 for(int i=0;i<count;i++){
    196                     //列名
    197                     String name = meta.getColumnName(i+1);
    198                     Object value = rs.getObject(name);
    199                     Field f = bean.getClass().getDeclaredField(name);
    200                     f.setAccessible(true);
    201                     f.set(bean, value);
    202                 }
    203                 list.add(bean);
    204             }
    205         }catch(Exception e){
    206             throw new RuntimeException(e);
    207         }
    208         return list;
    209     }
    210 }
    211 
    212 
    213 
    214 
    215     

    测试:

      1 package com.utils;
      2 
      3 import java.sql.SQLException;
      4 import java.util.Iterator;
      5 import java.util.List;
      6 
      7 import org.junit.Test;
      8 
      9 import com.domain.Account;
     10 
     11 public class Demo {
     12     
     13     //测试添加
     14     @Test
     15     public void testAdd() throws SQLException{
     16         Account a = new Account();
     17         a.setName("陈海宏");
     18         a.setMoney(30);
     19         add(a);
     20     }
     21     
     22     @Test
     23     //测试删除
     24     public void testDelete() throws SQLException{
     25         delete(1);
     26     }
     27     
     28     @Test
     29     //测试更改
     30     public void testUpdate() throws SQLException{
     31         Account a = new Account();
     32         a.setId(2);
     33         a.setName("王五");
     34         a.setMoney(30);
     35         update(a);
     36     }
     37     
     38     @Test
     39     //测试查找单项记录
     40     public void testFind() throws SQLException{
     41         Account a = find(7);
     42         System.out.println(a.getName());
     43     }
     44     
     45     
     46     
     47     
     48     //测试查找单记录
     49     @Test
     50     public void testGetAll() throws SQLException{
     51         List list = getAll();
     52         //对集合进行迭代
     53         Iterator it = list.iterator();
     54         while(it.hasNext()){
     55             Account a = (Account) it.next();
     56             System.out.println(a.getId()+"+"+a.getName()+"+"+a.getMoney());
     57             
     58         }
     59     }
     60 
     61     
     62     
     63     //添加
     64     public void add(Account a) throws SQLException{
     65         
     66         //准备sql语句
     67         String sql = "insert into account(name,money) values(?,?)";
     68         //替换?的参数数据
     69         Object params[] = {a.getName(),a.getMoney()};
     70         DButils.create_delete_update(sql, params);
     71         
     72     }
     73     
     74     //删除
     75     public void delete(int id) throws SQLException{
     76         
     77         //准备sql语句
     78         String sql = "delete from account where id=?";
     79         //替换?的参数数据
     80         Object params[] = {id};
     81         DButils.create_delete_update(sql, params);
     82     }
     83     
     84     //更新
     85     public void update(Account a) throws SQLException{
     86         String sql = "update account set name = ?,money = ? where id=?";
     87         Object params[] = {a.getName(),a.getMoney(),a.getId()};
     88         DButils.create_delete_update(sql, params);
     89     }
     90     
     91     //查找单项记录
     92     public Account find(int i) throws SQLException{
     93         String sql = "select * from account where id=?";
     94         Object params[] = {i};
     95         return (Account) DButils.query(sql, params,new BeanHandler(Account.class));
     96     }
     97     
     98     //查找所有记录
     99         public List getAll() throws SQLException{
    100             String sql = "select * from account";
    101             Object params[] = {};
    102             return (List) DButils.query(sql, params,new BeanListHandler(Account.class));
    103         }
    104 }

     

     

     

     

     

     

  • 相关阅读:
    设计模式之策略模式
    assert断言——调试中不应该是syso
    Spring AOP
    MyBatis
    事务处理与使用连接池管理连接
    管理结果集(ResultSet)
    执行SQL语句的方式
    JDBC基础:
    NIO.2
    NIO
  • 原文地址:https://www.cnblogs.com/niuchuangfeng/p/9180835.html
Copyright © 2020-2023  润新知