使用 DBUtils 编写通用的DAO

主要遇到的问题:

->DAO的实现方式不止JDBC一种,所以要写一个DAO接口,然后用JDBC来实现,实现其中的方法
->如果要通用的话,必须要泛型,可是 queryRunner 中的部分方法要获取 存储对象的class文件,要考虑如何获取 T.class

UML图
这里写图片描述

1.配置 c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <named-config name="helloc3p0">

        <!-- 指定连接数据源的基本属性 -->
        <property name="user">root</property>
        <property name="password">1995</property>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///db_javaee</property>

        <!-- 若服务器中连接数不足时,一次向数据库服务器申请多少个连接 -->
        <property name="acquireIncrement">50</property>
        <!-- 初始化数据库连接池时连接的数量 -->
        <property name="initialPoolSize">5</property>
        <!-- 数据库连接池中的最小的数据库连接数 -->
        <property name="minPoolSize">50</property>
        <!-- 数据库连接池中的最大的数据库连接数 -->
        <property name="maxPoolSize">1000</property>

        <!-- C3P0 数据库连接池可以维护的 Statement 的个数 -->
        <property name="maxStatements">20</property>
        <!-- 每个连接同时可以使用的 Statement 对象的个数 -->
        <property name="maxStatementsPerConnection">5</property> 
    </named-config>
</c3p0-config>

2.编写JDBCTools

package com.anqi.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JDBCTools {

    private static DataSource dataSource = null;

    //数据库连接池只需要被初始化一次
    static {
        dataSource = new ComboPooledDataSource("helloc3p0");
    }

    public static Connection getConnection() throws Exception {
        return dataSource.getConnection();
    }
    public static void releaseDb(ResultSet resultSet, Statement sta, Connection con) {
        if(resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(sta != null) {
            try {
                sta.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(con != null) {
            try {
                //数据库连接池的 connection 对象进行 close 时
                //并不是真的进行关闭,而是把数据库连接归还到数据库连接池中
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

3.DAO接口

package com.anqi.jdbc;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/**
 * 返回数据的 DAO 接口
 * 里边定义好访问数据表的个各种方法
 * 可供 JDBC 实现、JDBCUtils 实现等
 * @param T:DAO 处理的实体类的类型
 */
public interface DAO<T> {

    /**
     * 批量处理的方法
     * @param con
     * @param sql
     * @param args:填充占位符的 Object [] 类型的可变参数
     */
    void batch(Connection con, String sql, Object[] ...args); 

    /**
     * 返回一个具体的值,比如总人数,平均工资,某人的姓名等
     * @param con
     * @param sql
     * @param args
     * @return
     */
    <E> E getForValue(Connection con, String sql, Object ...args);

    /**
     * 返回 T 的一个请求
     * @param con
     * @param sql
     * @param args
     * @return
     */
    List<T> getForList(Connection con, String sql, Object ...args);

    /**
     * 返回一个 T 的对象
     * @param con
     * @param sql
     * @param args
     * @return
     * @throws SQLException 
     */
    T get(Connection con, String sql, Object ...args) throws SQLException;

    /**
     * INSERT,UPDATE,DELETE
     * @param con:数据库连接
     * @param sql:sql 语句
     * @param args:填充占位符的参数
     */
    void update(Connection con, String sql, Object ... args);

}

4.JDBC实现DAO接口

package com.anqi.jdbc;
import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

/**
 * 使用 QueryRunner 提供其具体实现
 * @param <T> 子类传入的泛型类型
 */
public class JdbcDaoImp<T> implements DAO<T>{

    private QueryRunner queryRunner = null;
    private Class<T> type;
    public JdbcDaoImp() {
        queryRunner = new QueryRunner(); 
        type =(Class<T>) ((ParameterizedType)getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
    }

    public void batch(Connection con, String sql, Object[]... args) {

    }

    public Object getForValue(Connection con, String sql, Object... args) {
        return null;
    }

    public List getForList(Connection con, String sql, Object... args) {
        return null;
    }

    public T get(Connection con, String sql, Object... args) throws SQLException {
        return queryRunner.query(con, sql, new BeanHandler<>(type),args);
    }

    public void update(Connection con, String sql, Object... args) {

    }

}

5.CustomerDao 可以再此处添加其他业务,也可以直接使用访问进行数据访问

package com.anqi.jdbc;

public class CustomerDao extends JdbcDaoImp<Customer>{


}

猜你喜欢

转载自blog.csdn.net/baidu_37181928/article/details/79485780