欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

web应用dao层的开发经验小结

程序员文章站 2022-06-19 08:06:58
...
框架用多了,也有些腻。虽然struts2,spring,hibernate,ibatis等等都是一些很优秀的框架。不过,发现很多框架的功能都没用到,感觉有些浪费啊!于是,想着是不是自己学习用过框架的思想,然后用传统的无框架来进行开发。

这两天利用路上两个小时的坐公车时间,思考了如何去开发dao层。总结如下:
1、使用模板模式来开发通用的JdbcTemplate,简单的写了下jdbc模板类
public class JdbcTemplate<T> {

/**
* 查找表对象列表
*/
@SuppressWarnings("unchecked")
public List<T> query(String sql, Object[] args, BaseDao dao){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<T> list = new ArrayList<T>();
try {
conn = DBUtils.getConnectionByC3P0();
ps = conn.prepareStatement(sql);
if(args!=null){
for(int i=0; i<args.length; i++){
ps.setObject(i+1, args[i]);
}
}
rs = ps.executeQuery();
while(rs.next()){
T obj = dao.rowMapper(rs);
list.add(obj);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(conn.getAutoCommit()){
DBUtils.release(rs, ps, conn);
}else{
DBUtils.release(rs, ps, null);
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return list;
}

/**
* 更新表对象
*/
public void update(String sql, Object[] args){
Connection conn = null;
PreparedStatement ps = null;
try {
conn = DBUtils.getConnectionByC3P0();
ps = conn.prepareStatement(sql);
if(args!=null){
for(int i=0; i<args.length; i++){
ps.setObject(i+1, args[i]);
}
}
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(conn.getAutoCommit()){
DBUtils.release(null, ps, conn);
}else{
DBUtils.release(null, ps, null);
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}

在这个模板类中数据库连接没有直接关闭的原因,是为了之后的事务管理。当然,模板类肯定不能只是这两个方法,具体可以参考spring的jdbctemplate来进行模板类的开发。
BaseDao是个接口,完成rs到bean的映射,代码如下:
public interface BaseDao<T> {
public T rowMapper(ResultSet rs);
}

2、其它dao层类使用JdbcTemplate来进行开发。下面举个简单的例子:
	public List<SearchUpdate> findBySql(String sql, Object[] objs) {
return jt.query(sql, objs, new BaseDao<User >() {
public User rowMapper(ResultSet rs) {
User user = new User ();
try {
user.setName(rs.getString("name"));
user.setId(rs.getInt("id"));
} catch (Exception e) {
e.printStackTrace();
}
return user;
}
});
}

3、使用代理模式来进行事务的处理。下面是,关于业务代理类的代码,在里面进行了事务的开启,提交或者回滚。
public class TransactionProxy implements InvocationHandler {
private Object targetObject;

public Object bind(Object targetObject) {
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
}

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
TransactionManager tm = DBUtils.getTransactionManager();
tm.beginTransaction();
Object result = null;
try {
result = method.invoke(targetObject, args);
tm.commitTransaction();
} catch (Exception e) {
tm.rollBackTransaction();
}
return result;
}
}

这种代理方式,前提是代理对象必须是相应的接口的实现。如果代理对象没有接口的话,可以利用第三方包cglib来实现对象的代理。

以上纯粹只是个人的经验之谈,作为自己的小小的记录。如有错漏,望提出。完整的代码在附件中,包含了一个数据库链接池的包和cglib包。