编写自己的JDBC框架

1.目的:简化代码,提高开发效率

策略设计模式:

代码贴上:

 1 #连接设置
 2 driverClassName=com.mysql.jdbc.Driver
 3 url=jdbc:mysql://localhost:3306/day17
 4 username=root
 5 password=sorry
 6 
 7 #<!-- 初始化连接 -->
 8 initialSize=10
 9 
10 #最大连接数量
11 maxActive=50
12 
13 #<!-- 最大空闲连接 -->
14 maxIdle=20
15 
16 #<!-- 最小空闲连接 -->
17 minIdle=5
18 
19 #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
20 maxWait=60000
21 
22 
23 #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] 
24 #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
25 connectionProperties=useUnicode=true;characterEncoding=utf8
26 
27 #指定由连接池所创建的连接的自动提交(auto-commit)状态。
28 defaultAutoCommit=true
29 
30 #driver default 指定由连接池所创建的连接的只读(read-only)状态。
31 #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
32 defaultReadOnly=
33 
34 #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
35 #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
36 defaultTransactionIsolation=REPEATABLE_READ
dbcpconfig.properties
 1 import java.util.List;
 2 import org.junit.Test;
 3 import com.itheima.dbassist.BeanHandler;
 4 import com.itheima.dbassist.BeanListHandler;
 5 import com.itheima.dbassist.DBAssist;
 6 import com.itheima.domain.User;
 7 import com.itheima.util.DBCPUtil;
 8 
 9 public class UserDaoImpl {
10     private DBAssist da = new DBAssist(DBCPUtil.getDataSource());
11     //SQL和参数
12     @Test
13     public void add(){
14         da.update("insert into user values(?,?,?,?)", "aa","wf","123","非同寻常");
15     }
16     @Test
17     public void update(){
18         da.update("update user set password=? where id=?", "12345","aa");
19     }
20     @Test
21     public void delete(){
22         da.update("delete from user where id=?", "aa");
23     }
24     @Test
25     public void query1(){
26         User user = (User)da.query("select * from user where id=?", new BeanHandler(User.class), "a5cc6e18-f3b8-44a6-bcdd-c6476f1edb87");
27         System.out.println(user);
28     }
29     @Test
30     public void query2(){
31         List<User> users = (List<User>)da.query("select * from user", new BeanListHandler(User.class));
32         for(User user:users)
33             System.out.println(user);
34     }
35 }
UserDaoImpl
 1 import java.lang.reflect.Field;
 2 import java.sql.ResultSet;
 3 import java.sql.ResultSetMetaData;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 /**
 7  * 适合有多条结果记录的数据封装
 8  * 返回的是一个List
 9  *
10  */
11 public class BeanListHandler implements ResultSetHandler {
12     private Class clazz;
13     public BeanListHandler(Class clazz){
14         this.clazz = clazz;
15     }
16     public Object handle(ResultSet rs) {
17         try {
18             List list = new ArrayList();
19             while(rs.next()){
20                 Object bean = clazz.newInstance();
21                 //封装数据:书写JavaBean的前提,类中的字段名或属性名与数据库表的字段名保持一致
22                 ResultSetMetaData rsmd = rs.getMetaData();
23                 int columnCount = rsmd.getColumnCount();
24                 for(int i=0;i<columnCount;i++){
25                     String columnName = rsmd.getColumnName(i+1);//与JavaBean的字段名一致
26                     Object columnValue = rs.getObject(columnName);//列值
27                     
28                     //得到JavaBean的对应字段
29                     Field field = clazz.getDeclaredField(columnName);
30                     field.setAccessible(true);//强暴它 有可能是私有的
31                     field.set(bean, columnValue);
32                 }
33                 list.add(bean);
34                 
35             }
36             return list;
37         } catch (Exception e) {
38             throw new RuntimeException("封装数据失败");
39         }
40     }
41 }
BeanListHandler
  1 import java.sql.Connection;
  2 import java.sql.ParameterMetaData;
  3 import java.sql.PreparedStatement;
  4 import java.sql.ResultSet;
  5 import java.sql.SQLException;
  6 import java.sql.Statement;
  7 
  8 import javax.sql.DataSource;
  9 
 10 import com.itheima.util.DBCPUtil;
 11 
 12 public class DBAssist {
 13     private DataSource dataSource;
 14     public DBAssist(DataSource dataSource){
 15         this.dataSource = dataSource;
 16     }
 17     /*
 18      * 能够执行DML语句:INSERT UPDATE DELETE
 19      */
 20     public void update(String sql,Object...params){
 21         Connection conn = null;
 22         PreparedStatement stmt = null;
 23         ResultSet rs = null;
 24         try{
 25             conn = dataSource.getConnection();//具体的数据源无关
 26             stmt = conn.prepareStatement(sql);
 27             //看sql中的占位符的个数:参数元信息的获取
 28             ParameterMetaData pmd = stmt.getParameterMetaData();
 29             int paramCount = pmd.getParameterCount();
 30             //设置参数:略
 31             if(paramCount>0){
 32                 //判断参数占位符的个数和params的个数是否一致
 33                 if(params==null||params.length!=paramCount){
 34                     throw new RuntimeException("参数个数不匹配");
 35                 }
 36                 //设置SQL中的参数占位符的值
 37                 for(int i=0;i<paramCount;i++){
 38                     stmt.setObject(i+1, params[i]);
 39                 }
 40             }
 41             stmt.executeUpdate();
 42         }catch(Exception e){
 43             throw new RuntimeException(e);
 44         }finally{
 45             release(rs, stmt, conn);
 46         }
 47     }
 48     /**
 49      * 执行查询
 50      * @return 封装了数据的对象
 51      */
 52     public Object query(String sql,ResultSetHandler handler,Object...params){
 53         Connection conn = null;
 54         PreparedStatement stmt = null;
 55         ResultSet rs = null;
 56         try{
 57             conn = dataSource.getConnection();
 58             stmt = conn.prepareStatement(sql);
 59             //看sql中的占位符的个数:参数元信息的获取
 60             ParameterMetaData pmd = stmt.getParameterMetaData();
 61             int paramCount = pmd.getParameterCount();
 62             //设置参数:略
 63             if(paramCount>0){
 64                 //判断参数占位符的个数和params的个数是否一致
 65                 if(params==null||params.length!=paramCount){
 66                     throw new RuntimeException("参数个数不匹配");
 67                 }
 68                 //设置SQL中的参数占位符的值
 69                 for(int i=0;i<paramCount;i++){
 70                     stmt.setObject(i+1, params[i]);
 71                 }
 72             }
 73             rs = stmt.executeQuery();//如何封装呢:
 74                                         //有结果集:不知道有什么字段和值
 75                                         //不知道封装成什么对象:谁用谁知道
 76             
 77                                     //策略:有数据----->有目标
 78             return handler.handle(rs);
 79         }catch(Exception e){
 80             throw new RuntimeException(e);
 81         }finally{
 82             release(rs, stmt, conn);
 83         }
 84     }
 85     private void release(ResultSet rs,Statement stmt,Connection conn){
 86         if(rs!=null){
 87             try {
 88                 rs.close();
 89             } catch (SQLException e) {
 90                 e.printStackTrace();
 91             }
 92             rs = null;
 93         }
 94         if(stmt!=null){
 95             try {
 96                 stmt.close();
 97             } catch (SQLException e) {
 98                 e.printStackTrace();
 99             }
100             stmt = null;
101         }
102         if(conn!=null){
103             try {
104                 conn.close();
105             } catch (SQLException e) {
106                 e.printStackTrace();
107             }
108             conn = null;
109         }
110     }
111 }    
DBAssist
 1 package com.itheima.dbassist;
 2 
 3 import java.sql.ResultSet;
 4 //抽象策略
 5 public interface ResultSetHandler {
 6     /**
 7      *把结果集中的数据封装到对象中
 8      * @param rs
 9      * @return
10      */
11     Object handle(ResultSet rs);
12 }
ResultSetHandler
 1 import java.lang.reflect.Field;
 2 import java.sql.ResultSet;
 3 import java.sql.ResultSetMetaData;
 4 //策略的具体实现
 5 /**
 6  * 专门用于封装结果中只有一条的记录的情况
 7  * 返回值:封装好的Java对象
 8  *
 9  */
10 public class BeanHandler implements ResultSetHandler {
11     private Class clazz;
12     public BeanHandler(Class clazz){
13         this.clazz = clazz;
14     }
15     public Object handle(ResultSet rs) {
16         try {
17             if(rs.next()){
18                 Object bean = clazz.newInstance();
19                 //封装数据:书写JavaBean的前提,类中的字段名或属性名与数据库表的字段名保持一致
20                 ResultSetMetaData rsmd = rs.getMetaData();
21                 int columnCount = rsmd.getColumnCount();
22                 for(int i=0;i<columnCount;i++){
23                     String columnName = rsmd.getColumnName(i+1);//与JavaBean的字段名一致
24                     Object columnValue = rs.getObject(columnName);//列值
25                     
26                     //得到JavaBean的对应字段
27                     Field field = clazz.getDeclaredField(columnName);
28                     field.setAccessible(true);//强暴它 有可能是私有的
29                     field.set(bean, columnValue);
30                 }
31                 
32                 return bean;
33             }
34             return null;
35         } catch (Exception e) {
36             throw new RuntimeException("封装数据失败");
37         }
38     }
39 
40 }
BeanHandler
 1 public class User {
 2     private String id;
 3     private String username;
 4     private String password;
 5     private String nick;
 6     public String getId() {
 7         return id;
 8     }
 9     public void setId(String id) {
10         this.id = id;
11     }
12     public String getUsername() {
13         return username;
14     }
15     public void setUsername(String username) {
16         this.username = username;
17     }
18     public String getPassword() {
19         return password;
20     }
21     public void setPassword(String password) {
22         this.password = password;
23     }
24     public String getNick() {
25         return nick;
26     }
27     public void setNick(String nick) {
28         this.nick = nick;
29     }
30     @Override
31     public String toString() {
32         return "User [id=" + id + ", username=" + username + ", password="
33                 + password + ", nick=" + nick + "]";
34     }
35     
36 }
User
 1 import java.io.InputStream;
 2 import java.sql.Connection;
 3 import java.sql.ResultSet;
 4 import java.sql.SQLException;
 5 import java.sql.Statement;
 6 import java.util.Properties;
 7 
 8 import javax.sql.DataSource;
 9 
10 import org.apache.commons.dbcp.BasicDataSourceFactory;
11 
12 public class DBCPUtil {
13     private static DataSource dataSource;
14     static{
15         try {
16             InputStream in = DBCPUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
17             Properties props = new Properties();
18             props.load(in);
19             dataSource = BasicDataSourceFactory.createDataSource(props);
20         } catch (Exception e) {
21             throw new ExceptionInInitializerError("初始化数据源失败");
22         }
23     }
24     public static Connection getConnection(){
25         try {
26             return dataSource.getConnection();
27         } catch (SQLException e) {
28             throw new RuntimeException("获取数据库连接失败");
29         }
30     }
31     public static DataSource getDataSource(){
32         return dataSource;
33     }
34     
35 }
DBCPUtil

猜你喜欢

转载自www.cnblogs.com/biaogejiushibiao/p/9319101.html