伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

手把手教你如何自定义DAO框架(重量级干货)

来源:本站原创 浏览:145次 时间:2021-07-31

本文为投稿文,作者:湖南大学CS- scw。

另外他在CSDN有个不错的博客,欢迎点击下方阅读原文,进行围观。

描述:本篇博客,主要是对于目前实际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                  re�༭,����turn 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);      }  }

  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net