zoukankan      html  css  js  c++  java
  • 自己写的Dao框架

    在使用数据库连接池的时候,每次写Dao都很烦,要写很多重复的Sql语句,还有各种针对查询好的Rs后fetch出Bean,真的让我很不能忍。

    于是在经过了一下午的研究,终于针对Dao进行的封装。

    废话不多说 先看Dao父类:

    package com.tim.DaoProject.dao;

    import java.beans.BeanInfo;
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.Method;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.HashMap;
    //import java.util.logging.Logger;

    import com.tim.DaoProject.util.StringUtils;

    public class DAO<T> {

    private static boolean LOG_CONSOLE = true;

    protected Connection conn;

    public DAO(Connection conn) {
    this.conn = conn;
    }

    public String tablename = "";
    public Class<T> clazz = null;

    // Logger log = Logger.getLogger(DAO.class);

    protected static final int timeStampLen = "2011-01-18 16:18:18".length();
    protected static final String timeStampPattern = "yyyy-MM-dd HH:mm:ss";
    protected static final String datePattern = "yyyy-MM-dd";

    public void setConnection(Connection connection){
    conn = connection;
    }

    public synchronized long add(T daoBean)
    throws SQLException {
    HashMap<String, String> valueMap = this.getBeanHash(daoBean);
    String sqlsString = this.getInsertSqlString(tablename, valueMap);
    log(sqlsString);
    PreparedStatement statement = conn.prepareStatement(sqlsString,Statement.RETURN_GENERATED_KEYS);
    int index = 1;
    for (String key : valueMap.keySet()) {
    statement.setString(index++, valueMap.get(key));
    }
    long count = statement.executeUpdate();
    if(count > 0){
    ResultSet rs = statement.getGeneratedKeys();
    if(rs.next()){
    count = rs.getInt(1);
    }
    }
    return count;
    }

    public synchronized long update(T daoBean) throws SQLException{
    HashMap<String, String> valueMap = this.getBeanHash(daoBean);
    String sqlString = this.getUpdateSqlString(tablename, valueMap);
    PreparedStatement statement = conn.prepareStatement(sqlString);
    int index = 1;
    for (String key : valueMap.keySet()) {
    if(key.equals("id")){
    continue;
    }
    statement.setString(index++, valueMap.get(key));
    }
    long count = statement.executeUpdate();
    return count;
    }



    public ArrayList<T> getAllObj() throws SQLException{
    return this.getAllObj("");
    }

    public ArrayList<T> getAllObj(String append) throws SQLException{
    String sqlStr = "SELECT * FROM "+tablename+" " + append + ";";
    log("sqlstr is " + sqlStr);
    PreparedStatement ps = conn.prepareStatement(sqlStr);
    ResultSet rs = ps.executeQuery();
    return this.fetchList(rs);
    }


    public T getById(String id) throws SQLException{
    String sqlStr = "SELECT * FROM "+tablename+" where id = ?;";
    PreparedStatement ps = conn.prepareStatement(sqlStr);
    ps.setString(1, id);
    ResultSet rs = ps.executeQuery();
    return this.fetch(rs);

    }


    public int deleteById(String id) throws SQLException{
    String sqlStr = "DELETE FROM "+tablename+" where id = ?;";
    PreparedStatement ps = conn.prepareStatement(sqlStr);
    ps.setString(1, id);
    return ps.executeUpdate();
    }

    private T fetch(ResultSet rs) {
    T returnObj = null;

    try {
    if (rs.next()) {
    returnObj = clazz.newInstance();
    BeanInfo beanInfo = Introspector.getBeanInfo(returnObj.getClass());
    PropertyDescriptor[] propertyDesc = beanInfo
    .getPropertyDescriptors();
    for (int i = 0; i < propertyDesc.length; i++) {
    if (propertyDesc[i].getName().compareToIgnoreCase("class") == 0)
    continue;
    String key = propertyDesc[i].getName();
    String value = rs.getString(key);
    if (value != null) {
    try {
    Method mr = propertyDesc[i].getWriteMethod();
    Class<?> class1 = mr.getParameterTypes()[0];
    mr.invoke(returnObj, this.convert(class1, value));
    } catch (Exception e) {
    e.printStackTrace();
    }

    }
    }
    }
    } catch (Exception e) {
    e.printStackTrace();
    // log.error(e, e);
    }
    return returnObj;
    }


    private ArrayList<T> fetchList(ResultSet rs) {
    ArrayList<T> returnList = new ArrayList<T>();

    try {
    while (rs.next()) {
    T tempObj = clazz.newInstance();
    BeanInfo beanInfo = Introspector.getBeanInfo(tempObj.getClass());
    PropertyDescriptor[] propertyDesc = beanInfo
    .getPropertyDescriptors();
    for (int i = 0; i < propertyDesc.length; i++) {
    if (propertyDesc[i].getName().compareToIgnoreCase("class") == 0)
    continue;
    String key = propertyDesc[i].getName();
    try {
    String value = rs.getString(key);
    if (value != null) {
    try {
    Method mr = propertyDesc[i].getWriteMethod();
    Class<?> class1 = mr.getParameterTypes()[0];
    mr.invoke(tempObj, this.convert(class1, value));
    } catch (Exception e) {
    e.printStackTrace();
    }

    }
    } catch (Exception e) {
    // log.error(e,e);
    }

    }
    returnList.add(tempObj);
    }
    } catch (Exception e) {
    e.printStackTrace();
    // log.error(e, e);
    }
    return returnList;
    }


    /***
    * 根据startString 和valueMap 拼接出插入的sqlStr
    * @param startString
    * @param valueMap
    * @return
    */
    public String getInsertSqlString(String tableName, HashMap<String, String> valueMap ){

    StringBuffer sqlBuffer = new StringBuffer();
    StringBuffer valueBuffer = new StringBuffer(" values(");
    sqlBuffer.append("INSERT INTO " + tableName + " (");

    //是否是第一次循环 如果不是 则先append字符 ,
    boolean isFirstValue = true;
    for (String key : valueMap.keySet()) {
    if(key.equals("id")){
    continue;
    }
    if(!isFirstValue){
    sqlBuffer.append(",");
    valueBuffer.append(",");
    }
    isFirstValue = false;
    sqlBuffer.append("`");
    sqlBuffer.append(key);
    sqlBuffer.append("`");

    valueBuffer.append("?");
    }

    sqlBuffer.append(")");
    valueBuffer.append(")");
    sqlBuffer.append(valueBuffer);

    return sqlBuffer.toString();
    }


    public String getUpdateSqlString(String tableName, HashMap<String, String> valueMap ){

    StringBuffer sqlBuffer = new StringBuffer();
    sqlBuffer.append("Update" + tableName + " set ");
    StringBuffer whereBuffer = new StringBuffer();
    whereBuffer.append(" where `id` = '");
    //是否是第一次循环 如果不是 则先append字符 ,
    boolean isFirstValue = true;
    for (String key : valueMap.keySet()) {
    if(key.equals("id")){
    whereBuffer.append(valueMap.get(key));
    whereBuffer.append("';");
    }else {
    if(!isFirstValue){
    sqlBuffer.append(",");
    }
    isFirstValue = false;
    sqlBuffer.append(" `");
    sqlBuffer.append(key);
    sqlBuffer.append("`");
    sqlBuffer.append(" = ");

    sqlBuffer.append("?");
    }
    }

    sqlBuffer.append(whereBuffer);
    return sqlBuffer.toString();
    }


    //根据bean现有的属性 获取对应的key put到map中并返回
    public HashMap<String, String> getBeanHash(Object daoBean) {
    HashMap<String, String> returnHash = new HashMap<String, String>();
    try {
    BeanInfo beanInfo = Introspector.getBeanInfo(daoBean.getClass());
    PropertyDescriptor[] propertyDesc = beanInfo
    .getPropertyDescriptors();

    for (int i = 0; i < propertyDesc.length; i++) {
    try {
    if (propertyDesc[i].getName().compareToIgnoreCase("class") == 0)
    continue;
    String key = propertyDesc[i].getName();
    Method m = propertyDesc[i].getReadMethod();
    if (m != null) {
    Object[] oParam = new Object[] {};
    String value = "" + m.invoke(daoBean, oParam);
    if (!StringUtils.isBlank(value) && !value.equalsIgnoreCase("null")) {
    returnHash.put(key, value);
    }
    }
    } catch (Exception e) {
    e.printStackTrace();
    }

    }

    } catch (Exception e) {
    // TODO: handle exception
    }
    return returnHash;
    }

    //感谢詹波的jfinal开源
    protected Object convert(Class<?> clazz, String s)
    throws ParseException {

    // mysql type: varchar, char, enum, set, text, tinytext, mediumtext,
    // longtext
    if (clazz == String.class) {
    return ("".equals(s) ? null : s); // 用户在表单域中没有输入内容时将提交过来 "",
    // 因为没有输入,所以要转成 null.
    }
    s = s.trim();
    if ("".equals(s)) { // 前面的 String跳过以后,所有的空字符串全都转成 null, 这是合理的
    return null;
    }
    // 以上两种情况无需转换,直接返回, 注意, 本方法不接受null为 s 参数(经测试永远不可能传来null, 因为无输入传来的也是"")

    Object result = null;
    // mysql type: int, integer, tinyint(n) n > 1, smallint, mediumint
    if (clazz == Integer.class || clazz == int.class) {
    result = Integer.parseInt(s);
    }
    // mysql type: bigint
    else if (clazz == Long.class || clazz == long.class) {
    result = Long.parseLong(s);
    }
    // 经测试java.util.Data类型不会返回, java.sql.Date,
    // java.sql.Time,java.sql.Timestamp 全部直接继承自 java.util.Data, 所以
    // getDate可以返回这三类数据
    else if (clazz == java.util.Date.class) {
    if (s.length() >= timeStampLen) {
    // Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
    // result = new
    // java.util.Date(java.sql.Timestamp.valueOf(s).getTime()); //
    // error under jdk 64bit(maybe)
    result = new SimpleDateFormat(timeStampPattern).parse(s);
    } else {
    // result = new
    // java.util.Date(java.sql.Date.valueOf(s).getTime()); // error
    // under jdk 64bit
    result = new SimpleDateFormat(datePattern).parse(s);
    }
    }
    // mysql type: date, year
    else if (clazz == java.sql.Date.class) {
    if (s.length() >= timeStampLen) {
    // result = new
    // java.sql.Date(java.sql.Timestamp.valueOf(s).getTime()); //
    // error under jdk 64bit(maybe)
    result = new java.sql.Date(new SimpleDateFormat(
    timeStampPattern).parse(s).getTime());
    } else {
    // result = new
    // java.sql.Date(java.sql.Date.valueOf(s).getTime()); // error
    // under jdk 64bit
    result = new java.sql.Date(new SimpleDateFormat(datePattern)
    .parse(s).getTime());
    }
    }
    // mysql type: time
    else if (clazz == java.sql.Time.class) {
    result = java.sql.Time.valueOf(s);
    }
    // mysql type: timestamp, datetime
    else if (clazz == java.sql.Timestamp.class) {
    result = java.sql.Timestamp.valueOf(s);
    }
    // mysql type: real, double
    else if (clazz == Double.class) {
    result = Double.parseDouble(s);
    }
    // mysql type: float
    else if (clazz == Float.class) {
    result = Float.parseFloat(s);
    }
    // mysql type: bit, tinyint(1)
    else if (clazz == Boolean.class) {
    result = Boolean.parseBoolean(s);
    }
    // mysql type: decimal, numeric
    else if (clazz == java.math.BigDecimal.class) {
    result = new java.math.BigDecimal(s);
    }
    // mysql type: binary, varbinary, tinyblob, blob, mediumblob, longblob.
    // I have not finished the test.
    else if (clazz == byte[].class) {
    result = s.getBytes();
    }

    return result;
    }


    private void log(String string){
    if(LOG_CONSOLE){
    System.out.println(string);
    }
    }

    }

    这里最重要的两个属性是 tablename 和 clazz。在子类Dao中必须要设置这两个属性:tablename为Dao要操作的表的表明;clazz为对应JavaBean的反射类对象。

    同时最后一个方法convert拷贝自詹波的JFinal中,感谢詹波的慷慨开源。

    下面简单写了个JavaBean,注意,javabean中的各属性名必须和表中的各属性名保持一直,不能有丝毫差错。因为父类Dao中采用反射获取属性名,并把属性名当作字段名。

    package com.tim.DaoProject.dao;

    import java.sql.Connection;

    import com.tim.DaoProject.bean.UserBean;

    public class UserDao extends DAO<UserBean> {

    public UserDao(Connection conn) {
    super(conn);
    this.clazz = UserBean.class;
    this.tablename = "`jdbc_db`.`tb_user`";
    }

    }

    注:本文默认使用的MySql数据库,若使用其他数据库可能会存在Sql语句错误的现象。

  • 相关阅读:
    python用requests请求,报SSL:CERTIFICATE_VERIFY_FAILED错误。
    动态语言,静态语言,强类型定义语言,弱类型定义语言
    Tensorflow学习教程简单练一波,线性模型
    Tensorflow学习教程利用卷积神经网络对mnist数据集进行分类_训练模型
    Tensorflow学习教程tensorboard网络运行和可视化
    Tensorflow学习教程softmax简单介绍
    Tensorflow学习教程非线性回归
    Tensorflow学习教程代价函数
    Tensorflow学习教程普通神经网络对mnist数据集分类
    Tensorflow学习教程利用卷积神经网络对mnist数据集进行分类_利用训练好的模型进行分类
  • 原文地址:https://www.cnblogs.com/JustAlloc/p/3837348.html
Copyright © 2011-2022 走看看