优化JDBC开发

Posted 牛穿疯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了优化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 }

 

 

 

 

 

 

 

以上是关于优化JDBC开发的主要内容,如果未能解决你的问题,请参考以下文章

优化JDBC开发

优化 C# 代码片段、ObservableCollection 和 AddRange

如何在片段中填充列表视图?

使用 C++ 反转句子中的每个单词需要对我的代码片段进行代码优化

如何优化C ++代码的以下片段 - 卷中的零交叉

JDBC优化策略总结