自己动手写泛型dao

来源:互联网 发布:svm算法原理 编辑:程序博客网 时间:2024/06/05 14:11

在经过一系列的问题得到解决之后,泛型dao终于写出来了。泛型dao相比于以前写的dao最大的好处就是,大大提高了代码的复用性,以往我们要对数据库中表中的数据进行操作的时候,每张表都需要写一个dao来操作,当表非常多的时候,代码量就会很大,还有就是这些代码大部分都是重复的,获取数据库连接、sql预处理,返回结果集,最后关闭数据库连接,获取数据库连接和关闭资源可以放在一个数据库工具类中很简单,剩下的对数据进行操作的方法,由于我们事先不知道要对那张表进行操作,所以就需要利用一些特殊的手段来获取,动态的获取,利用反射这个特性,我们可以很容易的获得我们想要得到的信息。

在前面有一篇文章讲了反射获取类中信息的例子: 通过反射获取属性名和属性类型这篇文章就是在这里遇到的问题

还有就是在存储获得到的数据时候,需要用到有序的键值对在:有序的Map集合--LinkedHashMap中说明了

下面开始正题:
代码结构:


在例子中用到了c3p0和读取properties配置文件连接数据库,构建数据库连接池,在第一个方法中写了注释,剩下的方法都是类似的

注意:代码中有get和getset方法分别是拼接get方法和set方法的方法……还有获得属性信息的getField方法都在代码的最后面

package com_basedao;import java.util.List;/** * Created with IDEA * author:DuzhenTong * Date:2017/11/8 * Time:19:40 */public interface BaseDao<T> {    void update(T t, String password, int id);    void insert(T t);    void delete(T t, int id);    List selectAll(T t);    List selectOne(T t,int id);}


package com_daoImp;import com_basedao.BaseDao;import com_util.JdbcUtil;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.*;/** * Created with IDEA * author:DuzhenTong * Date:2017/11/8 * Time:19:46 */public class BaseDaoImp<T> implements BaseDao<T>{    private Connection connection;    private PreparedStatement preparedStatement;    private ResultSet resultSet;    private String sql;    private List<Object> list = null;    //LinkedHashMap是一个有顺序的map集合    private static Map<String, String> map = new LinkedHashMap<String, String>();    /**     * 查询表中所有数据     * @param t     * @return     */    @Override    public List<Object> selectAll(T t) {        //初始化字符串        StringBuffer stringBuffer = new StringBuffer("select * from ");        //创建对象的容器list集合        list = new ArrayList<Object>();        //获取类的类        Class clazz =t.getClass();        //获取到类的名字处理拼接sql语句        sql = stringBuffer.append(clazz.getSimpleName()).toString().toLowerCase();        try {            connection = JdbcUtil.getInstance().getConnection();            preparedStatement = connection.prepareStatement(sql);            resultSet = preparedStatement.executeQuery();            while (resultSet.next()) {                //利用反射获得对象                Object object = clazz.newInstance();                getField(object);                int i = 1;                //遍历map集合                for (Map.Entry<String, String> entry : map.entrySet()) {                    if ("int".equals(entry.getValue())) {                        //利用发射获取实体类中的set方法                        Method method = clazz.getMethod(getSet(entry.getKey()), int.class);                        //执行方法                        method.invoke(object, resultSet.getInt(i));                        //从结果集中想要获取列值需要一个计数器如果查到的是本列加一                        i++;                    }                    if ("String".equals(entry.getValue())) {                        Method method = clazz.getMethod(getSet(entry.getKey()), String.class);                        method.invoke(object, resultSet.getString(i));                        i++;                    }                }                list.add(object);            }        } catch (SQLException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (InvocationTargetException e) {            e.printStackTrace();        }finally {            JdbcUtil.releaseResources(connection,preparedStatement,resultSet);        }        return list;    }    /**     * 根据id查询     * @param t     * @param id     * @return     */    @Override    public List<Object> selectOne(T t,int id) {        StringBuffer stringBuffer = new StringBuffer("select * from ");        list = new ArrayList<Object>();        Class clazz = t.getClass();        sql = stringBuffer.append(clazz.getSimpleName()+" where id=?").toString().toLowerCase();        try {            connection = JdbcUtil.getInstance().getConnection();            preparedStatement = connection.prepareStatement(sql);            preparedStatement.setInt(1,id);            resultSet = preparedStatement.executeQuery();            while (resultSet.next()) {                Object object = clazz.newInstance();                getField(t);                int i = 1;                for (Map.Entry<String, String> entry : map.entrySet()) {                    if ("int".equals(entry.getValue())) {                        Method method = clazz.getMethod(getSet(entry.getKey()), int.class);                        method.invoke(object, resultSet.getInt(i));                        i++;                    }                    if ("String".equals(entry.getValue())) {                        Method method = clazz.getMethod(getSet(entry.getKey()), String.class);                        method.invoke(object, resultSet.getString(i));                        i++;                    }                }                list.add(object);            }        } catch (SQLException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (InvocationTargetException e) {            e.printStackTrace();        }finally {            JdbcUtil.releaseResources(connection,preparedStatement,resultSet);        }        return list;    }    /**     * 根据id删除记录     * @param t     * @param id     */    @Override    public void delete(T t, int id){        StringBuffer stringBuffer = new StringBuffer("delete from ");        Class clazz = t.getClass();        String tableName = clazz.getSimpleName().toLowerCase();        sql = stringBuffer.append(tableName + " where id=?").toString();        try {            connection = JdbcUtil.getInstance().getConnection();            preparedStatement = connection.prepareStatement(sql);            preparedStatement.setInt(1, id);            preparedStatement.execute();        } catch (SQLException e) {            e.printStackTrace();        }finally {            JdbcUtil.releaseResources(connection, preparedStatement, null);        }    }    /**     * 修改密码     * @param t     * @param password     * @param id     */    @Override    public void update(T t, String password, int id) {        Class clazz = t.getClass();        String tableName = clazz.getSimpleName().toLowerCase();        StringBuffer stringBuffer = new StringBuffer("update " + tableName + " set password=? where id=?");        sql = stringBuffer.toString();        try {            connection = JdbcUtil.getInstance().getConnection();            preparedStatement = connection.prepareStatement(sql);            preparedStatement.setString(1, password);            preparedStatement.setInt(2, id);            preparedStatement.execute();        } catch (SQLException e) {            e.printStackTrace();        } finally {            JdbcUtil.releaseResources(connection, preparedStatement, null);        }    }    /**     * 增加记录     * @param t     */    @Override    public void insert(T t) {        StringBuffer stringBuffer = new StringBuffer("insert into ");        Class clazz = t.getClass();        String table = clazz.getSimpleName().toLowerCase();        try {            Object object = t;            getField(object);            stringBuffer.append(table + " values(");            for (int i = 0; i < map.size(); i++) {                if (i == map.size() - 1) {                    stringBuffer.append("?)");                }else {                    stringBuffer.append("?,");                }            }            sql = stringBuffer.toString();            connection = JdbcUtil.getInstance().getConnection();            preparedStatement = connection.prepareStatement(sql);            System.out.println(sql);            int i=1;            for (Map.Entry<String, String> entry : map.entrySet()) {                if ("int".equals(entry.getValue())) {                    Method method = clazz.getMethod(get(entry.getKey()));                    System.out.println(method.invoke(object,null));                    preparedStatement.setInt(i,(int)method.invoke(object,null));                    i++;                }                if ("String".equals(entry.getValue())) {                    Method method = clazz.getMethod(get(entry.getKey()));                    preparedStatement.setString(i,(String)method.invoke(object,null));                    i++;                }            }            preparedStatement.execute();        }  catch (IllegalAccessException e) {            e.printStackTrace();        } catch (SQLException e) {            e.printStackTrace();        } catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (InvocationTargetException e) {            e.printStackTrace();        }finally {            JdbcUtil.releaseResources(connection,preparedStatement,null);        }    }    /**     * 根据属性名拼接set方法字符串     * @param str     * @return     */    public static String getSet(String str) {        return "set" + str.substring(0, 1).toUpperCase() + str.substring(1);    }    /**     * 拼接get方法     * @param str     * @return     */    public static String get(String str) {        return "get" + str.substring(0, 1).toUpperCase() + str.substring(1);    }    public static void getField(Object object) {        Class clazz = object.getClass();        // 获取实体类的所有属性,返回Field数组        Field[] fields = clazz.getDeclaredFields();        for (Field field : fields) {            String type = field.getGenericType().toString();            /*如果是String听会带有class java.lang.String截取再放入map中,其他直接放入            * 把属性名作为键,属性类型作为值*/            if ("class java.lang.String".equals(type)) {                int index = type.lastIndexOf(".");                map.put(field.getName(), type.substring(index + 1));            } else {                map.put(field.getName(), field.getGenericType().toString());            }        }    }}

数据库工具类:JdbcUtil  用到了单例模式

package com_util;import com.mchange.v2.c3p0.ComboPooledDataSource;import java.beans.PropertyVetoException;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Properties;public class JdbcUtil {    private Properties properties = new Properties();    private static String dirverName;    private static String url;    private static String username;    private static String password;    private static ComboPooledDataSource dataSource;    private static JdbcUtil jdbcUtil = new JdbcUtil();    private JdbcUtil() {        try {            InputStream inputStream = JdbcUtil.class.getClassLoader()                    .getResourceAsStream("datebase.properties");//            从输入字节流读取属性列表(键和元素对)            properties.load(inputStream);//            用此属性列表中指定的键搜索属性,获取驱动,url,username,password            dirverName = properties.getProperty("driverName").trim();            url = properties.getProperty("url").trim();            username = properties.getProperty("username").trim();            password = properties.getProperty("password").trim();            dataSource = new ComboPooledDataSource();            dataSource.setUser(username);            dataSource.setPassword(password);            dataSource.setJdbcUrl(url);            dataSource.setDriverClass(dirverName);            dataSource.setInitialPoolSize(5); //初始化连接数            dataSource.setMinPoolSize(1);//最小连接数            dataSource.setMaxPoolSize(20);//最大连接数            dataSource.setMaxStatements(50);//最长等待时间            dataSource.setMaxIdleTime(60);//最大空闲时间,单位毫秒        } catch (PropertyVetoException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }    public static JdbcUtil getInstance(){        return jdbcUtil;    }    public synchronized Connection getConnection() {        Connection conn = null;        try {            conn=dataSource.getConnection();        } catch (SQLException e) {            e.printStackTrace();        }        return conn;    }//关闭连接工具方法    public static void releaseResources(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) {        if (resultSet != null) {            try {                resultSet.close();            } catch (SQLException e) {                e.printStackTrace();            }        }        if (connection != null) {            try {                connection.close();            } catch (SQLException e) {                e.printStackTrace();            }        }        if (preparedStatement != null) {            try {                preparedStatement.close();            } catch (SQLException e) {                e.printStackTrace();            }        }    }}

实体类:用于测试

package com_domain;public class Users {  private int id;  private String name;  private String password;  private int aid;  @Override  public String toString() {    return "Users{" +            "id=" + id +            ", name='" + name + '\'' +            ", password='" + password + '\'' +            ", aid=" + aid +            '}';  }  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public String getPassword() {    return password;  }  public void setPassword(String password) {    this.password = password;  }  public int getAid() {    return aid;  }  public void setAid(int aid) {    this.aid = aid;  }}

datebase.properties数据库连接配置文件

driverName=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/testusername=rootpassword=root

代码放在了github上,可以下载完整代码(Code_story仓库fanxing文件夹):https://github.com/Ai-yoo/Code_story.git

原创粉丝点击