首页 > 技术文章 > MyBatisUtils工具类的书写以及解释

RHsama 2020-07-31 21:39 原文

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;
    }
}

推荐阅读