使用模板方法模式简化JDBC操作
在使用JDBC时,会重复的写很多重复的代码,例如
Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; String sql="insert into t_user(username,brithday) values(?,?)"; try { conn = JdbcUtils.getConnection(); ps = conn.prepareStatement(sql); } catch (SQLException e) { throw new DaoException(e.getMessage(), e); } finally { JdbcUtils.free(rs, ps, conn); }
这部分代码在数据库操作方法中都会有。因此我们可以把这部分不变的内容提取出来,作为一个公用的方法。
例如,我们的增,删,改操作可以这样写
/** * 增,删,改方法 * @param sql * @param args sql参数 * @return */ public int update(String sql, Object[] args) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = JdbcUtils.getConnection(); ps = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) ps.setObject(i + 1, args[i]); return ps.executeUpdate(); } catch (SQLException e) { throw new DaoException(e.getMessage(), e); } finally { JdbcUtils.free(rs, ps, conn); } }
最麻烦的就是返回一个对象的操作了。因为我不知道要返回的对象是什么,所以在往对象里设值的时候就不确定了。因此我们可以在这个类里面定义一个抽象的方法,具体怎么实现,它的子类知道。
因此我们的这个类就可以这样设计了
package com.zzg.jdbc.base; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import com.zzg.jdbc.exception.DaoException; import com.zzg.jdbc.util.JdbcUtils; public abstract class BaseDao { /** * 增,删,改方法 * @param sql * @param args sql参数 * @return */ public int update(String sql, Object[] args) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = JdbcUtils.getConnection(); ps = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) ps.setObject(i + 1, args[i]); return ps.executeUpdate(); } catch (SQLException e) { throw new DaoException(e.getMessage(), e); } finally { JdbcUtils.free(rs, ps, conn); } } /** * 返回一个对象 * @param <T> * @param sql * @param args * @return */ public <T> T find(String sql, Object[] args) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = JdbcUtils.getConnection(); ps = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) ps.setObject(i + 1, args[i]); rs = ps.executeQuery(); T t = null; if (rs.next()) { t = rowMapper(rs); } return t; } catch (SQLException e) { throw new DaoException(e.getMessage(), e); } finally { JdbcUtils.free(rs, ps, conn); } } /** * 返回一个List * @param <T> * @param sql * @param args * @return */ public <T> List<T> list(String sql, Object[] args) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = JdbcUtils.getConnection(); ps = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) ps.setObject(i + 1, args[i]); rs = ps.executeQuery(); T t = null; List<T> list = new ArrayList<T>(); while (rs.next()) { t = rowMapper(rs); list.add(t); } return list; } catch (SQLException e) { throw new DaoException(e.getMessage(), e); } finally { JdbcUtils.free(rs, ps, conn); } } abstract protected <T> T rowMapper(ResultSet rs) throws SQLException; }
在使用时我们的类只需要继承上面那个类就可以了。
package com.zzg.jdbc.dao.impl; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import com.zzg.jdbc.base.BaseDao; import com.zzg.jdbc.dao.UserDao; import com.zzg.jdbc.domain.User; public class UserDaoImpl extends BaseDao implements UserDao { @Override public User findUser(int id) { String sql = "select *from t_user where id=?"; Object[] args = new Object[] { id }; User user = super.find(sql, args); return user; } @Override public List<User> listUser(String username) { String sql = "select *from t_user where username=?"; Object[] args = new Object[] { username }; List<User> list = super.list(sql, args); for (User u : list) { System.out.println(u.getId()); } return list; } @Override protected Object rowMapper(ResultSet rs) throws SQLException { User user = new User(); user.setId(rs.getInt("id")); user.setUsername(rs.getString("username")); user.setBrithday(rs.getDate("brithday")); return user; } }
附加分页的方法:
/** * 分页 * @param tableName * @param PK * @param methodPageNum * @param methodNumPerPage * @param conditions * @param <T> * @return * @throws SQLException */ public <T> List<T> getPageListResultSet(String tableName,String PK,int methodPageNum,int methodNumPerPage,Map<String,String> conditions) throws SQLException{ int pageNum = methodPageNum==0?DEFAULT_PAGE_NUM:methodPageNum; int numPerPage = methodNumPerPage==0?DEFAULT_NUM_PER_PAGE:methodNumPerPage; List<T> list = null; DataSetOp dataSetOp = null; try { dataSetOp = new DataSetOp(); String PAGE_SQL_PREFIX = " SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY t1.ID DESC) AS ROW_NUM, t1.* FROM "; String PAGE_SQL_END = " ) TT WHERE TT.ROW_NUM >? AND TT.ROW_NUM <= ? "; if(StringUtil.isNotBlank(PK)){ PAGE_SQL_PREFIX = PAGE_SQL_PREFIX.replace("ID",PK); } StringBuffer sql = new StringBuffer(PAGE_SQL_PREFIX); sql.append(tableName).append(" t1 WHERE 1=1 "); //设置条件 if(conditions!=null && conditions.size()>0){ Set<String> key = conditions.keySet(); for (Iterator it = key.iterator(); it.hasNext();) { String column = (String) it.next(); //System.out.println(conditions.get(s)); StringBuffer cd = new StringBuffer(" and t1."); cd.append(column).append("='").append(conditions.get(column)).append("' "); sql.append(cd); } } sql.append(PAGE_SQL_END); System.out.println(sql); PreparedStatement ps = dataSetOp.getConnection().prepareStatement(sql.toString()); ps.setInt(1, (pageNum - 1) * numPerPage); ps.setInt(2, pageNum*numPerPage); ResultSet rs = ps.executeQuery(); T t = null; list = new ArrayList<T>(); while (rs.next()) { t = rowMapper(rs); list.add(t); } } catch (DataException e) { e.printStackTrace(); }finally{ if(dataSetOp != null) dataSetOp.close(); } return list; }