mybatis源码分析

    之前看了看mybatis的日志模块源码,对mybatsi的运行流程也有了一些兴趣,下面我们从sqlsessionFactory开始,看看mybatis是如何实现orm查询的。

    一般初始化sqlSessionFactory的代码如下:mybatis的config文件通过Resources类中的静态方法传入,可以接受Reader或者inputStream。然后通过sqlSessionFactoryBuilder构造sqlSessionFactory,然后拿到sqlsession,通过getMapper方法传入dao接口或者通过selectList等方法传入dao接口路径和DO类。

 public static void main(String[] args) throws IOException {
        SqlSessionFactory builder = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("resources path"));
        SqlSession sqlSession = builder.openSession();
        QueryDao mapper = sqlSession.getMapper(QueryDao.class);
//        Entry entry = new Entry();
//        List<Object> list = sqlSession.selectList("mapping.namespace",entry);
        List list = mapper.queryList();
    }
    static class Entry{
        String name;
        int age;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }
    }
    interface QueryDao {
        List queryList();
    }

把以上的过程稍微拆分一下:

            //解析xml
            InputStream resourceAsStream = Resources.getResourceAsStream(resources);
            XMLConfigBuilder xmlConfigBuilder = new XMLConfigBuilder(resourceAsStream);
            Configuration parse = xmlConfigBuilder.parse();
            //返回configure
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(parse);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //getMapper
            StudentDAO mapper = sqlSession.getMapper(StudentDAO.class);
            Student student = mapper.showStudent(2276189);

1.通过ClassLoader获取配置文件输入流

2.构造XMLConfigBuilder对象,用于解析xml文件

3.xml解析,把配置文件中的内容映射到Configuration对象中

4.通过SqlSessionFactoryBuilder传入一个configuration对象构建SqlSessionFactory

5.openSession开启会话

6.拿到mapper代理对象

        前三布没什么好说的,无论什么框架都要经过xml解析,但解析的细节有的是自己实现的,有的引用了别的开源框架,mybatis用的应该是封装后的SAX。然后parse,把一些必要的属性和对象初始化。

        第四部也没什么好说的,一个工厂模式,把sax解析后的confguration对象set到SqlSessionFactory里了。我们主要看openSession和getMapper。openSession代码如下:

DefaultSqlSessionFactory.openSessionFromDataSource

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

exectype是个枚举类,有三种状态,SIMPLE, REUSE, BATCH,分别是基础类型,重用(缓存过),批量,默认使用SIMPLE,后面的事务隔离等级和自动提交为null。至于configuration.getEnvironment(),顾名思义,对应的是conf文件中的Environment标签及内容。然后通过事务工厂新建个事务,如果你的mybatis没和spring整合,这个事务会使用默认的mybatis包装后的jdbc事务。然后是新建一个Executor执行器,代码如下:

public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    if (ExecutorType.BATCH == executorType) {
      executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      executor = new SimpleExecutor(this, transaction);
    }
    if (cacheEnabled) {
      executor = new CachingExecutor(executor);
    }
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }
如果第一次创建,则会使用simpleExecutor,这个执行器会被缓存的executor包装起来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值