ORM框架封装(六)之连接池
作者:互联网
- pool
package pool;
import java.util.ArrayList;
import java.util.List;
/**
* 这是自己设计的一个管理类
* 好多连接需要存储---连接池---List
* 目的是为了管理连接
*/
public class ConnectionPool {
//属性--所谓的"大池子"
private List<MyConnection> connectionList = new ArrayList();
//块 目的是在当前类创建对象的时候 给连接池集合赋值
{
int count = 5;
for(int i=1;i<=count;i++){
connectionList.add(new MyConnection());
}
}
//需要给用户提供一个方法
//可以去"大池子"里获取一个可用连接
//参数 不用
//返回值--连接 Conn MyConn
//考虑用户使用完以后---> MyConn状态 切换状态即可
public MyConnection getMC(){
MyConnection result = null;
//去连接池集合中寻找
for(int i=0;i<connectionList.size();i++){
MyConnection mc = connectionList.get(i);
//判断mc的状态
if(mc.isUsed() == false){//mc是空闲的 可用
mc.setUsed(true);//找到一个mc是可用的 马上占有
result = mc;
break;
}
}
return result;
}
}
package pool;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 这个类就是我们自己要封装的那个类
* 目的是为了将一个连接和一个状态放在一起的
*/
public class MyConnection {
private static String className = "com.mysql.jdbc.Driver";
private static String url = "jdbc:mysql://localhost:3306/newtest?useSSL=false&characterEncoding=utf8";
private static String username = "root";
private static String password = "123456";
//类的加载顺序???
// 属性
// 方法
// 块
// 构造
// 内存中开辟堆内存对象空间 往空间内摆放信息
// 块自动调用执行
//两个属性
private Connection conn;
private boolean used = false;//true被占用 false空闲的
static{
try {
Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
{
//目的是为了每次构造方法执行之前
//默认先执行这个代码块---为了给conn属性赋值
try {
conn = DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void setUsed(boolean used) {
this.used = used;
}
//补充两个get方法
public Connection getConn() {
return conn;
}
public boolean isUsed() {//boolean的get方法命名规范是以is开头
return used;
}
}
package pool;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@SuppressWarnings("all")
public class TestConnection {
public static void main(String[] args) throws Exception {
// String className = "com.mysql.jdbc.Driver";
// String url = "jdbc:mysql://localhost:3306/newtest?useSSL=false&characterEncoding=utf8";
// String username = "root";
// String password = "123456";
// String sql = "select sid,sname,ssex,sage from student";
//
// long t1 = System.currentTimeMillis();
// //JDBC
// //1.导包
// //2.加载驱动
// Class.forName(className);
// //3.获取连接
// Connection conn = DriverManager.getConnection(url,username,password);
// long t2 = System.currentTimeMillis();
// //4.获取状态参数
// PreparedStatement pstat = conn.prepareStatement(sql);
// //5.执行操作 增删改 查询--结果
// ResultSet rs = pstat.executeQuery();
// while(rs.next()){
// int sid = rs.getInt("sid");
// String sname = rs.getString("sname");
// String ssex = rs.getString("ssex");
// int sage = rs.getInt("sage");
// System.out.println(sid+"--"+sname+"--"+ssex+"--"+sage);
// }
// //6.关闭操作
// rs.close();
// pstat.close();
// //conn.close();
// long t3 = System.currentTimeMillis();
// System.out.println("创建连接所需时间:"+(t2-t1));
// System.out.println("执行操作所需时间:"+(t3-t2));
long t1 = System.currentTimeMillis();
//1.导包
//2.加载驱动??------>加载连接池对象
ConnectionPool pool = new ConnectionPool();
//3.获取连接??------>连接池对象获取
MyConnection mc = pool.getMC();
Connection conn = mc.getConn();
long t2 = System.currentTimeMillis();
//4.状态参数
PreparedStatement pstat = conn.prepareStatement("select * from student");
//5.执行操作
ResultSet rs = pstat.executeQuery();
//6.关闭
rs.close();
pstat.close();
mc.setUsed(false);//释放连接---修改状态
System.out.println(t2-t1);
//=====================================================
long t3 = System.currentTimeMillis();
//1.导包
//2.加载驱动??------>加载连接池对象
//3.获取连接??------>连接池对象获取
MyConnection mc2 = pool.getMC();
Connection conn2 = mc2.getConn();
long t4 = System.currentTimeMillis();
//4.状态参数
PreparedStatement pstat2 = conn2.prepareStatement("select * from student");
//5.执行操作
ResultSet rs2 = pstat2.executeQuery();
//6.关闭
rs2.close();
pstat2.close();
mc2.setUsed(false);//释放连接---修改状态
System.out.println(t4-t3);
}
}
- annotation
package orm.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Insert {
//理解为注解就是一个搬运工
//帮用户搬运一条SQL语句 给别人(框架)去解析
//设计一个方法 没有参数 有返回值
String value();
}
package orm.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Delete {
//理解为注解就是一个搬运工
//帮用户搬运一条SQL语句 给别人(框架)去解析
//设计一个方法 没有参数 有返回值
String value();
}
package orm.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Update {
//理解为注解就是一个搬运工
//帮用户搬运一条SQL语句 给别人(框架)去解析
//设计一个方法 没有参数 有返回值
String value();
}
package orm.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Select {
//理解为注解就是一个搬运工
//帮用户搬运一条SQL语句 给别人(框架)去解析
//设计一个方法 没有参数 有返回值
String value();
}
package orm;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Handler {
//============================
//设计一个小弟方法---帮助我们解析SQL语句
SQLAndKey parseSQL(String sql){
//解析之前肯定需要两个变量
StringBuilder newSQL = new StringBuilder();
List<String> keyList = new ArrayList<>();
//解析SQL
//insert into student values(#{sid},#{sname},#{ssex},#{sage})
while(true){
//按照规定的结构来找寻索引位置
int left = sql.indexOf("#{");
int right = sql.indexOf("}");
//判断两个索引的位置是否合法
if(left!=-1 && right!=-1 && left<right){
//找到一组#{key}
newSQL.append(sql.substring(0,left));//截取左边的部分拼接到newSQL里
newSQL.append("?");
keyList.add(sql.substring(left+2,right));
}else{//找不到
newSQL.append(sql);
break;
}
sql = sql.substring(right+1);
}
return new SQLAndKey(newSQL,keyList);
}
//----------------------------
//设计一个小小弟--负责帮下面那个handlerParameter方法处理map集合的拼接
private void setMap(PreparedStatement pstat, Object obj, List<String> keyList) throws SQLException {
//按照keyList规定的顺序 从map中获取元素 让pstat拼接到SQL上
//还原一下obj类型
Map map = (Map)obj;
for(int i=0;i<keyList.size();i++){
pstat.setObject(i+1,map.get(keyList.get(i)));
}
}
//设计一个小小弟--负责帮下面那个handlerParameter方法处理domain的拼接
private void setDomain(PreparedStatement pstat,Object obj,List<String> keyList) throws SQLException, NoSuchFieldException, IllegalAccessException {
//获取obj类型
Class clazz = obj.getClass();
//遍历keyList 规定了顺序
for(int i=0;i<keyList.size();i++){
String key = keyList.get(i);
//去domain对象中获取key对应属性的值
Field field = clazz.getDeclaredField(key);
//直接操作私有属性啦
field.setAccessible(true);
//拼接
// Object obj = 对象; field = clazz.getField();
// value = obj.getName(); value = field.get(对象);
pstat.setObject(i+1,field.get(obj));
}
}
//设计一个小弟方法---帮我们处理参数(SQL和对象中的值拼接在一起)
// 参数pstat Object 顺序? keyList<key>
void handlerParameter(PreparedStatement pstat,Object obj,List<String> keyList) throws SQLException {
//获取这个obj对象的Class
Class clazz = obj.getClass();
//clazz通常可以是什么类型
// 1.基础类型 int-Integer float-Float String
// 2.domain类型 Student Atm Teacher
// 3.map类型
if(clazz==int.class || clazz==Integer.class){
pstat.setInt(1,(Integer)obj);
}else if(clazz==float.class || clazz==Float.class){
pstat.setFloat(1,(Float)obj);
}else if(clazz==double.class || clazz==Double.class){
pstat.setDouble(1,(Double)obj);
}else if(clazz==String.class){
pstat.setString(1,(String)obj);
}else if(clazz.isArray()){
//自己处理 数组循环 对不起我不支持
}else{
//认为只剩下两个可能
//1.map
if(obj instanceof Map){
this.setMap(pstat,obj,keyList);
}else{//domain
try {
this.setDomain(pstat,obj,keyList);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
//----------------------------
//设计一个小小弟--负责帮下面那个handlerResult方法处理map返回值
private Map getMap(ResultSet rs) throws SQLException {
//创建map
Map result = new HashMap<String,Object>();
//获取rs中的全部信息(表格原来的列名 和 查询到的值) Set<Map<列名,值>>
ResultSetMetaData resultSetMetaData = rs.getMetaData();
//遍历含有列的信息
for(int i=1;i<=resultSetMetaData.getColumnCount();i++){
//获取一个列名字
String columnName = resultSetMetaData.getColumnName(i);
//根据列名字获取rs中的值
Object value = rs.getObject(columnName);
result.put(columnName,value);
}
return result;
}
//设计一个小小弟--负责帮下面那个handlerResult方法处理domain返回值
private Object getDomain(ResultSet rs,Class resultType) throws IllegalAccessException, InstantiationException, SQLException, NoSuchFieldException {
Object obj = null;
//通过Class反射创建对象
obj = resultType.newInstance();
//遍历rs
ResultSetMetaData resultSetMetaData = rs.getMetaData();
for(int i=1;i<=resultSetMetaData.getColumnCount();i++){
//获取一个列名字
String columnName = resultSetMetaData.getColumnName(i);
//反射找domain对象中对应列名的哪个属性
Field field =resultType.getDeclaredField(columnName);
//操作私有属性
field.setAccessible(true);
field.set(obj,rs.getObject(columnName));
}
return obj;
}
//设计一个小弟方法---帮我们处理返回值(rs信息取出 组装成一个对象 基础类型 domain map)
Object handlerResult(ResultSet rs,Class resultType) throws SQLException {
Object result = null;//变量用来存储最终的返回值
if(resultType==int.class || resultType==Integer.class){
result = rs.getInt(1);
}else if(resultType==float.class || resultType==Float.class){
result = rs.getFloat(1);
}else if(resultType==double.class || resultType==Double.class){
result = rs.getDouble(1);
}else if(resultType==String.class){
result = rs.getString(1);
}else{
//在这认为是对象 map domain
if(resultType==Map.class){
result = this.getMap(rs);
}else{
try {
result = this.getDomain(rs,resultType);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
return result;
}
//============================
}
package orm;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 这是自己定义的一个规则
* 提供策略的规则接口
*/
public interface RowMapper {
//设计一个规则方法
//将rs的信息组装成一个对象domain
//是否需要参数 rs
//是否需要返回值 <T>
<T>T mapperRow(ResultSet rs) throws SQLException;
}
package orm;
import java.util.ArrayList;
import java.util.List;
/**
* 这是我们自己定义的类
* 是为了解析带有#{key}形式的SQL时候
* 装载解析后的返回值的
* 解析后的返回值有两个
* 一个是带有问号形式的原来SQL
* 一个是ArrayList集合 集合内存放好多key
*/
public class SQLAndKey {
//属性 存放原先形式的sql 带问号的
private StringBuilder sql = new StringBuilder();
//属性 存放解析出来的那些#{key}
private List<String> keyList = new ArrayList();
//带参数的构造方法
public SQLAndKey(StringBuilder sql,List<String> keyList){
this.sql = sql;
this.keyList = keyList;
}
public String getSQL(){
return this.sql.toString();
}
public List<String> getKeyList(){
return this.keyList;
}
}
package orm;
import orm.annotation.Delete;
import orm.annotation.Insert;
import orm.annotation.Select;
import orm.annotation.Update;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 单独设计了一个类
* 负责帮所有的DAO来做事
* 以后只能在这个类的方法中见到JDBC的流程啦
* 以后所有的DAO再也看不见JDBC啦
* 以后的DAO只保留了一条SQL语句
*/
@SuppressWarnings("all")
public class SqlSession {
private Handler handler = new Handler();
//面向配置文件开发
//驱动类 账号 密码都存在文件中
//单独设计一个小弟方法
//负责处理所有的增删改操作
// 参数 SQL , SQL语句上需要的那些问号值
// 返回值? void int--->行数 原本对象形式的容器--->数组Object[] 集合
// insert into student values(?,?,?,?)
// values->Object[] {10,"zzt","男",18}
public void update(String sql,Object... values){//容器目的存储好几个问号值的
String className = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/newtest?useSSL=false&characterEncoding=utf8";
String username = "root";
String password = "123456";
try {
//加载驱动
Class.forName(className);
//获取连接
Connection conn = DriverManager.getConnection(url,username,password);
//创建状态参数----预处理
PreparedStatement pstat = conn.prepareStatement(sql);
//给SQL问号赋值的过程
// 赋值 几个 什么类型
for(int i=0;i<values.length;i++){
pstat.setObject(i+1,values[i]);
}
//执行操作啦
pstat.executeUpdate();
//关闭
pstat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void insert(String sql,Object... values){
this.update(sql,values);
}
public void delete(String sql,Object... values){
this.update(sql,values);
}
//单独设计一个小弟方法
//负责处理所有DAO的单条查询
// 参数 SQL Object[]
// 返回值 <T> Object(Student Atm)
public <T>T selectOne(String sql,RowMapper rm,Object... values){
Object obj = null;
String className = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/newtest?useSSL=false&characterEncoding=utf8";
String username = "root";
String password = "123456";
try {
//加载驱动
Class.forName(className);
//获取连接
Connection conn = DriverManager.getConnection(url,username,password);
//创建状态参数----预处理
PreparedStatement pstat = conn.prepareStatement(sql);
//给SQL问号赋值的过程
// 赋值 几个 什么类型
for(int i=0;i<values.length;i++){
pstat.setObject(i+1,values[i]);
}
//-------------------------------------------
//执行操作啦---查询
ResultSet rs = pstat.executeQuery();
if(rs.next()){
//将rs中的数据取出来 存入一个新的容器里 domain 数组 集合
//1. rs数据取出来 存入一个新的容器--->domain map
//2. 策略模式----多态的时候 银行取钱 去银行取钱的流程固定 每一人执行结果不一样
// 一个类负责制定流程(方法) 提供一个参数(接口) 真正传参数的时候具体子类
// public void test(接口 a){
// 1.
// 2.
// 3.不一样 a.方法();
// 4.
// 5.
// }
// Test t = new Test();
// t.test(a子类对象); 子类重写之后的效果
// 将rs的信息拿出来 组装成一个对象
obj = rm.mapperRow(rs);
//3. 利用反射来完成
}
//关闭
rs.close();//rs就可以关闭啦
pstat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
return (T)obj;
}
//设计一个小弟方法
//负责处理所有DAO的多条查询
// 参数
// 返回值
// select * from student where ssex = ? and sage = ?
// values 男 18
// 三行记录
public <T> List<T> selectList(String sql, RowMapper rm, Object...values){
List<T> list = new ArrayList();
String className = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/newtest?useSSL=false&characterEncoding=utf8";
String username = "root";
String password = "123456";
try {
//加载驱动
Class.forName(className);
//获取连接
Connection conn = DriverManager.getConnection(url,username,password);
//创建状态参数----预处理
PreparedStatement pstat = conn.prepareStatement(sql);
//给SQL问号赋值的过程
// 赋值 几个 什么类型
for(int i=0;i<values.length;i++){
pstat.setObject(i+1,values[i]);
}
//-------------------------------------------
//执行操作啦---查询
ResultSet rs = pstat.executeQuery();
while(rs.next()){
//将rs中的数据取出来 存入一个新的容器里 domain 数组 集合
//1. rs数据取出来 存入一个新的容器--->domain map
//2. 策略模式----多态的时候 银行取钱 去银行取钱的流程固定 每一人执行结果不一样
// 一个类负责制定流程(方法) 提供一个参数(接口) 真正传参数的时候具体子类
// public void test(接口 a){
// 1.
// 2.
// 3.不一样 a.方法();
// 4.
// 5.
// }
// Test t = new Test();
// t.test(a子类对象); 子类重写之后的效果
// 将rs的信息拿出来 组装成一个对象
T obj = (T)rm.mapperRow(rs);
list.add(obj);
//3. 利用反射来完成
}
//关闭
rs.close();//rs就可以关闭啦
pstat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
//方案二(利用反射将上述的方法参数values处理一下)
public void update(String sql,Object obj){
//Object obj可以理解为是原来的那个domain
//新增
//insert into student values(#{sid},#{sname},#{ssex},#{sage})
//values[] sid sname ssex sage 按顺序的?
//student对象 sid sname ssex sage属性---->属性值拼到对应的问号位置上?
//如果用户是按照上面的SQL写过来的
//我们需要做什么???
// 1.解析SQL---> 要每一个#{key} 将#{key}替换回原来的?
// 一条原来形式的sql语句 String sql
// 一堆key 集合ArrayList ArrayList<String> 对象
SQLAndKey sqlAndKey = handler.parseSQL(sql);
//执行JDBC的流程
String className = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/newtest?useSSL=false&characterEncoding=utf8";
String username = "root";
String password = "123456";
try {
//加载驱动
Class.forName(className);
//获取连接
Connection conn = DriverManager.getConnection(url,username,password);
//创建状态参数----预处理
PreparedStatement pstat = conn.prepareStatement(sqlAndKey.getSQL());
//给SQL问号赋值的过程
// 赋值 几个 什么类型
// 问号的值存储在一个对象里的obj 对象里面的值和SQL拼接在一起
if(obj!=null) {
handler.handlerParameter(pstat, obj, sqlAndKey.getKeyList());
}
//执行操作啦
pstat.executeUpdate();
//关闭
pstat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void insert(String sql,Object obj){this.update(sql,obj);}
public void delete(String sql,Object obj){this.update(sql,obj);}
//方案二(利用反射将selectOne方法处理一下 rm values)
public <T>T selectOne(String sql,Object obj,Class resultType){
Object result = null;
try {
//1.解析sql--带#{key}
SQLAndKey sqlAndKey = handler.parseSQL(sql);
//2.获取连接
String className = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/newtest?useSSL=false&characterEncoding=utf8";
String username = "root";
String password = "123456";
//加载驱动
Class.forName(className);
//获取连接
Connection conn = DriverManager.getConnection(url,username,password);
//创建状态参数----预处理
PreparedStatement pstat = conn.prepareStatement(sqlAndKey.getSQL());
//拼接SQL和问号的值
if(obj!=null) {
handler.handlerParameter(pstat, obj, sqlAndKey.getKeyList());
}
//-------------------------------------------
//执行操作啦---查询
ResultSet rs = pstat.executeQuery();
if(rs.next()){
//组装对象 将rs里面的信息取出来 组装成一个对象
result = handler.handlerResult(rs,resultType);
}
//关闭
rs.close();//rs就可以关闭啦
pstat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
return (T)result;
}
public <T>List<T> selectList(String sql,Object obj,Class resultType){
List<T> list = new ArrayList();
try {
//1.解析sql--带#{key}
SQLAndKey sqlAndKey = handler.parseSQL(sql);
//2.获取连接
String className = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/newtest?useSSL=false&characterEncoding=utf8";
String username = "root";
String password = "123456";
//加载驱动
Class.forName(className);
//获取连接
Connection conn = DriverManager.getConnection(url,username,password);
//创建状态参数----预处理
PreparedStatement pstat = conn.prepareStatement(sqlAndKey.getSQL());
//拼接SQL和问号的值
if(obj!=null) {
handler.handlerParameter(pstat, obj, sqlAndKey.getKeyList());
}
//-------------------------------------------
//执行操作啦---查询
ResultSet rs = pstat.executeQuery();
while(rs.next()){
//组装对象 将rs里面的信息取出来 组装成一个对象
list.add((T)handler.handlerResult(rs,resultType));
}
//关闭
rs.close();//rs就可以关闭啦
pstat.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
//=======================================================================
//设计一个方法 让SqlSession帮DAO创建一个代理对象
//让代理对象去代替DAO做一件事情(告知SqlSession做事--调用方法那一行代码的过程)
//如果想要使用代理对象来帮忙做事
//前提是 被代理的那个对象必须是一个接口
public <T>T getMapper(Class clazz){//clazz---StudentDao(接口) 代理对象DAO的子类对象
return (T)Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//invoke方法是代理对象该具体做的事情
//帮助原来的DAO做他原本该做的事情
//DAO原本只做了一件事 调用sqlSession.方法();
//invoke方法方式代理对象的方法
// proxy代理对象
// method被代理的那个方法(DAO的方法)
// args被代理方法执行时的那个参数
//调用上述四个方法的其中一个 增删改查 哪一个呢? 注解名字
//1.获取方法上面的注解
Annotation an = method.getAnnotations()[0];
//2.获取这个注解的类型
Class type = an.annotationType();//Insert Delete Update Select
//3.想要调用如下的方法,还需要注解对象里面的那条SQL语句
//通过注解类型 获取注解类中的那个value方法
Method valueMethod = type.getDeclaredMethod("value");
//反射执行这个方法 获取结果-->SQL
String sql = (String)valueMethod.invoke(an);
//最好将args做一个严谨的处理
Object param = args==null ? null : args[0];
if(type == Insert.class){
SqlSession.this.insert(sql,param);
}else if(type == Delete.class){
SqlSession.this.delete(sql,param);
}else if(type == Update.class){
SqlSession.this.update(sql,param);
}else if(type == Select.class){
//根据方法的返回值类型来确定 单条/多条
Class methodReturnType = method.getReturnType();
if(methodReturnType == List.class){//多条 List<泛型>
//需要解析methodReturnType这个List中的那个泛型
//返回值的具体类型(java.util.List<domain.Student>)
Type returnType = method.getGenericReturnType();
//获取一个能操作泛型的对象 向下转型
ParameterizedTypeImpl realReturnType = (ParameterizedTypeImpl)returnType;
//可以操作返回值反省类
Type[] patternTypes = realReturnType.getActualTypeArguments();//泛型数组
//因为是List集合 泛型数组的第一个
Type patternType = patternTypes[0];
//还原成原来的Class
Class resultType = (Class)patternType;
return SqlSession.this.selectList(sql,param,resultType);
}else{//单条
return SqlSession.this.selectOne(sql,param,methodReturnType);
}
}else{
System.out.println("其他注解 我处理不了");
}
return null;
}
});
//--------------------------------------------------
// //JDK中给我们提供好了一个类
// //Proxy类可以帮我们创建一个代理对象
// //想要通过下面代码创建一个代理对象
// //需要提供三个条件
// // 1.ClassLoader 需要一个类加载器
// ClassLoader loader = clazz.getClassLoader();
// // 2.Class[] 加载的类 有可能代理好多不同的类 正常的使用中 通常就代理一个类
// Class[] interfaces = new Class[]{clazz};
// // 3.InvocationHandler 代理对象代替你做事情的时候 具体该怎么做
// InvocationHandler handler = new InvocationHandler(){
// public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// //代理对象的执行方法 帮真实对象做事
// //sqlSession.insert(sql,student);
// return null;
// }
// };
// return (T)Proxy.newProxyInstance(loader,interfaces,handler);
}
}
标签:java,封装,String,rs,pstat,ORM,sql,import,连接池 来源: https://blog.csdn.net/m0_51945027/article/details/113724269