Mybatis特性
1、使用连接池对连接进行管理
2、SQL与代码分离,集中管理
3、参数映射和动态SQL
4、结果集映射
5、缓存管理
6、重复SQL的提取
7、插件机制
MyBatia映射过程
SqlSessionFactoryBuilder ------>创建工厂类(生产完工厂对象就销毁) 生命周期:方法级别的
SqlSessionFactory ------>创建会话(单例对象,全局的生命周期,服务停止才销毁) 生命周期:全局
SqlSession ------>会话(每次请求/会话之前创建,请求/会话完成就销毁) 生命周期:方法级别
Mapper ------>映射(与SqlSession的生命周期类似) 生命周期:方法级别
MyBatis两种配置文件
1.全局配置文件 mybatis-config.xml 启动时候解析成Configuration类
2.映射器文件 mapper.xml
MyBatis执行过程
SqlSessionFactoryBuilder解析配置文件----->Configurarion----->SqlSessionFactory------>SqlSession------>Executor ------>StatementHandler(操作入参,并返回结果)------>关系型数据库 解析配置文件–>创建工厂类—>创建会话—>执行
MyBatis三层
接口层:SqlSession(接收用户指令)
核心层:配置解析----参数处理----SQL执行----结果映射、插件
基础层:日志、缓存、数据源/连接池、事务、反射
MyBatis缓存
一级缓存
作用域:SqlSession级别,同一个会话中缓存才能被共享。也就是说同一个会话中如果二次查询,会从缓存中获取数据。
flushCache:true/false 增删改默认的flushCache是true,也就是执行后会清空缓存。
select默认的flushCache是false,也就是执行后不会清空缓存 ,可以在mapper.xml对应的执行语句添加flushCache属性。
一级缓存缺点:跨会话会造成脏读。
注:一级缓存是默认打开的。
二级缓存
CacheExecutor(鸡肋,用第三方缓存代替二级缓存)。
作用域:namespace级别。
二级缓存工作在一级缓存之前(二级缓存范围广)
二级缓存默认打开的。
开启缓存:在mapper.xml中添加cache标签
useCache:true/false 默认true。设置为false关闭二级缓存。
inert/delete/update会清空某个namespace中的二级缓存
使用场景:单对象操作,并且其他mapper.xml中没有对该对象的操作,namespace中只有select,没有insert/delete/update。
配置案例
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 属性 -->
<properties resource="db.properties">
<property name="driver" value="${driverClassName}"/>
<property name="url" value="${jdbcUrl}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</properties>
<!-- 核心配置 -->
<settings>
<!-- 全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存 -->
<setting name="cacheEnabled" value="true"/>
<!-- 延迟加载的全局开关 -->
<setting name="lazyLoadingEnabled" value="false"/>
<!-- 允许 JDBC 支持自动生成主键 -->
<setting name="useGeneratedKeys" value="false"/>
<!-- 配置默认的执行器 SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句; BATCH 执行器将重用语句并执行批量更新 -->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 驱动等待数据库响应的秒数 -->
<setting name="defaultStatementTimeout" value="100"/>
<!-- 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据 -->
<setting name="localCacheScope" value="SESSION"/>
<!-- 指定哪个对象的方法触发一次延迟加载 -->
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
<!-- 指定 Enum 使用的默认 TypeHandler -->
<!--<setting name="defaultEnumTypeHandler" value="org.apache.ibatis.type.EnumTypeHandler"/>-->
<!-- 指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具 -->
<setting name="proxyFactory" value="JAVASSIST"/>
<!-- 指定 MyBatis 所用日志的具体实现,未指定时将自动查找 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- 类型别名 -->
<typeAliases>
<typeAlias type="com.ns.vo.User" alias="User"/>
</typeAliases>
<!-- 自定义类型处理器,要求:实现org.apache.ibatis.type.TypeHandler接口或者继承org.apache.ibatis.type.BaseTypeHandler -->
<typeHandlers>
<typeHandler handler="com.ns.handler.StringTypeHandler"/>
</typeHandlers>
<!-- 对象工厂 -->
<!--<objectFactory type="com.ns.factory.UserObjectFactory">-->
<!--<property name="userProperty" value="100"/>-->
<!--</objectFactory>-->
<!-- 环境配置 -->
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driverClassName}"/>
<property name="url" value="${jdbcUrl}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 映射器 -->
<mappers>
<mapper resource="com/ns/mapper/UserMapper.xml"/>
</mappers>
</configuration>