本文概览:本文介绍了mybatis大致实现原理。分为sqlSessionTempalte@Responsitory两种实现方式

1 底层实现

每一个线程对于一个数据源会生成一个sqlSession,通过这个sqlSession可以执行mapper文件定义的sql。sqlSessionTempalte@Responsitory两种实现方式都是基于这个底层来实现的,如下图所示:

snip20161210_35

1. 1 Mapper文件

mapper中一个sql对应一个stament。解析mapper文件时会生成一个map:

  • key为sql的id。这里id就是mapper文件的namesapce和sql语句中定义的id两部分拼接组成,这就保证了所有mapper中的sql都有一个唯一的id
  • value为生成一个statement所需要的属性MappedStaement。即如<select >中配置的timeout、resultMap、resultType等属性。

1.2 DefaultSqlSession

1、作用

用来执行执行sql,每一个线程对于一个数据源有一个SqlSession。

2、执行一个sql的过程如下

  • 根据id从Mapper文件生成的map中找到对应的属性MappedStement。其中id就是mapper中namesapce和sql中id属性的拼接。
  • 取当前线程dataSource对应的connection,结合MapperdStament,生成一个stament;
  • 执行stament;
  • 关闭stament。

2 两种方式实现

2.2 SqlSessionTemplate

1、作用

用来执行update/select等操作。

2、实现

通过sqlSeesionFactory获取当前线程对应数据源的DefalutSqlSession,然后通过DefaultSqlSession来执行。

3、使用SqlSessionTemplate实现Dao

2.2 MapperScannerConfigurer

1、作用

实现了@Respository方式

2、实现

首先,将每一个定义的dao接口生成一个动态代理对象,放置到IOC容易中。

然后,通过代理对象执行某一个函数,具体逻辑为:

  • 根据函数名可以从mapper文件生成的map中获取对应的MappedStatement。根据函数名生成map中key的逻辑为:“包名+类名+函数名”
  • 通过sqlSeesionFactory获取当前线程对应数据源的DefalutSqlSession,然后通过DefaultSqlSession来执行。

3、使用

2.3 比较SqlSessiontTemplate和MapperScannerConfigureer

1、执行的步骤共同点都是一样的,如下

  • 第一步 获取一个唯一key。这个key是根据mapper文件的namesapce和一个sql的id拼接生成;
  • 第二步 通过DefaulteSqlSession来执行这个key。如下DeflultSqlSession中一个函数,参数statement就是上面的key值。

2、不同点

在上面第一步中获取key的方式是不同的:

  • 对于SqlSessiontTemplate,是需要自己指定的key。如下

  • @Respository方式,程序自己根据自己定义的dao接口中方法,获取一个key,如下,此时代码,此时对于count这个函数的key就是“包名+类名+函数名”,即dao.mybatis.annotation.datasource1.StudentDao,也是“mapper文件中namesapce的值+sql的id属性”。

3 一些总结

1. 在mybtais中,每一个线程中对于一个数据源有一个connection。

(1)通过TreadLocal来存储,key为数据源。

(2)不同mapper中定义的sql,每一个mapper中sql对应一个statmenet,如果他们数据源一样,则对应的connection是同一个。

2. 默认情况下,自动提交会设置为true,此时每一次执行一个stament(mapper中的一个sql),都会进行默认提交。但是这个线程对应dataSouce的connection会一直保留,线程执行完毕之后,连接池会回收这个connection。

(全文完)

分类&标签

发表评论

电子邮件地址不会被公开。 必填项已用*标注