Java Web基础入门第六十讲 使用自己开发好的JDBC框架来升级客户关系管理系统模块

前言:我们已经会编写自己的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);
		}
	}
	
}

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李阿昀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值