zoukankan      html  css  js  c++  java
  • 手把手教你如何自定义DAO框架(重量级干货)(yet)

    https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247484864&idx=2&sn=9721e840eab2b929e9523d82c45a1bb6&chksm=ebd63aecdca1b3fa998f27a185630f7e6b40564cf7cacec8e32818184fcf1d2e23d33757beee&mpshare=1&scene=1&srcid=0206Vt8xydSjEPcErB4rA2az&key=7a4fd26cfac6ce0520c3b75a31a96df31d4be437a8f3317af06cfc9c97b79ac5fbf1bdc6bd5d03aed3ab70644e57d1140efc6bdc63ad85edd4508daea3e8e113732c605adb68dc975c22022d8f989caf&ascene=0&uin=MTA2NzUxMDAyNQ%3D%3D&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.10.5+build(14F2511)&version=11020012&lang=zh_CN&pass_ticket=EVZTeGFk8lco7QnbdQu1aVcnN2PUGDc58FC5tG6YJ74SpwFYT%2BA%2BC4MKrc8qeCV1



    描述:本篇博客,主要是对于目前实际web项目开发中,对于数据库操作的一些基本方法的封装,通过这样的方式,可以使得开发更加简单,减少代码量,也便于维护和阅读。其中,主要是讲解了三种不同情况的封装方法,都是自身实际开发过程中,进行积累的,当然,还有很多不足之处,但是基本够项目的基本开发。


    一:非框架的DAO层封装

    其中包含的知识点:

    1:连接池

    2:数据源

    3:反射

    4:数据库元数据对象

    5:基本的jdbc知识


    封装步骤:


    (1)导入dbcp数据源包


    (2)编写properties文件,并且命令为dbcpconfig.properties

    #连接设置  
       driverClassName=com.mysql.jdbc.Driver  
       url=jdbc:mysql://localhost:3306/填写要使用的数据库  
       username=填写自己的mysql账号  
       password=填写自己的mysql密码  
         
       #<!-- 初始化连接 -->  
       initialSize=10  
         
       #最大连接数量  
       maxActive=50  
         
       #<!-- 最大空闲连接 -->  
       maxIdle=20  
         
       #<!-- 最小空闲连接 -->  
       minIdle=5  
         
       #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->  
       maxWait=60000  
         
         
       #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]   
       #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。  
       connectionProperties=useUnicode=true;characterEncoding=gbk  
         
       #指定由连接池所创建的连接的自动提交(auto-commit)状态。  
       defaultAutoCommit=true  
         
       #driver default 指定由连接池所创建的连接的只读(read-only)状态。  
       #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)  
       defaultReadOnly=false  
         
       #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。  
       #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE  
       defaultTransactionIsolation=READ_UNCOMMITTED


    (3)编写DBCP工具类

    public class DBCPUtils {  
       private static DataSource ds ;    
       static {  
           //将配置文件加载进来  
           InputStream in = DBCPUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties") ;  
           Properties props = new Properties() ;  
           try {  
               props.load(in) ;  
               ds = BasicDataSourceFactory.createDataSource(props) ;  
           } catch (Exception e) {  
               throw new RuntimeException("服务器忙") ;  
           }  
       }  
         
       //提供获取连接的方法  
       public static Connection getConnection(){  
           try {  
               return ds.getConnection() ;  
           } catch (SQLException e) {  
               throw new RuntimeException("服务器忙") ;  
           }  
       }  
    }


    (4)编写基本DAO层方法封装

    //自定义框架  
    public class BaseDao{  
     
       // 执行添改删语句  
       public boolean update(String sql, Object... params) {  
           // 拿到连接对象  
           Connection conn = DBCPUtils.getConnection();  
           int t = 0;  
           try {  
               // 创建预处理命令对象  
               PreparedStatement pstmt = conn.prepareStatement(sql);  
               // 对?进行赋值  
               // 获取ParameterMetaData对象  
               ParameterMetaData pmd = pstmt.getParameterMetaData();  
               // 拿到?的个数  
               int n = pmd.getParameterCount();  
               if (n > 0) {  
                   // sql语句里有?号  
                   if (params == null || params.length != n) {  
                       throw new RuntimeException("参数的个数不匹配");  
                   }  
                   // 依次给每个?赋值  
                   for (int i = 0; i < n; i++) {  
                       pstmt.setObject(i + 1, params[i]);  
                   }  
               }  
     
               t = pstmt.executeUpdate();  
           } catch (SQLException e) {  
               e.printStackTrace();  
           } finally {  
               try {  
                   conn.close(); // 还回池中了  
               } catch (SQLException e) {  
                   // TODO Auto-generated catch block  
                   e.printStackTrace();  
               }  
           }  
           return t > 0 ? true : false;  
       }  
     
       // 执行查询(返回的结果可能是一个或者多个,或者为null,这个就具体根据返回结果再进行处理即可)  
       public Object queryOne(String sql,Class clazz, Object... params) {  
           // 拿到连接对象  
           Connection conn = DBCPUtils.getConnection();  
           try {  
               // 创建预处理命令对象  
               PreparedStatement pstmt = conn.prepareStatement(sql);  
               // 对?进行赋值  
               // 获取ParameterMetaData对象  
               ParameterMetaData pmd = pstmt.getParameterMetaData();  
               // 拿到?的个数  
               int n = pmd.getParameterCount();  
               if (n > 0) {  
                   // sql语句里有?号  
                   if (params == null || params.length != n) {  
                       throw new RuntimeException("参数的个数不匹配");  
                   }  
                   // 依次给每个?赋值  
                   for (int i = 0; i < n; i++) {  
                       pstmt.setObject(i + 1, params[i]);  
                   }  
               }  
     
               ResultSet rs = pstmt.executeQuery();  
               //返回的结果可能是一个或者多个,或者为null  
               return new ResultSetListenerHandlerImpl().handler(rs, clazz) ;  
           } catch (SQLException e) {  
               throw new RuntimeException() ;  
           } finally {  
               try {  
                   conn.close(); // 还回池中了  
               } catch (SQLException e) {  
                   // TODO Auto-generated catch block  
                   e.printStackTrace();  
               }  
           }  
       }  
     
    }


    (5)查询返回结果集与实体bean的封装对象ResultSetListenerHandlerImpl

    //只适用于结果集有多条记录的情况  
    //对象的属性名和表中的字段名应当一致  
    public class ResultSetListenerHandlerImpl{  
       public Object handler(ResultSet rs, Class clazz) {        
           List<Object> list = new ArrayList<Object>() ;  
           //拿到结果集的元数据对象  
           try {  
               while(rs.next()){  
                   ResultSetMetaData rsmd = rs.getMetaData() ;  
                   //拿到公有多少列  
                   int columnCount = rsmd.getColumnCount() ;  
                   //先创建对象  
                   Object obj = clazz.newInstance() ;  
                   for (int i = 0; i < columnCount; i++) {  
                       //拿到列名  
                       String columnName = rsmd.getColumnName(i+1) ;         
                       //拿到对象对应的属性  
                       Field field = clazz.getDeclaredField(columnName) ;  
                       //设置私有属性可以访问  
                       field.setAccessible(true) ;  
                       //拿到此列对应的值  
                       Object objectValue = rs.getObject(i+1) ;  
                       //给属性赋值  
                       field.set(obj, objectValue) ;  
                   }  
                   list.add(obj) ;  
               }  
               return list ;  
           } catch (Exception e) {  
               throw new RuntimeException() ;  
           }  
       }  
     
    }


    上面这个是返回一个List的情况,如果只想是返回单个对象,那么很简单,稍微处理一下就可以用下面这个类来实现:

    //只适用于结果集只有一条记录的情况  
    //对象的属性名和表中的字段名应当一致  
    public class ResultSetHandlerImpl {  
       public Object handler(ResultSet rs, Class clazz) {  
           //拿到结果集的元数据对象  
           try {  
               if(rs.next()){  
                   ResultSetMetaData rsmd = rs.getMetaData() ;  
                   //拿到公有多少列  
                   int columnCount = rsmd.getColumnCount() ;  
                   //先创建对象  
                   Object obj = clazz.newInstance() ;  
                   for (int i = 0; i < columnCount; i++) {  
                       //拿到列名  
                       String columnName = rsmd.getColumnName(i+1) ;         
                       //拿到对象对应的属性  
                       Field field = clazz.getDeclaredField(columnName) ;  
                       //设置私有属性可以访问  
                       field.setAccessible(true) ;  
                       //拿到此列对应的值  
                       Object objectValue = rs.getObject(i+1) ;  
                       //给属性赋值  
                       field.set(obj, objectValue) ;  
                   }  
                   return obj ;  
               }else  
                   return null ;  
           } catch (Exception e) {  
               throw new RuntimeException() ;  
           }  
       }  
     
    }


    二:Mybatis的DAO层封装


    (1)一般先写接口:

    public interface DAO {  
       /**  
        * 保存对象  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object save(String str, Object obj) throws Exception;  
     
       /**  
        * 修改对象  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object update(String str, Object obj) throws Exception;  
     
       /**  
        * 删除对象  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object delete(String str, Object obj) throws Exception;  
     
       /**  
        * 查找对象  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object findForObject(String str, Object obj) throws Exception;  
     
       /**  
        * 查找对象  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object findForList(String str, Object obj) throws Exception;  
     
       /**  
        * 查找对象封装成Map  
        *   
        * @param s  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object findForMap(String sql, Object obj, String key, String value) throws Exception;  
    }


    (2)再写实现层:

    @Repository("daoSupport")  
    public class DaoSupport implements DAO {  
     
       @Resource(name = "sqlSessionTemplate")  
       private SqlSessionTemplate sqlSessionTemplate;  
     
       /**  
        * 保存对象  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object save(String str, Object obj) throws Exception {  
           return sqlSessionTemplate.insert(str, obj);  
       }  
     
       /**  
        * 批量更新  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object batchSave(String str, List objs) throws Exception {  
           return sqlSessionTemplate.insert(str, objs);  
       }  
     
       /**  
        * 修改对象  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object update(String str, Object obj) throws Exception {  
           return sqlSessionTemplate.update(str, obj);  
       }  
     
       /**  
        * 批量更新  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public void batchUpdate(String str, List objs) throws Exception {  
           SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();  
           // 批量执行器  
           SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);  
           try {  
               if (objs != null) {  
                   for (int i = 0, size = objs.size(); i < size; i++) {  
                       sqlSession.update(str, objs.get(i));  
                   }  
                   sqlSession.flushStatements();  
                   sqlSession.commit();  
                   sqlSession.clearCache();  
               }  
           } finally {  
               sqlSession.close();  
           }  
       }  
     
       /**  
        * 批量更新  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object batchDelete(String str, List objs) throws Exception {  
           return sqlSessionTemplate.delete(str, objs);  
       }  
     
       /**  
        * 删除对象  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object delete(String str, Object obj) throws Exception {  
           return sqlSessionTemplate.delete(str, obj);  
       }  
     
       /**  
        * 查找对象  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object findForObject(String str, Object obj) throws Exception {  
           return sqlSessionTemplate.selectOne(str, obj);  
       }  
     
       /**  
        * 查找对象  
        *   
        * @param str  
        * @param obj  
        * @return  
        * @throws Exception  
        */
      
       public Object findForList(String str, Object obj) throws Exception {  
           return sqlSessionTemplate.selectList(str, obj);  
       }  
     
       public Object findForMap(String str, Object obj, String key, String value) throws Exception {  
           return sqlSessionTemplate.selectMap(str, obj, key);  
       }  
    }



  • 相关阅读:
    学习笔记(二)Eclipse设置 Servlet配置及初始化参数读取 及Servlet应用
    html实例
    如何使用JDBC调用存储在数据库中的函数或存储过程 */
    如何使用 JDBC 调用存储在数据库中的函数或存储过程
    c3p0数据库连接池使用--创建JDBCTools 公共类
    创建DBCP数据源
    使用Batch批量添加数据
    sqlserver事务隔离级别
    事务处理
    得到数据库自动生成的主键值
  • 原文地址:https://www.cnblogs.com/silyvin/p/9106620.html
Copyright © 2011-2022 走看看