在使用别人的框架时,框架中会有很多符合我们需求的方法,一般情况下我们只用熟练掌握如何使用即可,对于框架而言,万变不离其宗,我们如果了解底层的运行逻辑,不仅可以加深我们对框架使用的理解,也能在我们自身拥有封装搭建框架时完善自身的框架。
于是我打算保存一些简易化的底层代码实现,以便日后回顾和优化。
线程池简易模拟:
package com.util.Connection;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.List;
/**
* 模拟 数据库连接池,管理,分配连接对象
* @author qiufen
* 连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,
* 当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。
* 使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。
* 而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、
* 连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
*
*/
public class ConnectionPool {
private List<Connection> list=new ArrayList<>(); //连接池
int initialSize; //初始连接数
public ConnectionPool(int initialSize) {
this.initialSize=initialSize;
init();
}
// 系统初始化
public void init() {
try {
//创建size个连接对象,存储在list集合中
Class.forName("com.mysql.jdbc.Driver");
for(int i=0;i<initialSize;i++) {
String url="jdbc:mysql://localhost:3306/j2005_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai";
Connection conn=DriverManager.getConnection(url, "root", "123456");
list.add(conn);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//用户需要连接对象的时候,并不是重新创建,而是直接从连接池中获取
public synchronized Connection getConnection() {
while(list.isEmpty()) { //如果没有可用的连接对象,则进入等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Connection conn=list.remove(0); //直接获取连接对象使用
return conn;
}
// 使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。
public synchronized void returnConn(Connection conn) {
list.add(conn);
this.notifyAll(); //唤醒在连接池上等待的其他线程,可以使用连接对象
}
}
模拟BeanHandler处理器:
package com.pojo.DataBaseConn;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.dbutils.ResultSetHandler;
/**
* 将结果集转换成java对象
*
* @author qiufen
*
* @param <T>
*/
public class BeanHandler<T> implements ResultSetHandler<T> {
private final Class<? extends T> type;
public BeanHandler(Class<? extends T> type) {
this.type = type;
}
@Override
public T handle(ResultSet rs) throws SQLException {
T obj = null;
if (rs != null) {
while (rs.next()) {
Map<String, Object> map = new HashMap<String, Object>();
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount(); // 获取表中列的个数
for (int i = 1; i <= columnCount; i++) {
// 获取列名
String columnName = metaData.getColumnName(i);
// 列名对应的值
Object value = rs.getObject(columnName);
// 把列名---值
map.put(columnName, value);
}
// map---》转换成对象
obj = mapToJavaBean(map);
}
}
return obj;
}
private <T> T mapToJavaBean(Map<String, Object> map) {
T obj = null;
try {
// 创建一个T对象
obj = (T) type.newInstance();
// 获取这个类的属性名
Field[] fs = type.getDeclaredFields();
for (Field f : fs) {
System.out.println("Hero类中的属性:" + f.getName() + "," + f.getType());
f.setAccessible(true); // 暴力访问
// 反射操作
if (f.getType() == int.class) {
f.set(obj, (Integer) map.get(f.getName()));
}
if (f.getType() == String.class) {
f.set(obj, (String) map.get(f.getName()));
}
if (f.getType() == java.util.Date.class) {
f.set(obj, (java.sql.Date) map.get(f.getName()));
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
}
模拟QueryRunner类:
package com.pojo.DataBaseConn;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbutils.ResultSetHandler;
public class QueryRunner {
private DataSource dataSource;
public QueryRunner(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* 通用的插入,修改,删除的方法
* @param sql
* @param params
* @return
* @throws SQLException
*/
public int update(String sql,Object... params)throws SQLException{
//1.从连接池中获取连接
Connection conn=dataSource.getConnection();
//2.创建预编译处理对象
PreparedStatement ps=conn.prepareStatement(sql);
//3.给sql语句中的问号赋值
if(params!=null && params.length>0) {
for(int i=0;i<params.length;i++) {
ps.setObject(i+1, params[i]);
}
}
//4,执行sql语句
int n=ps.executeUpdate();
return n;
}
/**
*
* @param <T> 泛型方法
* @param sql 指向select语句
* @param rsh 处理结果集的接口,handle方法,将结果集转换成T类型
* @param params sql语句?参数的值
* @return 转换后的对象
* @throws SQLException
*/
public <T> T query(String sql, ResultSetHandler<T> rsh,Object... params) throws SQLException {
//1.获取连接对象
Connection conn=dataSource.getConnection();
//2.创建预编译处理对象
PreparedStatement ps=conn.prepareStatement(sql);
//3,若sql语句有问号,则给问号赋值
if(params!=null && params.length>0) {
for(int i=0;i<params.length;i++) {
ps.setObject(i+1, params[i]);
}
}
//4.执行sql语句
ResultSet rs=ps.executeQuery();
//5.调用处理器的方法,将结果集转换成T类型
T obj=rsh.handle(rs);
return obj ;
}
}