使用自己开发好的JDBC框架来升级客户关系管理系统模块

来源:互联网 发布:反馈神经网络算法 c 编辑:程序博客网 时间:2024/06/06 02:59

我们已经会编写自己的JDBC框架了,不会写的请参考我的笔记编写自己的JDBC框架。
现在我们来使用自己开发好的JDBC框架来升级客户关系管理系统模块,关于怎么设计客户关系管理系统模块,也请参考我的笔记JDBC实现客户关系管理系统模块。

在应用程序中加入dbcp连接池

导入相关jar包:

  • commons-dbcp-1.4.jar
  • commons-pool-1.6.jar

在类目录下加入dbcp的配置文件:dbcpconfig.properties。dbcpconfig.properties的配置信息如下:

#连接设置driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/day16username=rootpassword=yezi#<!-- 初始化连接 -->initialSize=10#最大连接数量maxActive=50#<!-- 最大空闲连接 -->maxIdle=20#<!-- 最小空闲连接 -->minIdle=5#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->maxWait=60000#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。connectionProperties=useUnicode=true;characterEncoding=utf8#指定由连接池所创建的连接的自动提交(auto-commit)状态。defaultAutoCommit=true#driver default 指定由连接池所创建的连接的只读(read-only)状态。#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)defaultReadOnly=#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLEdefaultTransactionIsolation=READ_COMMITTED

如下图所示:
这里写图片描述
将cn.itcast.utils包下的获取数据库连接的工具类(JdbcUtils)的代码修改为:

public class JdbcUtils {    private static DataSource ds = null;    // 静态代码块只执行一次,因为静态代码块在类加载时执行,类永远只加载一次    static {        // 初始化连接池        try {            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");            Properties prop = new Properties();            prop.load(in);            BasicDataSourceFactory factory = new BasicDataSourceFactory();            ds = factory.createDataSource(prop);        } catch (Exception e) {            throw new ExceptionInInitializerError(e);        }    }    public static Connection getConnection() throws SQLException {        return ds.getConnection(); // 不会将真正的MySQL驱动返回的Connection返回给你    }    public static void release(Connection conn, Statement st, ResultSet rs) {        if (rs!=null) {            try {                rs.close(); // 假设throw异常            } catch (Exception e) {                e.printStackTrace(); // 只需在后台记录异常            }            rs = null; // 假设rs对象没有释放,将其置为null,该对象就变成垃圾,由Java垃圾回收器回收        }        if (st!=null) {            try {                st.close(); // 假设throw异常            } catch (Exception e) {                e.printStackTrace(); // 只需在后台记录异常            }            st = null;        }        if (conn!=null) {            try {                conn.close();            } catch (Exception e) {                e.printStackTrace(); // 只需在后台记录异常            }        }    }    // 抽取增删改的公共代码      /*     * String sql = "insert into account(id,name,money) values(?,?,?)";     * Object[]{1, "aaa", 10000}     */    public static void update(String sql, Object[] params) throws SQLException {        Connection conn = null;        PreparedStatement st = null;        ResultSet rs = null;        try {            conn = getConnection();            st = conn.prepareStatement(sql);            for (int i = 0; i < params.length; i++) {                st.setObject(i+1, params[i]);            }            st.executeUpdate();        } finally {            release(conn, st, rs);        }    }    // 抽取查询的公共代码,优化查询,替换掉所有的查询    public static Object query(String sql, Object[] params, ResultSetHandler handler) throws SQLException {        Connection conn = null;        PreparedStatement st = null;        ResultSet rs = null;        try {            conn = getConnection();            st = conn.prepareStatement(sql);            for (int i = 0; i < params.length; i++) {                st.setObject(i+1, params[i]);            }            /*             * 框架的设计者是不知道要执行的sql语句的,             * 执行该sql语句,拿到的结果集,如何对结果集进行处理框架的设计者也是不知道的             * 那该怎么办呢?框架的设计者不知道没关系,但使用该框架的人是知道怎么对结果集进行处理的,             * 那就让他去做这种事情。             * 代码该这样写:我对外暴露一个接口,使用该框架的人去实现该接口做这种事情,我针对接口进行调用。这是一种设计模式——策略模式             */            rs = st.executeQuery();            return handler.handler(rs);        } finally {            release(conn, st, rs);        }    }}

使用自己开发好的JDBC框架来升级客户关系管理系统模块

在cn.itcast.utils包下创建一个对外暴露的ResultSetHandler接口。
这里写图片描述
ResultSetHandler接口的具体代码如下:

public interface ResultSetHandler {    public Object handler(ResultSet rs);}

编写该项目要使用的结果集处理器

BeanHandler——将结果集转换成bean对象的处理器

在cn.itcast.utils包下创建一个处理器——BeanHandler.java,该处理器用于将结果集转换成bean对象。
这里写图片描述
BeanHandler类的具体代码如下所示:

//框架设计者在编写这个处理器的时候,并不知道把结果集处理到哪个对象里面去,//框架的设计者不知道没关系,但使用该框架的人总该知道,到时候在使用这个结果集处理器时传给框架设计者public class BeanHandler implements ResultSetHandler {    private Class clazz;    public BeanHandler(Class clazz) {        this.clazz = clazz;    }    @Override    public Object handler(ResultSet rs) {        try {            if (!rs.next()) {                return null;            }            // 创建封装结果集的bean            Object bean = clazz.newInstance();            // 得到结果集的元数据,以获取结果集的信息            ResultSetMetaData meta = rs.getMetaData();            int count = meta.getColumnCount();            for (int i = 0; i < count; i++) {                String name = meta.getColumnName(i+1); // 获取到结果集每列的列名     id                Object value = rs.getObject(name);     // 1                // 反射出bean上与列名相应的属性                Field f = bean.getClass().getDeclaredField(name);                f.setAccessible(true);                f.set(bean, value);            }            return bean;        } catch (Exception e) {            throw new RuntimeException(e);        }    }}

BeanListHandler——将结果集转换成bean对象的list集合的处理器

在cn.itcast.utils包下创建一个处理器——BeanListHandler.java,该处理器用于将结果集转换成bean对象的list集合。
这里写图片描述
BeanListHandler类的具体代码如下:

public class BeanListHandler implements ResultSetHandler {    private Class clazz;    public BeanListHandler(Class clazz) {        this.clazz = clazz;    }    @Override    public Object handler(ResultSet rs) {        List list = new ArrayList();        try {            while (rs.next()) {                Object bean = clazz.newInstance();                ResultSetMetaData meta = rs.getMetaData();                int count = meta.getColumnCount();                for (int i = 0; i < count; i++) {                    String name = meta.getColumnName(i+1);                    Object value = rs.getObject(name);                    Field f = bean.getClass().getDeclaredField(name);                    f.setAccessible(true);                    f.set(bean, value);                }                list.add(bean);            }        } catch (Exception e) {            throw new RuntimeException(e);        }        return list;    }}

IntHandler——将结果集转换成int的处理器

在cn.itcast.utils包下创建一个处理器——IntHandler.java,该处理器用于将结果集转换成一个int数。
这里写图片描述
IntHandler类的具体代码如下:

public class IntHandler implements ResultSetHandler {    @Override    public Object handler(ResultSet rs) {        try {            if (rs.next()) {                return rs.getInt(1);            }        } catch (SQLException e) {            throw new RuntimeException(e);        }        return 0;    }}

修改CustomerDaoImpl的代码

使用我们自己开发好的JDBC框架来简化CustomerDaoImpl类代码的编写。CustomerDaoImpl类修改后的代码如下:

public class CustomerDaoImpl implements CustomerDao {    @Override    public void add(Customer c) {        try {            String sql = "insert into customer(id, name,gender,birthday,cellphone,email,preference,type,description) values(?,?,?,?,?,?,?,?,?)";            Object[] params = {c.getId(),c.getName(),c.getGender(),c.getBirthday(),c.getCellphone(),c.getEmail(),c.getPreference(),c.getType(),c.getDescription()};            JdbcUtils.update(sql, params);        } catch (SQLException e) {            throw new DaoException(e);        }    }    @Override    public void update(Customer c) {        try {            String sql = "update customer set name=?,gender=?,birthday=?,cellphone=?,email=?,preference=?,type=?,description=? where id=?";            Object[] params = {c.getName(),c.getGender(),c.getBirthday(),c.getCellphone(),c.getEmail(),c.getPreference(),c.getType(),c.getDescription(),c.getId()};            JdbcUtils.update(sql, params);        } catch (SQLException e) {            throw new DaoException(e);        }    }    @Override    public void delete(String id) {        try {            String sql = "delete from customer where id=?";            Object[] params = {id};            JdbcUtils.update(sql, params);        } catch (SQLException e) {            throw new DaoException(e);        }    }    @Override    public Customer find(String id) {        try {            String sql = "select * from customer where id=?";            Object[] params = {id};            return (Customer) JdbcUtils.query(sql, params, new BeanHandler(Customer.class));        } catch (SQLException e) {            throw new DaoException(e);        }       }    @Override    public List<Customer> getAll() {        try {            String sql = "select * from customer";            Object[] params = { };            return (List) JdbcUtils.query(sql, params, new BeanListHandler(Customer.class));        } catch (SQLException e) {            throw new DaoException(e);        }       }    @Override    // 获取到页面数据和页面大小    public QueryResult pageQuery(int startindex, int pagesize) {        QueryResult qr = new QueryResult();        // 还要进行一次查询,查询出总记录数        try {            String sql = "select * from customer limit ?,?";            Object[] params = {startindex, pagesize};            List list = (List) JdbcUtils.query(sql, params, new BeanListHandler(Customer.class));            qr.setList(list);            sql = "select count(*) from customer";            params = new Object[]{ };            int totalrecord = (Integer) JdbcUtils.query(sql, params, new IntHandler());            qr.setTotalrecord(totalrecord);            return qr;        } catch (SQLException e) {            throw new DaoException(e);        }       }}

这样写代码,是不是感觉很清爽啊!不像以前那样臃肿了,这个得赞一个!!!

0 0
原创粉丝点击