Mybits源码分析

mybatis简介

mybatis是一款优秀的半自动化持久层框架,它支持定制化SQL,存储过程以及高级映射。Mybatis避免了几乎所有的JDBC代码和手动设置参数获取结果集。Mybatis可以使用简单的XML或者注解来配置和映射原生信息,将java的pojo映射成数据库中的记录。

优点:SQL统一维护配置文件中,方便管理维护,半自动化,插件支持,简单易学

接下来我们对Mybits的底层代码进行解析

流程总结

1、读取Mybatis配置文件信息

2、获取SqlSessionFactory

 

3、获取session

 

4、操作mapper接口

主要代码

        // 1.定义mybatis_config文件地址
        String resources = "mybatis_config.xml";
        // 2.获取InputStreamReaderIo流
        Reader reader = Resources.getResourceAsReader(resources);
        // 3.获取SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        // 4.获取Session
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 5.操作Mapper接口
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

 1、读取Mybatis配置文件信息

首先调用getResourceAsStream(String resource)方法,传入mybatis-config.xml

然后该方法里面又调用了本类中的两个参数的getResuorceAsStream(ClassLoader loader,String resource)方法。

通过classLoaderWrapper.getResourceAsStream(resource, loader)方法来获取流,

再调用getResourceAsStream(resource, loader)方法,然后再调用了本类中的getResourceAsStream(String resource, ClassLoader[ ] classLoader)方法

最后判断类加载器中所读的流是否为null,如果不为null,则返回InputStream对象。

InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
    for (ClassLoader cl : classLoader) {
       if (null != cl) {
         InputStream returnValue = cl.getResourceAsStream(resource)
         if (null == returnValue) {
            returnValue = cl.getResourceAsStream("/" + resource);
         }
     
         if (null != returnValue) {
            return returnValue;
         }
      }
    }
    return null;
 }

2、获取SqlSessionFactory

首先创建SqlSessionFactoryBuilder对象;然后调用build(InputStream inputStream)方法;

再调用本类中的build(InputStream inputStream, String environment, Properties properties),

然后创建解析器parser,通过Xpath解析的方式去解析mybatis-config.xml 文件,保存到configuration对象中 ,

后返回DefaultSqlSessionFactory对象。

3、获取session

首先调用openSession()方法,再去调用本类中的openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit)方法。

接而创建事务tx,获取environment信息,通过environment构建出transactionFactory事务工厂,通过事务工厂对事物进行设置。

newExecutor(),根据Executor在全局配置中的类型,创建出对应的执行器,

最后返回 DefaultSqlSession对象。

 

SqlSession session = sqlsessionfactor.openSession();

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {

Transaction tx = null;

try {

final Environment environment = configuration.getEnvironment();

final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);

tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);

final Executor executor = configuration.newExecutor(tx, execType);

return new DefaultSqlSession(configuration, executor, autoCommit);

} catch (Exception e) {

closeTransaction(tx); // may have fetched a connection so lets call close()

throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);

} finally {

ErrorContext.instance().reset();

}

}

4、操作mapper接口

调用DefaultSqlSession中getMapper(Class<T> type)方法。

再调用Configuration中的getMapper(Class<T> type, SqlSession sqlSession)方法。

再调用MapperRegistry中的getMapper(Class<T> type, SqlSession sqlSession)方法。

调用mapperProxyFactory中的newInstance(SqlSession sqlSession)方法获取一个MapperProxy对象mapperProxy。

根据mapperProxy调用newInstance(MapperProxy<T> mapperProxy),创建出MapperProxy的代理对象并且返回。

 

UserMapper mapper = session.getMapper(UserMapper.class);

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {

final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);

if (mapperProxyFactory == null)

throw new BindingException("Type " + type + " is not known to the MapperRegistry.");

try {

return mapperProxyFactory.newInstance(sqlSession);

} catch (Exception e) {

throw new BindingException("Error getting mapper instance. Cause: " + e, e);

}

}

protected T newInstance(MapperProxy<T> mapperProxy) {

return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);

}

public T newInstance(SqlSession sqlSession) {

final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);

return newInstance(mapperProxy);

 

【目的】 如果您希望弄懂框架的原理,但是苦于不知道如何读框架源码? 希望该课程能够通过带领大家阅读源码的方式,了解源码是如何阅读的。该课程选择了一个比较小,比较简单的框架入门,相信大家应该也用过该工具——mybatis generator 【内容】 该课程内容如下,列出了具体时间,便于复习: 第一课:mybatis-generator源码分析-解析配置 这节课分为如下几段: 【00:00-05:00】:介绍源码阅读的方法 【05:00-08:00】:简介mybatis-generator的使用 【08:00-27:30】:mybatis-generator包一览 【27:30-结束】:解析配置源码解读 【总结】所在的位置:1.第一次总结【34:15】。2.第二次总结【52:40】 涉及的【设计思路】和【设计模式】:1.模板模式【15:30】。2.xml解析的对象设计+组合模式:【37:00】。3.策略模式:【45:40】 第二课:mybatis-generator源码分析-生成文件 这节课分为如下几段:        1. 【00:00-10:20】:上节课内容回顾        2. 【10:20-42:20】:如何从数据库中获取元数据信息        3. 【42:20-结束】:生成文件 【总结】所在的位置:1.第一次总结【37:45】。2.第二次总结【56:25】 涉及的【设计思路】和【设计模式】:1、简单工厂方法模式【35:20】。2、聚合的设计思想【44:00】。 第三课:mybatis-generator源码分析-总结 这节课分为如下几段:         1. 【00:00-01:00】: 设计思路总结         2. 【01:00-02:50】:配置解析总结         3. 【02:50-03:55】: 从数据库获取信息总结         4. 【03:55-结束】: 文件的生成总结         
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页