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<SqlSession> 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> T getMapper(Class<T> 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> T getProxyMapper(Class<T> 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;
}
}