前言:我们已经会编写自己的JDBC框架了,不会写的请参考我的笔记《Java Web基础入门第五十九讲 编写自己的JDBC框架》。现在我们来使用自己开发好的JDBC框架来升级客户关系管理系统模块,关于怎么设计客户关系管理系统模块,也请参考我的笔记《Java Web基础入门第四十八讲 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=liayun
#<!-- 初始化连接 -->
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.liayun.utils包下的获取数据库连接的工具类(JdbcUtils)的代码修改为:
package cn.liayun.utils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class JdbcUtils {
private static DataSource ds = null;
//在静态代码块里面初始化DBCP链接池
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();
}
public static void release(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if (st != null) {
try {
st.close();
} catch (Exception e) {
e.printStackTrace();
}
st = null;
}
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
conn = null;
}
}
//以下方法用来抽取增删改的公共代码
/*
* 别人调用以下方法时,会传进来如下参数:
* String sql = "insert into account(id,name,money) values(?,?,?)";
* Object[]{1,"haha",1000}
*/
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]);
}
rs = st.executeQuery();
return handler.handler(rs);
} finally {
release(conn, st, rs);
}
}
}
使用自己开发好的JDBC框架来升级客户关系管理系统模块
在cn.liayun.utils包下创建一个对外暴露的ResultSetHandler接口,该接口的具体代码如下:
package cn.liayun.utils;
import java.sql.ResultSet;
public interface ResultSetHandler {
public Object handler(ResultSet rs);
}
编写该项目要使用的结果集处理器
BeanHandler——将结果集转换成bean对象的处理器
在cn.liayun.utils包下创建一个处理器——BeanHandler.java,该处理器用于将结果集转换成bean对象。
package cn.liayun.utils;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
/*
* 框架设计者在编写这个处理器的时候,并不知道把结果集处理到哪个对象里面去,
* 框架的设计者不知道没关系,但使用该框架的人总该知道吧,到时候他在使用这个结果集处理器时传递给框架设计者即可。
*/
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);//获取到结果集每列的列名
Object value = rs.getObject(name);//获取到结果集每列的值(id-1)
//反射出bean上与列名相应的属性
Field f = bean.getClass().getDeclaredField(name);
f.setAccessible(true);
f.set(bean, value);//取到每列的数据,并把每列的数据全部整到bean上与列名相应的属性上面去了
}
return bean;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
BeanListHandler——将结果集转换成bean对象的List集合的处理器
在cn.liayun.utils包下创建一个处理器——BeanListHandler.java,该处理器用于将结果集转换成bean对象的List集合。
package cn.liayun.utils;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
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.liayun.utils包下创建一个处理器——IntHandler.java,该处理器用于将结果集转换成一个int数。
package cn.liayun.utils;
import java.sql.ResultSet;
public class IntHandler implements ResultSetHandler {
@Override
public Object handler(ResultSet rs) {
try {
if (rs.next()) {
return rs.getInt(1);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return 0;
}
}
修改CustomerDaoImpl的代码
使用我们自己开发好的JDBC框架来简化CustomerDaoImpl实现类代码的编写。CustomerDaoImpl类修改后的代码如下:
package cn.liayun.dao.impl;
import java.sql.SQLException;
import java.util.List;
import cn.liayun.dao.CustomerDao;
import cn.liayun.domain.Customer;
import cn.liayun.domain.QueryResult;
import cn.liayun.exception.DaoException;
import cn.liayun.utils.BeanHandler;
import cn.liayun.utils.BeanListHandler;
import cn.liayun.utils.IntHandler;
import cn.liayun.utils.JdbcUtils;
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<Customer>) JdbcUtils.query(sql, params, new BeanListHandler(Customer.class));
} catch (SQLException e) {
throw new DaoException(e);
}
}
//获取到页面数据以及总记录数
public QueryResult pageQuery(int startindex, int pagesize) {
QueryResult qr = new QueryResult();
try {
String sql = "select * from customer limit ?,?";
Object[] params = {startindex, pagesize};
List<Customer> list = (List<Customer>) JdbcUtils.query(sql, params, new BeanListHandler(Customer.class));
qr.setList(list);
sql = "select count(*) from customer";
params = new Object[]{};
int totalrecord = (int) JdbcUtils.query(sql, params, new IntHandler());
qr.setTotalrecord(totalrecord);
return qr;
} catch (SQLException e) {
throw new DaoException(e);
}
}
}
这样写代码,是不是感觉很清爽啊!不再像以前那样臃肿了,这个得赞一个!!!