Mybatis基础

说明:本文基本是读了湖畔微风大神的微博后写下的总结,有很多详细细节没有给出,只是用来当做个人笔记,如果要详细了解Mybatis,请参考原大神微博,地址:点击打开链接http://blog.csdn.net/hupanfeng/article/details/9068003

一、Mybatis简介

1、mybatis结构图

从该结构图可知mybatis的功能架构分为三层:
(1)API结构层:提供给外部使用的结构API,开发人员通过这些本地API来操纵数据库;
(2)数据处理层:负责具体的sql查找、sql解析、sql执行和执行结果映射处理;
(3)基础支持层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载、缓存管理;
2、mybatis执行流程图

SqlSessionFactoryBuilder
每一个mybatis应用程序的入口都是SqlSessionFactoryBuilder,他的作用是通过xml配置文件创建Configuration对象,然后通过build方法创建SqlSessionFactory对象,没有必要每次访问Mybatis就创建一次SqlSessionFactoryBuilder,通常的做法是创建一个全局的对象就可以了。
SqlSessionFactory
SqlSessionFactory对象由SqlSessionFactoryBuilder创建。它的主要功能是创建SqlSession对象,和SqlSessionFactoryBuilder对象一样,没有必要每次访问Mybatis就创建一次SqlSessionFactory,通常的做法是创建一个全局的对象就可以了。SqlSessionFactory对象一个必要的属性是Configuration对象,它是保存Mybatis全局配置的一个配置对象,通常由SqlSessionFactoryBuilder从XML配置文件创建。
SqlSession
SqlSession对象的主要功能是完成一次数据库的访问和结果的映射,它类似于数据库的session概念,由于不是线程安全的,所以SqlSession对象的作用域需限制方法内。SqlSession的默认实现类是DefaultSqlSession,它有两个必须配置的属性:Configuration和Executor。Configuration前文已经描述这里不再多说。SqlSession对数据库的操作都是通过Executor来完成的。

到目前为止,我们看到的都是mybatis的流程,我们的应用程序在什么地方插入到这个流程中并获得我们想要的结果呢?就是SqlSession这里。SqlSession有一个重要的方法getMapper,顾名思义,这个方式是用来获取Mapper对象的。什么是Mapper对象?根据Mybatis的官方手册,应用程序除了要初始并启动Mybatis之外,还需要定义一些接口,接口里定义访问数据库的方法,存放接口的包路径下需要放置同名的XML配置文件。SqlSession的getMapper方法是联系应用程序和Mybatis纽带,应用程序访问getMapper时,Mybatis会根据传入的接口类型和对应的XML配置文件生成一个代理对象,这个代理对象就叫Mapper对象。应用程序获得Mapper对象后,就应该通过这个Mapper对象来访问Mybatis的SqlSession对象,这样就达到里插入到Mybatis流程的目的。
Executor
Executor对象在创建Configuration对象的时候创建,并且缓存在Configuration对象里。Executor对象的主要功能是调用StatementHandler访问数据库,并将查询结果存入缓存中(如果配置了缓存的话)。

StatementHandler

StatementHandler是真正访问数据库的地方,并调用ResultSetHandler处理查询结果。

ResultSetHandler

处理查询结果。

二、Configuration

MyBatis配置文件中大标签configuration下子标签包括:

1、properties
properties里配置的属性将被存放在Configuration的variables变量里,供Mybatis使用。
dataSource里也可指定属性值,并且resource里属性值的优先级高于property子节点里配置的值,也就是说resource的同名属性将会覆盖于property子节点里的值。
2、settings
setting节点里配置的值会直接改写Configuration对应的变量值,这些变量描述的是Mybatis的全局运行方式,如果对这些属性的含义不熟悉的话建议不要配置,使用默认值即可。
3、typeAliases类型命名
别名是为Java类型命名一个短的名字。它只用在XML配置文件里,用来减少类完全限定名的多余部分。
4、typeHandlers类型处理器
无论是MyBatis在预处理语句中设置一个参数,还是从结果集中取出一个值时,类型处理器被用来将获取的值以合适的方式转换成Java类型。
5、plugins插件
插件可以改变某些类的执行, MyBatis允许被插件来拦截的类有:
Executor、ParameterHandler、ResultSetHandler、StatementHandler。
6、environments环境
environments里可以配置多个environment,每个environment对应一个数据库环境。
environment属性:
id:通过id属性与其他数据库环境区别
 transactionManager:

MyBatis中有两种事务管理器类型(也就是type=”[JDBC|MANAGED]”):

JDBC这个配置直接简单使用了JDBC的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围。

MANAGED这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期(比如SpringJEE应用服务器的上下文)

 dataSource:

MyBatis中有三种数据源类型(也就是type=”[UNPOOLED | POOLED| JNDI]”):

UNPOOLED –这个数据源的实现是每次被请求时简单打开和关闭连接,需要配置的属性:

driver – 这是JDBC驱动的Java类的完全限定名

url – 这是数据库的JDBC URL地址。

username – 登录数据库的用户名。

password – 登录数据库的密码。

defaultTransactionIsolationLevel – 默认的连接事务隔离级别。

7、mapper映射器
Mappers用于告诉Mybatis去哪里寻找sql映射文件。sql映射文件是Mybatis最灵活的地方。

8、如何构建configuration
Configuration在SqlSessionFactoryBuilder创建SqlSessionFactory时创建,通过XMLConfigBuilder的parse方法创建。

三、MapperBuilder

1、mapper文件结构:
cache:配置本命名空间的缓存
cache-ref:从其他命名空间引用缓存配置
resultMap:结果映射
parameterMap :废弃
sql:可重用的sql语句块
insert|update|delete|select–数据库操作语句
2、解析
Mapper的解析在XMLMapperBuilder里完成,主要通过configurationElement方法完成解析,在configurationElement内部调用各个元素的子解析方法完成解析。
buildStatementFromContext方法负责解析statement元素。id属性用于区分不同的statement元素,在同一个配置文件中可以配置多个statement元素。通过调用XMLStatementBuilder的parseStatementNode方法完成解析。在这个方法内有几个重要的步骤,理解他们对正确的配置statement元素很有帮助。其中insert|update|delete|select都属于statement元素。
(1)动态配置子元素
statement节点可以配置各种子元素,比如前面提到的include子元素和selectKey子元素等(在动态sql里还有更多的子元素,具体参考mybatis的官方文档)。动态解析子元素通过parseDynamicTags方法完成。该方法根据子元素的类型递归的解析成一个个的SqlNode,这些SqlNode对象提供了apply方法,供后续调用时生成sql语句所需。需要注意的是SelectKey没有对应的SqlNode对象,因为它的功能是用来生成KeyGenerator对象的(具体来说是SelectKeyGenerator对象)。另外,SelectKey节点生成的KeyGenerator优先级高于statement节点的useGeneratedKeys属性生成的KeyGenerator对象,也就是说配置了SelectKey子节点就不需要再配置useGeneratedKeys属性了。
(2)生成sqlSource
SqlSource用于后续调用时根据SqlNode和参数对象生成sql语句。它接收一个叫做rootsqlNode的对象作为构造参数。
(3)生成KeyGenerator
如果配置了selectKey子元素,KeyGenerator直接使用selectKey子元素里生成的KeyGenerator对象(具体来说是SelectKeyGenerator对象)。若没配置,则如果useGeneratedKeys属性的值为"true"且配置了 keyProperty属性,则生成默认的Jdbc3KeyGenerator对象,该对象调用JDBC驱动的getGeneratedKeys方法返回insert语句执行后生成的自增长主键。
(4)创建MappedStatement
MappedStatement对象封装了statement元素的所有属性以及子节点值,MappedStatement对象有一个id属性用于唯一标记它,这个id由namespace加statement元素的id属性值构成。创建好的MappedStatement对象存入Configuration对象的mappedStatements缓存中,key为MappedStatement对象的id值。
注册mapper类型

我们知道每个mapper配置文件的namespace属性对应于某个接口,应用程序通过接口访问mybatis时,mybatis会为这个接口生成一个代理对象,这个对象就叫mapper对象,在生成代理对象前mybatis会校验接口是否已注册,未注册的接口会产生一个异常。为了避免这种异常,就需要注册mapper类型。这个步骤是在XMLMapperBuilder的bindMapperForNamespace方法中完成的。它通过调用Configuration对象的addMapper方法完成,而Configuration对象的addMapper方法是通过MapperRegistry的addMapper方法完成的,它只是简单的将namespace属性对应的接口类型存入本地缓存中。

Configuration对象提供了一个重载的addMappers(StringpackageName)方法,该方法以包路径名为参数,它的功能是自动扫描包路径下的接口并注册到MapperRegistry的缓存中,同时扫描包路径下的mapper配置文件并解析之。解析配置文件是在MapperAnnotationBuilder类的parse方法里完成的,该方法先解析配置文件,然后再解析接口里的注解配置,且注解里的配置会覆盖配置文件里的配置,也就是说注解的优先级高于配置文件,这点需要注意。采用自动扫描会大大简化配置,只不过需要应用程序自己调用,mybatis默认是不会调用这个方法的

四、SqlSession

1、Sqlsession
Sqlsession对应着一次数据库会话。由于数据库回话不是永久的,因此Sqlsession的生命周期也不应该是永久的,相反,在你每次访问数据库时都需要创建它(当然并不是说在Sqlsession里只能执行一次sql,你可以执行多次,当一旦关闭了Sqlsession就需要重新创建它),创建Sqlsession的地方只有一个,那就是SqlsessionFactory的openSession方法。

2、Executor的创建

Executor与Sqlsession的关系就像市长与书记,Sqlsession只是个门面,真正干事的是Executor,Sqlsession对数据库的操作都是通过Executor来完成的。

如果不开启cache的话,创建的Executor只是3中基础类型之一,BatchExecutor专门用于执行批量sql操作,ReuseExecutor会重用statement执行sql操作,SimpleExecutor只是简单执行sql没有什么特别的。开启cache的话(默认是开启的并且没有任何理由去关闭它),就会创建CachingExecutor,它以前面创建的Executor作为唯一参数。CachingExecutor在查询数据库前先查找缓存,若没找到的话调用delegate(就是构造时传入的Executor对象)从数据库查询,并将查询结果存入缓存中。

CacheExecutor

CacheExecutor有一个重要属性delegate,它保存的是某类普通的Executor,值在构照时传入。执行数据库update操作时,它直接调用delegateupdate方法,执行query方法时先尝试从cache中取值,取不到再调用delegate的查询方法,并将查询结果存入cache中。

普通Executor

普通Executor3类,他们都继承于BaseExecutorBatchExecutor专门用于执行批量sql操作,ReuseExecutor会重用statement执行sql操作,SimpleExecutor只是简单执行sql没有什么特别的。
3、Mapper
表面上看mapper是在sqlsession里创建的,但实际创建它的地方是MapperRegistry。
4、StatementHandler
Executor将指挥棒交给StatementHandler后,接下来的工作就是StatementHandler的事了。
创建:
每次创建的StatementHandler都是RoutingStatementHandler,它只是一个分发者,他一个属性delegate用于指定用哪种具体的StatementHandler。可选的StatementHandlerSimpleStatementHandlerPreparedStatementHandlerCallableStatementHandler三种。选用哪种在mapper配置文件的每个statement里指定,默认的是PreparedStatementHandler。同时还要注意到StatementHandler是可以被拦截器拦截的,和Executor一样,被拦截器拦截后的对像是一个代理对象。由于mybatis没有实现数据库的物理分页,众多物理分页的实现都是在这个地方使用拦截器实现的,本文作者也实现了一个分页拦截器。
初始化:
StatementHandler创建后需要执行一些初始操作,比如statement的开启和参数设置、对于PreparedStatement还需要执行参数的设置操作等。
5、结果处理
结果处理使用ResultSetHandler来完成,默认的ResultSetHandler是FastResultSetHandler,它在创建StatementHandler时一起创建,
发布了10 篇原创文章 · 获赞 18 · 访问量 5万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览