关闭

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

标签: Java-Web基础
669人阅读 评论(0) 收藏 举报
分类:

我们已经会编写自己的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.Driver
url=jdbc:mysql://localhost:3306/day16
username=root
password=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, SERIALIZABLE
defaultTransactionIsolation=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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:353170次
    • 积分:6898
    • 等级:
    • 排名:第3420名
    • 原创:132篇
    • 转载:132篇
    • 译文:132篇
    • 评论:156条
    博客专栏
    最新评论