码迷,mamicode.com
首页 > 数据库 > 详细

JDBC的进化4--最终进化

时间:2015-03-08 01:26:17      阅读:285      评论:0      收藏:0      [点我收藏+]

标签:jdbc   记录   

除去直接调用开源组织给提供的jar包外,我今天要说的内容就是JDBC的最终版,需要我们多敲多练多理解。最重要的是理解。废话不多说了,开始吧。
早上的时候,我将昨天的内容整理,能处理事务的通用方法写到了JDBCUtils工具类中。
其实到这里的时候,所有细节部分的代码都已经实现了。接下来要进行的内容,其实就是对这些内容的整合,整体的调控。
我们来说DAO:
现在我们希望这个程序能更加自动化一点,我们只需要提供一个连接,它就能返回给我们一个对象或一个对象集,或一个结果。或是我们提供一个连接,一个对象,它就能自动的实现增删改。那么DAO就是这样产生的。
应用泛型类,我们将DAO设计成适用于可操作不同对象的增删改查的父类。具体的操作 由操纵具体实体类 的子类DAO 来完成。
来看代码:
DAO:

public class Dao<T> {
    Class<T> clazz = null;

    @SuppressWarnings("unchecked")
    public Dao(){
        Type type = this.getClass().getGenericSuperclass();
        ParameterizedType pt = (ParameterizedType) type;
        Type[] types = pt.getActualTypeArguments();
        clazz = (Class<T>) types[0];
        System.out.println(clazz);
    }

    protected List<T> getGroupValue(Connection conn, String sql, Object...args){
        List<T> list = new ArrayList<T>();
        // get PreparedStatement‘s object
        PreparedStatement ps = null;
        // execute sql
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(sql);

            // set ps
            for(int i = 0; i < args.length; i++){
                ps.setObject(i+1, args[i]);
            }

            rs = ps.executeQuery();
            ResultSetMetaData rsmd = rs.getMetaData();
            int columnCount = rsmd.getColumnCount();
            System.out.println(columnCount);

            while(rs.next()){
                T t = clazz.newInstance();
                for(int i = 1; i <= columnCount; i++){
                    // read
                    String columnName = rsmd.getColumnLabel(i);
                    Object columnValue = rs.getObject(columnName);

                    // write
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t, columnValue);
                }
                list.add(t);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs, ps, null);
        }

        return list;
    }

    protected Object getValue(Connection conn, String sql, Object... args){
        Object object = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // get PreparedStatement‘s object
            ps = conn.prepareStatement(sql);

            // set ps 
            for(int i = 0; i < args.length; i++){
                ps.setObject(i+1, args[i]);
            }

            // execute the sql
            rs = ps.executeQuery();

            // read rs
            if(rs.next()){
                object = rs.getObject(1);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs, ps, null);
        }

        return object;
    }

    /**
     * getPrepareAllTransaction()
     * 
     * @param conn
     * @param sql
     * @param clazz
     * @param args
     * @return
     */
    protected List<T> getPrepareAllTransaction(Connection conn, String sql,
            Object... args) {
        List<T> list = new ArrayList<T>();
        // get PreparedStatement
        PreparedStatement ps = null;
        // execute the sql
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(sql);
            // set the ps
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }
            rs = ps.executeQuery();
            // get the columnNum
            ResultSetMetaData rsmd = rs.getMetaData();
            int columnNum = rsmd.getColumnCount();
            // read the rs and write to an object
            while (rs.next()) {
                T t = clazz.newInstance();
                for (int i = 1; i <= columnNum; i++) {
                    // read
                    String columnName = rsmd.getColumnLabel(i);
                    Object columnVal = rs.getObject(columnName);

                    // through the method(reflect)
                    PropertyUtils.setProperty(t, columnName, columnVal);
                }
                list.add(t);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs, ps, null);
        }
        return list;
    }

    /**
     * getTransacation
     * 
     * @param conn
     * @param sql
     * @param clazz
     * @param args
     * @return
     */
    protected T getPrepareTransaction(Connection conn, String sql, Object... args) {
        T t = null;
        // get PreparedStatement‘s object
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            ps = conn.prepareStatement(sql);

            // set the ps
            ps.setObject(1, args[0]);

            rs = ps.executeQuery();

            ResultSetMetaData rsmd = rs.getMetaData();

            int columnNum = rsmd.getColumnCount();

            // read and write
            if (rs.next()) {
                t = clazz.newInstance();
                for (int i = 1; i <= columnNum; i++) {
                    // read
                    String columnName = rsmd.getColumnLabel(i);
                    Object columnValue = rs.getObject(columnName);

                    // write
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t, columnValue);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs, ps, null);
        }
        return t;
    }

    /**
     * Update
     * 
     * @param conn
     * @param sql
     * @param args
     * @return
     */
    protected int transactionUpdate(Connection conn, String sql, Object... args) {
        // get preparedStatement‘s object
        PreparedStatement ps = null;
        // execute the ps
        int rows = 0;
        try {
            conn = JDBCUtils.getConnection();
            ps = conn.prepareStatement(sql);

            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }
            rows = ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(ps, null);
        }
        // return
        return rows;
    }
}

发现,里面的方法和我们之前写的方法没有什么区别,只不过因为T的声明到了DAO里,所以我们下面的方法中就不需要再次声明。同时提供了一个构造方法,方法中利用反射,获取了当前对象的类的父类的泛型类型this.getClass().getGenericSuperClass(); 这是获取了父类所有泛型的类型,里面可能有一个值比如DAO<T>,也可能存在多个值,比如Map<K, V> ,通过API我们发现,Type中没有这样的方法可以将里边的类型全部取出来,而它的子接口中提供了这样的方法。
ParameterizedType pt = (ParameterizedType) type;
getActualTypeArguments() 返回一个type[]数组。这里因为我们知道就有一个泛型类型,直接取索引为0的元素即为泛型类型。

创建一个具体的操作类:

public class UserDAO extends Dao<User>{
    // select function
    public Object getSpecialValue(Connection conn){
        String sql = "SELECT count(*) FROM users";
        return getValue(conn, sql);
    }

    // select All
    public List<User> getAllUser(Connection conn){
        String sql = "SELECT * FROM users";
        return getPrepareAllTransaction(conn, sql);
    }

    // select info through id....
    public User getUser(Connection conn, int id){
        String sql = "SELECT * FROM users WHERE id = ?";
        return getPrepareTransaction(conn, sql, id);
    }

    //delete
    public int delete(Connection conn, int id){
        String sql = "DELETE FROM users WHERE id = ?";
        return transactionUpdate(conn, sql, id);

    // update
    public int update(Connection conn, User user){
        String sql = "UPDATE users SET address = ? WHERE id = ?";
        return transactionUpdate(conn, sql, user.getAddress(), user.getId());

    }

    // insert
    @Test
    public int insert(Connection conn, User user){
        String sql = "INSERT INTO users(name, address, phone) values(?,?,?)";
        int rows = transactionUpdate(conn, sql, user.getName(), user.getAddress(), user.getPhone());
        return rows;
    }
}

这里这个类是用来操作User类的。测试这里就不写了。还是要说一下刚刚的构造器。
我们在创建UserDao的时候,它默认的会调用UserDao的无参构造器,而又因为有继承,这个UserDao的构造器又会默认的调用父类DAO的构造器,再按照上面的步骤分析,是不是就明白了。
这样做的好处就是,我们不用在有的方法中继续重复的写Class clazz这个参数。
DAO就算说完了。
到这里为止,就要画个分割线了。之前的部分需要我们多多理解。因为这是后面学习三大框架的基础,核心。按照从进化1到最终进化这个思路,随便在一个编辑器里,从头到尾写三遍。我感觉很有必要。

————————————————华丽丽的分割线—————————————-
接下来是开源组织提供的一些工具类,他能帮我们完成上面所有的内容。当然可能他们写的更好,但是核心的思想就是上面这些。

获取连接:
推荐:c3p0
推荐理由:可以通过xml文件来进行配置。

执行SQL语句:
DbUtils()

具体的使用,参考他们提供的帮助文档。


今天实在是瞌睡的不行了,学校烦心的事情又比较多,本来想放弃更这篇博客的。但是又想了想,如果我这一放弃,就会给我以后的放弃带来更多的理由,而我克服了。我会坚持下去。加油吧,少年。

JDBC的进化4--最终进化

标签:jdbc   记录   

原文地址:http://blog.csdn.net/sloverpeng/article/details/44126887

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!