持久层之DAO
2015-11-20 10:48
453 查看
前言
DAO的意思是数据访问对象,就是用该类来访问数据库,具体来说是执行增删查改的。另外,还需要负责获取连接对象和关闭连接对象。
UML
代码示例
1、接口
1)增删查改。2)获取连接对象和关闭连接对象。
package com.bigning.db; import java.io.*; import java.util.*; import java.util.Date; import java.sql.*; import com.bigning.Important; import com.bigning.ImportantLevel; /** * DAO接口 * * @author gzh * @see AbstractDal * */ @Important(ImportantLevel.Top) public interface ComDal extends Serializable { /** * 增、删、改 * * @param sql * sql语句 * @return 记录数量 * @throws DalException */ public int execCommand(String sql) throws DalException; /** * 增、删、改 * * @param sql * sql语句 * @param date * 日期 * @return 记录数量 * @throws DalException */ public int execCommand(String sql, java.util.Date date) throws DalException; /** * 增、删、改 * * @param sql * sql语句 * @param dates * 日期数组 * @return 记录数量 * @throws DalException */ public int execCommand(String sql, java.util.Date[] dates) throws DalException; /** * 增、删、改 * * @param sql * sql语句 * @param dates * 日期列表 * @return 记录数量 * @throws DalException */ public int execCommand(String sql, List<Date> dates) throws DalException; /** * 查询 * * @param sql语句 * @return 结果集 * @throws DalException */ public ResultSet doSelect(String sql) throws DalException; /** * 查询 * * @param sql * sql语句 * @param date * 日期 * @return 结果集 * @throws DalException */ public ResultSet doSelect(String sql, java.util.Date date) throws DalException; /** * 查询 * * @param sql * sql语句 * @param dates * 日期数组 * @return 结果集 * @throws DalException */ public ResultSet doSelect(String sql, java.util.Date[] dates) throws DalException; /** * 查询 * * @param sql * sql语句 * @param dates * 日期列表 * @return 记录集 * @throws DalException */ public ResultSet doSelect(String sql, List<Date> dates) throws DalException; /** * 执行一批命令 * * @param arrSqls * 命令数组 */ public void execBatch(String[] arrSqls) throws DalException; /** * 执行一组命令 */ public void execBatch(List<String> vSqls) throws DalException; /** * 执行存储过程(对 SQL Server而言) * * @param spName * 存储过程名称 * @param spParams * 存储过程的参数 */ public void execStoreCommand(String spName, String spParams) throws DalException; /** * 取得连接对象 * * @return 连接对象 */ public Connection getConnection() throws DalException; /** * 清除历史的 statment */ public void clearHistory(); /** * 关闭结果集对象、语句对象和连接对象 */ public void closeConnection(); /** * 取得最后执行的一条 SQL 语句 */ public String getLastSql(); /** * 取得连接生成器 */ public ConnectionGenerator getConnectionGenerator(); /** * 设置数据的 Filter,插入到数据库之前, 将数据进行 convert 一下 -- updated on 20030117 */ // public void setFilter(DataFilter df); /** * 移除过滤器 -- updated on 20030117 */ // public DataFilter removeFilter() ; /** * 设置要获取的记录数量 * @param fetchSize 记录数量 */ public void setFetchSize(int fetchSize); };
2、实现类(非连接池)
注:该类是DAO接口的实现类,并不是抽象类,这里命名错误!package com.bigning.db; import java.util.*; import java.util.Date; import java.sql.*; import org.apache.log4j.*; import com.bigning.Important; import com.bigning.ImportantLevel; /** * DAO的实现类: 作为一个基本的 DAL 类存在, 而并不是一个Abstract 类, 可作为 ComDal 的一个参考实现 * * @author Administrator * */ @Important(ImportantLevel.Top) public class AbstractDal implements ComDal, Cloneable { /** * Comment for <code>serialVersionUID</code> */ private static final long serialVersionUID = 3257001055735658040L; static PreProcesser SPP = new PreProcesser(); // 字段定义 private ConnectionGenerator cg; // 连接生成器 private String lastSql; // 最后执行的 SQL 语句 protected Connection conn; // 数据库连接 private LinkedList<Statement> historyStatements; private LinkedList<ResultSet> historyResultSets; private static final Logger logger = Logger.getLogger(AbstractDal.class); // private DataFilter filter; int fetchSize = 20; // 构造方法说明: /** * @param cg * 连接生成器 */ public AbstractDal(ConnectionGenerator cg) { this.cg = cg; historyStatements = new LinkedList<Statement>(); historyResultSets = new LinkedList<ResultSet>(); } // 其他方法说明: /** * 执行 SQL 命令, 如 Insert, Delete等 * * @param sql * SQL命令 * @throws DalException * 封装SQL语句出错的命令 */ public int execCommand(String sql) throws DalException { return execCommand(sql, SPP); } /** * 执行 SQL 命令, 如 Insert, Delete等 * * @param sql * SQL命令 * @param aDate * 一个日期 */ public int execCommand(String sql, java.util.Date aDate) throws DalException { return execCommand(sql, new DatePreProcesser(aDate)); } /** * 执行 SQL 命令,如 Insert, Delete等, 但这条命令中包括有 Date 类型需要设置 * * @param sql * SQL 命令 * @param dates * 一组日期 */ public int execCommand(String sql, java.util.Date[] dates) throws DalException { return execCommand(sql, new DatePreProcesser(dates)); } /** * 执行 SQL 命令,如 Insert, Delete等, 但这条命令中包括有 Date 类型需要设置 * * @param sql * SQL 命令 * @param dates * 一组日期 */ public int execCommand(String sql, List<Date> dates) throws DalException { return execCommand(sql, new DatePreProcesser(dates)); } private int execCommand(String sql, PreProcesser dpp) throws DalException { ensureConnected(); lastSql = sql; int r = 0; try { PreparedStatement ps = conn.prepareStatement(sql); try { dpp.process(ps); r = ps.executeUpdate(); } finally { ps.close(); } logSucc(sql); } catch (SQLException ex) { logFail(ex, sql + dpp.getDates()); throw new DalException(this, ex, sql + dpp.getDates()); } return r; } /** * 执行 SQL 查询命令 * * @param sql * SQL查询语句 * @return 记录集 */ /** * 执行一批命令 * * @param arrSqls * 命令数组 */ public void execBatch(String[] arrSqls) throws DalException { ensureConnected(); try { Statement s = conn.createStatement(); try { for (int i = 0; i < arrSqls.length; i++) { lastSql = arrSqls[i]; s.executeUpdate(lastSql); logSucc(lastSql); } } finally { s.close(); } } catch (SQLException ex) { logFail(ex, lastSql); throw new DalException(this, ex, lastSql); } // end of catch } /** * 执行一组命令 */ public void execBatch(List<String> vSqls) throws DalException { String[] s = new String[vSqls.size()]; vSqls.toArray(s); execBatch(s); } /** * 执行 SQL 查询命令 * * @param sql * SQL查询语句 * @return 结果集 */ public ResultSet doSelect(String sql) throws DalException { return doSelect(sql, SPP); } /** * 执行查询语句 * * @param sql * sql语句 * @param spp * 3ff0 预处理 * @return 结果集 * @throws DalException */ private ResultSet doSelect(String sql, PreProcesser spp) throws DalException { ensureConnected(); lastSql = sql; try { PreparedStatement s = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); try { s.setFetchSize(fetchSize); } catch (Exception ex) { } spp.process(s); ResultSet r = s.executeQuery(); try { r.setFetchSize(fetchSize); } catch (Exception ex) { } synchronized (historyStatements) { historyStatements.addLast(s); historyResultSets.addLast(r); } logSucc(sql); return r; } catch (SQLException ex) { logFail(ex, sql + spp.getDates()); throw new DalException(this, ex, sql + spp.getDates()); } // end of catch } /** * 执行 SQL 查询命令 * * @param sql * SQL查询语句 * @return 结果集 */ public ResultSet doSelect(String sql, Date aDate) throws DalException { return doSelect(sql, new DatePreProcesser(aDate)); } /** * 执行 SQL 查询命令 * * @param sql * SQL查询语句 * @param dates * 一组日期 * @return 记录集 */ public ResultSet doSelect(String sql, Date[] dates) throws DalException { return doSelect(sql, new DatePreProcesser(dates)); } /** * 执行 SQL 查询命令 * * @param sql * SQL查询语句 * @param dates * 一组日期 * @return 记录集 */ public ResultSet doSelect(String sql, List<Date> dates) throws DalException { return doSelect(sql, new DatePreProcesser(dates)); } /** * 执行一批命令 * * @param arrSqls * 命令数组 */ /** * 清除历史记录的Statement */ public void clearHistory() { synchronized (historyStatements) { for (ResultSet rs : historyResultSets) { try { rs.close(); } catch (Exception ex) { } } historyResultSets.clear(); for (Statement s : historyStatements) { try { s.close(); } catch (Exception ex) { } } historyStatements.clear(); } } /** * 执行存储过程(对 SQL Server而言)(未实现) * * @param spName * 存储过程名称 * @param spParams * 存储过程的参数 */ public void execStoreCommand(String spName, String spParams) throws DalException { throw new DalException(" store Command is not supported by " + getClass().getName()); } /** * 取得连接对象 * * @return 连接对象 */ public Connection getConnection() throws DalException { ensureConnected(); return conn; } /** * 关闭连接串 */ public void closeConnection() { clearHistory(); try { // an exception would be shrown here, I try to catch it! if (conn != null) { // start of if doCloseConnection(conn); } // end of if } catch (Exception ex) { // // ex.printStackTrace(); // Print Stack Trace } // end of catch finally { conn = null; } } protected void doCloseConnection(Connection c) throws SQLException { c.close(); } /** * 取得最后执行的一条 SQL 语句 * * @return 通过 DAL 执行的最后一条 SQL 语句 */ public String getLastSql() { return lastSql; } /** * 确保当前有连接对象:如果没有的话,创建一个连接对象 * * @throws DalException */ private void ensureConnected() throws DalException { try { if (conn == null || conn.isClosed()) { // 如果当前没有连接对象,那么创建连接对象 conn = openConnection(); } // end of if } catch (SQLException ex) { throw new DalException(this, ex, "Fail to Connect To Database"); } // end of catch } /** * 获取连接对象 * * @return * @throws ConnectFailException */ protected Connection openConnection() throws ConnectFailException { return cg.getConnection(); } public void finalize() { closeConnection(); } /** * 取得连接生成器 */ public ConnectionGenerator getConnectionGenerator() { return cg; } private void doLog(Throwable t, String msg) { logger.error(msg, t); } private void logSucc(String sql) { logger.info(sql + "? SUCCESS"); } private void logFail(Throwable t, String sql) { doLog(t, sql + "? FAILUER"); } public String toString() { return "AbstractDal\r\nConnectionString: " + cg.getConnString() + "\r\nLast SQL: " + lastSql; } public Object clone() { try { AbstractDal dal = (AbstractDal) super.clone(); dal.conn = null; dal.historyResultSets = new LinkedList<ResultSet>(); dal.historyStatements = new LinkedList<Statement>(); return dal; } catch (Exception ex) { // ex.printStackTrace(); logger.error("Cannot Clone the Dal", ex); } return new AbstractDal(this.cg); } public void setFetchSize(int fetchSize) { if (fetchSize < 1) { fetchSize = 20; //如果要获取的记录数量小于1,那么默认设置为20 } this.fetchSize = fetchSize; } }
3、DAO实现类(连接池)
/* * @(#) * * Copyright bigNing(javaning@sina.com, 2003.06.01 */ package com.bigning.db.pool; import java.sql.Connection; import java.sql.SQLException; import com.bigning.db.*; /** * 可缓冲的数据访问层 */ public class PoolableComDal extends AbstractDal implements ComDal { /** * Comment for <code>serialVersionUID</code> */ private static final long serialVersionUID = 3546923576121899056L; /** * 默认的连接关闭监听器 * 关闭连接 -- 非缓冲 * @author fantasy * */ private static class CloseConnReleaseListener implements ConnReleaseListener{ /* (non-Javadoc) * @see bigning.db.pool.ConnReleaseListener#connReleased(bigning.db.pool.ConnReleaseEvent) */ public void connReleased(ConnReleaseEvent cre) { Connection c=cre.getConnection(); try{ c.close(); } catch (Throwable e ){} } } //默认的连接关闭监听器 private static final ConnReleaseListener DEFAULT_LISTENER=new CloseConnReleaseListener(); // 连接关闭监听器 private ConnReleaseListener listener; /** * 构造缓冲的数据访问层 * @param cg 连接生成器 * @param lsnr 连接关闭监听器 */ public PoolableComDal(PoolableConnectionGenerator cg,ConnReleaseListener lsnr) { super(cg); if(lsnr==null){ lsnr=DEFAULT_LISTENER; } listener=lsnr; } /** * 构造普通的数据访问层 * @param cg 连接生成器 */ public PoolableComDal(PoolableConnectionGenerator cg) { this(cg,DEFAULT_LISTENER); } public void setConnReleaseListener(ConnReleaseListener listener) { if(listener==null){ listener=DEFAULT_LISTENER; } this.listener=listener; } /** * 移除连接关闭监听器, 并使用默认监听器 * @return 当前使用的监听器 */ public ConnReleaseListener removeConnReleaseListener() { ConnReleaseListener l=listener; listener=DEFAULT_LISTENER; return l; } /** * 关闭连接串 * @throws SQLException */ protected void doCloseConnection(Connection c) throws SQLException{ listener.connReleased(new ConnReleaseEvent(this,c)); } }
总结
所有的关于持久层的实现或者说思想原理什么的,都是围绕着DAO的2大功能(即增删查改功能和获取/关闭连接对象)来实现的。以DAO为核心,其他的无非是连接池的运用,各种工厂类的运用(即设计模式的运用)…………等等。
相关文章推荐
- Asp实现的数据库连接池功能函数分享
- .net 中的SqlConnection连接池机制详解
- 在Tomcat服务器下使用连接池连接Oracle数据库
- Tomeat6.0 连接池数据库配置
- Tomcat 5.5 数据库连接池配置
- asp.net 数据库连接池浅析
- .NET 数据库连接池
- .NET Framework SQL Server 数据提供程序连接池
- java配置数据库连接池的方法步骤
- Java实现数据库连接池的方法
- 简单实现一个连接池
- 数据源连接池
- php-cp 连接池 php-connect-pool 介绍
- java Tomcat数据库连接池
- tomcat6数据库连接池配置详解
- 各种连接池参数比较
- mongodb连接池
- Ehcache ,C3p0 pool
- 服务端 高性能 (三) network
- 连接池原理