zoukankan      html  css  js  c++  java
  • 编写JDBC框架:(策略设计模式)

    package com.itheima.domain;
    //一般:实体类的字段名和数据库表的字段名保持一致
    //约定优于编码
    public class Account {
        private int id;
        private String name;
        private float money;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public float getMoney() {
            return money;
        }
        public void setMoney(float money) {
            this.money = money;
        }
        @Override
        public String toString() {
            return "Account [id=" + id + ", name=" + name + ", money=" + money
                    + "]";
        }
        
    }
    package com.itheima.util;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Properties;
    
    import javax.sql.DataSource;
    
    import org.apache.commons.dbcp.BasicDataSourceFactory;
    
    public class DBCPUtil {
        private static DataSource dataSource;
        static{
            try {
                InputStream in = DBCPUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
                Properties props = new Properties();
                props.load(in);
                dataSource = BasicDataSourceFactory.createDataSource(props);
            } catch (Exception e) {
                throw new ExceptionInInitializerError(e);
            }
        }
        
        public static DataSource getDataSource(){
            return dataSource;
        }
        
        public static Connection getConnection(){
            try {
                return dataSource.getConnection();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
    package com.itheima.dbassist;
    
    import java.sql.ResultSet;
    
    public interface ResultSetHandler {
        /**
         * 把结果中的数据封装到指定的对象中
         * @param rs
         * @return 封装了数据的对象
         */
        Object handle(ResultSet rs);
    }
    package com.itheima.dbassist;
    
    import java.lang.reflect.Field;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    /**
     * 封装到JavaBean中
     * 满足约定:数据库字段名和JavaBean字段名保持一致
     * @author wzhting
     *
     */
    public class BeanListHanlder implements ResultSetHandler {
        
        private Class clazz;//目标类型
        public BeanListHanlder(Class clazz){
            this.clazz = clazz;
        }
    
        public Object handle(ResultSet rs) {
            try {
                List list = new ArrayList();
                while(rs.next()){
                    //有记录
                    Object bean = clazz.newInstance();//目标对象
                    //有多少列,列名和值又是什么?
                    ResultSetMetaData rsmd = rs.getMetaData();
                    int count = rsmd.getColumnCount();//列数
                    for(int i=0;i<count;i++){
                        String fieldName = rsmd.getColumnName(i+1);//得到数据库字段名,也就得到了JavaBan的字段名
                        Object fieldValue = rs.getObject(fieldName);//字段值
                        //通过字段反射
                        Field f = clazz.getDeclaredField(fieldName);
                        f.setAccessible(true);
                        f.set(bean, fieldValue);
                    }
                    list.add(bean);
                }
                return list;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
    }
    package com.itheima.dbassist;
    
    import java.lang.reflect.Field;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    /**
     * 适合只有一条查询结果的情况
     * 封装到JavaBean中
     * 满足约定:数据库字段名和JavaBean字段名保持一致
     * @author wzhting
     *
     */
    public class BeanHanlder implements ResultSetHandler {
        
        private Class clazz;//目标类型
        public BeanHanlder(Class clazz){
            this.clazz = clazz;
        }
    
        public Object handle(ResultSet rs) {
            try {
                if(rs.next()){
                    //有记录
                    Object bean = clazz.newInstance();//目标对象
                    //有多少列,列名和值又是什么?
                    ResultSetMetaData rsmd = rs.getMetaData();
                    int count = rsmd.getColumnCount();//列数
                    for(int i=0;i<count;i++){
                        String fieldName = rsmd.getColumnName(i+1);//得到数据库字段名,也就得到了JavaBan的字段名
                        Object fieldValue = rs.getObject(fieldName);//字段值
                        //通过字段反射
                        Field f = clazz.getDeclaredField(fieldName);
                        f.setAccessible(true);
                        f.set(bean, fieldValue);
                    }
                    return bean;
                }
                return null;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
    }
    package com.itheima.dbassist;
    
    import java.sql.Connection;
    import java.sql.ParameterMetaData;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import javax.sql.DataSource;
    
    /**
     * 框架的核心类
     * @author wzhting
     *
     */
    public class DBAssist {
        private DataSource dataSource;
        public DBAssist(DataSource dataSource){
            this.dataSource = dataSource;
        }
        //写:添加、删除、修改
        //params参数要和sql中的占位符对应
        public void update(String sql,Object...params) {
            Connection conn = null;
            PreparedStatement stmt = null;
            ResultSet rs = null;
            try{
                conn = dataSource.getConnection();
                stmt = conn.prepareStatement(sql);
                //设置参数
                    //得到sql中的参数
                    ParameterMetaData pmd = stmt.getParameterMetaData();
                    int count = pmd.getParameterCount();
                    if(count>0){
                        if(params==null){
                            throw new RuntimeException("必须传入参数的值");
                        }
                        if(count!=params.length){
                            throw new RuntimeException("参数数量不匹配");
                        }
                        for(int i=0;i<count;i++){
                            stmt.setObject(i+1, params[i]);
                        }
                        
                    }
                
                stmt.executeUpdate();
            }catch(Exception e){
                throw new RuntimeException(e);
            }finally{
                release(rs, stmt, conn);
            }
        }
        
        
        //读:查询
        public Object query(String sql,ResultSetHandler rsh,Object...params) {
            Connection conn = null;
            PreparedStatement stmt = null;
            ResultSet rs = null;
            try{
                conn = dataSource.getConnection();
                stmt = conn.prepareStatement(sql);
                //设置参数
                    //得到sql中的参数
                    ParameterMetaData pmd = stmt.getParameterMetaData();
                    int count = pmd.getParameterCount();
                    if(count>0){
                        if(params==null){
                            throw new RuntimeException("必须传入参数的值");
                        }
                        if(count!=params.length){
                            throw new RuntimeException("参数数量不匹配");
                        }
                        for(int i=0;i<count;i++){
                            stmt.setObject(i+1, params[i]);
                        }
                        
                    }
                
                rs = stmt.executeQuery();
                //有结果集,要封装到对象中。策略设计模式
                return rsh.handle(rs);
            }catch(Exception e){
                throw new RuntimeException(e);
            }finally{
                release(rs, stmt, conn);
            }
        }
        
        
        private void release(ResultSet rs,Statement stmt,Connection conn){
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                rs = null;
            }
            if(stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }
    }
    package com.itheima.test;
    
    import java.util.List;
    
    import org.junit.Test;
    
    import com.itheima.dbassist.BeanHanlder;
    import com.itheima.dbassist.BeanListHanlder;
    import com.itheima.dbassist.DBAssist;
    import com.itheima.domain.Account;
    import com.itheima.util.DBCPUtil;
    
    public class DBAssistTest {
        private DBAssist da = new DBAssist(DBCPUtil.getDataSource());
        @Test
        public void testAdd(){
            da.update("insert into account values (?,?,?)", 7,"ggg",1000);
        }
        @Test
        public void testUpdate(){
            da.update("update account set money=? where id=?", 10000,7);
        }
        @Test
        public void testDel(){
            da.update("delete from account where id=?",7);
        }
        @Test
        public void testQueryOne(){
            Object obj = da.query("select * from account where id=?",new BeanHanlder(Account.class),2);
            System.out.println(obj);
        }
        @Test
        public void testQueryAll(){
            List list = (List)da.query("select * from account",new BeanListHanlder(Account.class));
            for(Object o:list)
                System.out.println(o);
        }
    }
  • 相关阅读:
    bzoj3930 [CQOI2015]选数
    bzoj4916 神犇和蒟蒻
    bzoj3439 Kpm的MC密码
    bzoj2535 [Noi2010]航空管制
    bzoj2600 [Ioi2011]ricehub
    控制和机器学习书籍推荐
    圆周率100位可以这样速记
    从哥德巴赫说开去(3)
    第一届熊赛试题解答
    Mathematical Reflections
  • 原文地址:https://www.cnblogs.com/xiarongjin/p/8411120.html
Copyright © 2011-2022 走看看