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

框架用多了,也有些腻。虽然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包。

你可能感兴趣的:(java,DAO,sql,jdbc)