public class MybatisUtils {
//初始化 SqlSessionFactory 对象 使SqlSessionFactory为空
private static SqlSessionFactory sqlSessionFactory = null;
static {
try{
//1 读取配置文件为(.properties) 结尾的文件一定要注意路径
String resource ="sqlMapConfig.xml";
//官方解释:Resources 类为从类路径中加载资源,提供了易于使用的方法
//大白话:Resources就是从你的.properties文件中得到路径,然后用
//getResourceAsReader(resource):
//INPUTSTREAM是字节流,READER是字符流,字符流是我们平常可见的字符,可以打印出来看(反正也看不懂),字节流就是二进制数据10011010这种(也看不懂)
//InputStream is =Resources.getResourceAsStream
Reader reader = Resources.getResourceAsReader(resource);
//SqlSessionFactoryBuilder是利用XML或者Java代码来获得资源并构建SqlSessionFactory。
//通过SqlSessionFactoryBuilder可以构建一个SqlSessionFactory。
//SqlSessionFactoryBuilder的作用就是一个构建器。
//.build的方法是获取流数据
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader );
}
catch(Exception e)
{
e.printStackTrace();
}
}
//1.定义Threadlocal存储类型为SqlSession
private static ThreadLocal threadLocal = new ThreadLocal<>();
//获取 SqlSession 对象的静态方法
public static SqlSession getSession()
{
//2.从线程里面获取共享的SqlSession对象
SqlSession sqlSession = threadLocal.get();
//3.对象为空,创建一个新的sqlSession写入线程共享ThreadLocal中
if(sqlSession==null){
sqlSession = sqlSessionFactory.openSession(true);
System.out.println(sqlSession+",初始化SqlSession资源");
threadLocal.set(sqlSession);
}
//4.返回有效对象
return sqlSession;
}
//根据给定的接口类型直接返回接口代理对象
public static T getMapper(Class interfaceClass){
return getSession().getMapper(interfaceClass);
}
//关闭sqlSession
public static void closeSession(SqlSession sqlSession){
sqlSession.commit();
sqlSession.close();
System.out.println(sqlSession+",释放SqlSession资源");
//从线程共享变量里面移出sqlSession
threadLocal.remove();
}
public static T getProxyMapper(Class interfaceClass){
/*
* 参数1:类加载器,
* 参数2:被代理对象实现的接口
* 参数3:处理器
* */
Class[] classes = new Class[1];//class类型的数组,数组长度为1
classes[0]=interfaceClass;//里面存储了interfaceClass 参数
/*
* newProxyInstance,方法有三个参数:
* loader: 用哪个类加载器去加载代理对象
* interfaces:动态代理类需要实现的接口
* h:动态代理方法在执行时,会调用h里面的invoke方法去执行
* */
Object proxyMapper = Proxy.newProxyInstance(interfaceClass.getClassLoader(), classes, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
SqlSession session = MybatisUtils.getSession();
T mapper = session.getMapper(interfaceClass);
//调用原有功能
Object res = method.invoke(mapper, args);
//释放资源
MybatisUtils.closeSession(session);
return res;
}
});
return (T)proxyMapper;
}
}