您的位置:首页 > 其它

持久层之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为核心,其他的无非是连接池的运用,各种工厂类的运用(即设计模式的运用)…………等等。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息