单纯使用JDBC的通用DAO类设计

设计功能要求:
    1:尽量保留原来API的操作
    2:尽量简化JDBC操作的代码
    3:带有分页功能
分析:
    尽量保留原来API的操作,那么这个通用DAO不能过度封装,对于外界操作来说应该是透明的,为了简化一般的分页控制,提供了一个简单的基于超链接方式的上下页翻页操作,代码如下:
BaseDao.java
[CODE]
package xx.xx.xx;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
/**
 * 作为所有数据库访问的父类<br/>适当的提供一些数据库的操作功能
 */
public class BaseDao {
 
 protected Connection conn = null;
 protected PreparedStatement pstmt = null;
 protected ResultSet rs = null;
 //最好通过配置文件加载,这样可以灵活的移动
 private static String JNDI_DS = "java:comp/env/jdbc/msg";
 
 public void query(String sql, Object... params) throws SQLException {
  openConn();
  preparedSql(sql, params);
  rs = pstmt.executeQuery();
 }
 
 protected void preparedSql(String sql, Object... params) throws SQLException {
  pstmt = conn.prepareStatement(sql);
  for (int i = 0; i < params.length; i++) {
   pstmt.setObject(i+1, params[i]);
  }
 }
 
 /**
  * @param sql,调用者方法中定义好的sql语句,通常是一个DAO类的方法
  * @param params 传入的参数,多个参数用逗号隔开即可
  * @return
  */
 public int update(String sql, Object... params) {
  openConn();
  int count = 0;
  try {
   preparedSql(sql, params);
   count = pstmt.executeUpdate();
  } catch (SQLException e) {
   e.printStackTrace();
  } finally {
   closeAll();
  }
  return count;
 }
 
 /**
  * pagedQuery分页查询功能
  * @param pb 分页的bean用于封装分页信息
  * @param sql
  * @param params
  * @throws SQLException
  */
 public void queryByPage(PageBean pb, String sql, Object... params) throws SQLException {
  //由于本方法有2次查询数据库,共用一个PreparedStatement,所以不重用本类中的query方法
  openConn();
  String totalSql = "select count(1) from (" + removeOrders(sql) + ")";
  preparedSql(totalSql, params);
  rs = pstmt.executeQuery();
  //设置总记录数
  if(rs.next()) {
   pb.setTotal(rs.getInt(1));
  }
  String pagedSql = "select * from (select rownum as rn, t__.* from ("
    + sql + ") t__) where rn >= ? and rn <= ?";
  Object[] p = new Object[params.length + 2];
  for(int i =0; i < params.length; i++) {
   p[i] = params[i];
  }
  p[params.length] = pb.getFirstResult();
  p[params.length + 1] = pb.getMaxResult();
  //分页查询结果
  preparedSql(pagedSql, p);
  rs = pstmt.executeQuery();
 }
 
 /**
  * 由于order by消耗资源相当大,统计行数时不需要<br/>本例使用正则表达式处理掉order by子句
  * @param sql
  * @return
  */
 protected String removeOrders(String sql) {
  Pattern pattern = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*",
    Pattern.CASE_INSENSITIVE);
  Matcher matcher = pattern.matcher(sql);
  StringBuffer buf = new StringBuffer();
  while (matcher.find()) {
   matcher.appendReplacement(buf, "");
  }
  matcher.appendTail(buf);
  return buf.toString();
 }
 
 protected void openConn() {
  Context ctx;
  try {
   ctx = new InitialContext();
   DataSource ds = (DataSource) ctx.lookup(JNDI_DS);
   conn = ds.getConnection();
  } catch (NamingException e) {
   e.printStackTrace();
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
 
 protected void closeAll() {
  try {
   if (rs != null) {
    rs.close();
   }
   if (pstmt != null) {
    pstmt.close();
   }
   if (conn != null) {
    conn.close();
   }
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
}
[/CODE]
本段代码需要一个类PageBean,代码如下
[CODE]
package xx.xx.xx;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class PageBean {
 
 private int pageSize = 10; //每页页面显示数据的条数
 
 private int total = 0;//数据库表的总记录数
 
 private int pageNum = 1;//当前第几页
 
 public boolean getHasNext() {
  if (this.getTotalPages() > pageNum) {
   return true;
  } else {
   return false;
  }
 }
 
 public int getNext() {
  return (pageNum + 1);
 }
 
 public boolean getHasPrevious() {
  if (pageNum > 1) {
   return true;
  } else {
   return false;
  }
 }
 
 public int getPrevious() {
  return (pageNum - 1);
 }
 
 public int getFirstResult() {
  return (pageNum - 1) * pageSize + 1;
 }
 
 public int getMaxResult() {
  return pageNum * pageSize;
 }
 
 /**
  * 获得分页的总页数
  * @return
  */
 public int getTotalPages() {
  if (total % pageSize == 0) {
   return (total/pageSize);
  } else {
   return (total/pageSize + 1);
  }
 }
 public int getPageSize() {
  return pageSize;
 }
 public void setPageSize(int pageSize) {
  this.pageSize = pageSize;
 }
 public int getTotal() {
  return total;
 }
 public void setTotal(int total) {
  this.total = total;
 }
 public int getPageNum() {
  return pageNum;
 }
 public void setPageNum(int pageNum) {
  this.pageNum = pageNum;
 }
 
 private Map<String, String[]> params;
 
 /**
  * 添加额外参数到页面上
  * @param param
  * @param value
  */
 public void addParam(String param, String value) {
  if (params == null) {
   params = new HashMap<String, String[]>();
  }
  if (params.containsKey(param)) {
   String[] oldValues = params.get(param);
   //多加了一个参数
   String[] pvalues = new String[oldValues.length+1];
   for (int i = 0; i < pvalues.length; i++) {
    pvalues[i] = oldValues[i];
   }
   pvalues[pvalues.length-1] = value;
  } else {
   params.put(param, new String[]{value});
  }
 }
 
 /**
  * 将网页的参数一次性添加上去,主要是为了在有查询条件的分页情况时使用
  * @param params
  */
 public void addAllParams(Map<String, String[]> params) {
  if (params == null) {
   return;
  }
  if (this.params == null) {
   this.params = new HashMap<String, String[]>();
  }
  this.params.putAll(params);
 }
 
 /**
  * 扩展参数
  * @return
  */
 private String getParamsString() {
  //将分页的信息清除,因为每次换页都不一样
  params.remove("pageNum");
  params.remove("pageSize");
  if (params == null || params.isEmpty()) {
   return null;
  } else {
   StringBuilder sb = new StringBuilder("");
   Iterator<Entry<String, String[]>> iter = params.entrySet().iterator();
   while (iter.hasNext()) {
    Entry<String, String[]> entry = iter.next();
    for (String str : entry.getValue()) {
     sb.append("&" + entry.getKey() + "=" + str);
    }
   }
   return sb.toString().substring(1);
  }
 }
 //基础路径,就是页面的访问路径
 private String basePath = "";
 public void setBasePath(String basePath) {
  this.basePath = basePath;
 }
 
 /**
  * 获得分页的控制面板
  * @return 字符串
  */
 public String getPagedPanel() {
  StringBuilder sb = new StringBuilder("当前页数:[" + pageNum + "/" + this.getTotalPages() + "]");
  sb.append("&nbsp;");
  if (pageNum > 1) {
   sb.append("<a href='【basePath】pageNum=1&pageSize=" + pageSize + "'>首页</a>");
  } else {
   sb.append("首页");
  }
  if (this.getHasPrevious()) {
   sb.append("<a href='【basePath】pageNum=" + this.getPrevious() + "&pageSize=" + pageSize + "'>上一页</a>");
  } else {
   sb.append("上一页");
  }
  if (this.getHasNext()) {
   sb.append("<a href='【basePath】pageNum=" + this.getNext() + "&pageSize=" + pageSize + "'>下一页</a>");
  } else {
   sb.append("下一页");
  }
  if (this.getTotalPages() > pageNum) {
   sb.append("<a href='【basePath】pageNum=" + this.getTotalPages() + "&pageSize=" + pageSize + "'>尾页</a>");
  } else {
   sb.append("尾页");
  }
  String replacePath = basePath + "?";
  String paramStr = this.getParamsString();
  if (paramStr != null) {
   replacePath = replacePath  + paramStr + "&";
  }
  return sb.toString().replaceAll("【basePath】", replacePath);
 }
}
[/CODE]

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