Mybatis的核心在于三部分:jdbc传入参数和结果与java类型之间的转换,动态SQL的生成,数据库连接和事务的管理

Mybatis的配置和hibernate类似,包括两种:基于注解和基于xml文件,前者可以做到无配置,但是缺点是不够灵活,xml文件的方式更加灵活,可以满足所有情况,因此还是将主要精力放在xml的方式上。

1、Mybatis的主要流程和核心概念之间的关系

(1)SqlSessionFactoryBuilder读取配置信息生成SqlSessionFacotry,配置信息主要是通过读取配置文件mybatis-config.xml得到的,也可以通过其他方式。

(2)通过SqlSessionFacotory可以获得SqlSession

(3)SqlSession可以调用具体的sql语句进行执行,sql语句则通过读取mapper xml文件得到

(4)最核心的地方就是sql语句的动态生成,以及参数的传入和查询结果的转化,这些都是Mybatis通过配置可以处理的,使用Mybatis主要在这三部分的编写

2、Mybatis的配置文件mybatis-config.xml

通过xml配置文件的形式配置一些Mybatis的全局信息,例如数据源、typehandler之类的,可以再构造时指定文件路径,不过mybatis-config.xml是默认的名字,可配置的主要信息如下:

(1)properties,配置一些属性值,全局都可以使用

(2)settings,配置Mybatis运行时一些关键属性的设置,包括设置缓存、懒加载、使用生成主键之类的,可以看文档了解

(3)typeAliases,定义一些全局的别名

(4)typeHandlers,配置一些全局的类型处理器,Mybatis在数据库类型和java类型进行值转化时所使用,主要是java类型参数传入转化为数据库类型,查询结果从数据库类型转化为java类型。Mybatis自带一些默认的typeHandler,处理常见的类型,例如字符串、布尔值、日期等等。该配置文件中用户自定义一些全局的typeHandler,Mybatis会在类型转化时自动寻找,typeHandler也可以在mapper xml文件中配置,不过只是针对具体字段起作用。typeHandler核心在于指定javaType,jdbcType和具体的处理器

(5)plugins,Mybatis允许用插件的方式对sql语句的生成和执行进行拦截,做一些处理。其中ResultSetHandler,StatementHandler是在meet-mybatis中用来处理分页,对生成的sql语句进行处理

(6)environments,和mavne中的profiles类似,都是定义一些environment,以ID区分,然后默认激活一种环境,environment中可以配置数据源datasource和事务管理器transactionManager

(7)mappers:定义需要加载的mapper xml文件,只有定义了该标签SqlSession才能更具id找到对应的sql语句执行。在mybatis-spring使用方式中,可以直接以属性方式配置给SqlSessionFactory

3、最核心文件Mapper XML

Mapper XML定义了具体执行的sql语句,缓存,定义传入参数和查询结果的转化方式

(1)select标签,定义查询语句,关键的属性包括:

参数 说明
parameterType 定义传入参数的类型
resultType 定义返回结果的类型
resultMap 定义处理结果转换的resultMap
flushCache 设置为true,语句被调用时缓存被清空,默认false
useCache 设置为true,将把本语句的返回结果缓存,默认true
timeout 设置驱动程序等待数据库返回请求结果并抛出异常时间的最大等待值,默认不设置
fetchSize 设置驱动程序每次批量返回的结果行数,默认不设置
resultSetType

FORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE的一种,默认不设置。

sqlSession的select方法中指定RowRounds进行分页查询时,不要设置为FORWARD_ONLY,否则一条条遍历直到偏移位置才读取

(2)insert标签定义增加操作,核心在于参数的传入。除了和select一些公共属性外,关键属性还包括

参数 说明
useGeneratedKeys 数据库支持自动生成主键,则可以设置为true,那么生成的主键就会设置到目标属性上
keyProperty 设置生成主键映射到的目标属性

(3)delete和update标签定义删改操作,核心在于参数的传入,除了公共属性,没有额外属性

(4)sql可以定义重用的sql代码段,供其他标签通过<include refid="XXX"/>导入

(5)参数的传入,主要采用parameterType定义,不仅可以指定基本类型,还可以指定自定义类型。主要格式就是#{参数,javaType,jdbcType,typeHandler},也可以定义numericScale主要是数值型进行转化时保留精确度,#{}会自动装入对应属性的值拼成sql,特殊需求下${}可以直接传入字符串而不会发生值替换,这种情况容易导致sql注入攻击,因此不提倡。

(6)最最核心的就是resultMap标签,查询是数据库最主要的功能,通常情况下,可以通过resultType指定返回结果类型,Mybatis会更具字段名称和类型,调用对应的typeHandler进行转换,但是对于复杂的查询结果,特别是多表关联查询时,比较复杂。在resultMap中id和result将具体字段和属性的值进行对应,它们可以自由的定义列的类型、属性的类型及处理器。其中比较有用的几个标签如下

标签 说明
constructor 构造函数的传入属性
association 属性关联的是复杂类型,相当于嵌套resultMap
collection 属性关联的是集合
discriminator 根据值,返回结果对应的java类型,相当于switch的错误,转给其他resultMap处理

(7)cache标签,定义缓存。Mybatis的缓存分为两种:session局部缓存,是在sqlSession生命周期中的缓存又称为本地缓存,cache相当于二级缓存,作用在当前Mapper XML范围内,默认不开启,开启只需添加<cache/>即可,

当前xml文件中所有select语句都将缓存,insert,update和delete语句都会刷新缓存,默认使用LRU算法,可以通过eviction来定义,刷新时间可通过flushInterval定义,size定义缓存的结果集的数量,readOnly定义

4、动态SQL

Mybatis相比jdbc的一大优势就是sql语句可以通过标签,判断条件动态生成sql语句,不用java代码中手动拼接。核心的四个标签名称:if,choose(when,otherwise),trim(where,set),foreach

5、Java API,连接的生成和事务的管理

(1)SqlSessionFactory提供openSession来提供SqlSession,openSession可以设置事务级别,执行方式,连接来源来生成连接。默认会开启事务,不自动提交,连接对象从配置的datasource获取,事务隔离级别采用驱动或数据源的设置,预处理语句不被复用,也不会批量处理。预处理语句应该是preparedstatement预编译语句,可能是同一个连接中语句相当预处理过的不会被复用。批量则是不支持在一个sqlsession中进行批量增删改,如果要用一个sqlsession进行批量更新,还是设置ExecutorType,效率会提高

(2)特别要注意,sqlSession提供的select语句,分页时,设置RowBounds,select的sql语句对应resultSetType一定不能是FORWARD_ONLY,否则一条条遍历直到偏移量,在取指定的记录数

(3)事务管理方面,Mybatis-Spring插件将Mybatis的事务管理交给Spring去做,如果外部框架不提供事务管理,那么sqlSession也提供commit和rollback来控制事务

(4)clearCache清理session级别的缓存,update,commit,rollback和close会自动调用

(5)除非上层管理,sqlSession在使用后一定要close来释放资源