要点讲解
需要记住4个对象的作用: 1、StatementHandler :SQL语句的处理器;2、ResultSetHandler: 结果集处理器; 3、ParameterHandler: 参数处理器; 4、Executor: 执行器,用来执行增删改查
0、mybatis最终将参数封装成map进行处理;
1、接口编程:mybatis会为接口创建一个代理对象,代理对象执行增删改查方法。
2、mybatis通过 SqlSession 与数据库连接,其中SqlSession是非线程安全,不能作为全局变量,每次使用必须新创建。
3、mybatis使用多个参数时在方法中使用 @Param("")标签; 比如查询方法:selectText(@Param("id")int id,@Param("name")String name);
4、mybatis支持List、Set类型参数,在配置文件中获取参数为:List 用#{list[0]};Set用#{collection[0]}
缓存
一级缓存:也叫"本地缓存",是sqlSession级别缓存,sqlSession是存储在Map中的,一级缓存是默认开启状态; a、与数据库同一次会话期间查询到的数据会放在本地缓存中,以后查询相同数据会从缓存中获取;b、什么情况下一级缓存会失效?1.使用的sqlSession不同;2.sqlSession相同但查询参数不同;3.sqlSession相同查询参数相同但中间执行增删改方法;4、手动清除缓存,清除缓存方法是openSession.clearCache();
二级缓存:也叫"全局缓存",是NameSpace级别缓存,一个NameSpace对应一个二级缓存也就是一个NameSpace对应一个Map工作机制:a、一次会话查询一条数据,会放在当前会话的一级缓存中。b、会话关闭后一级缓存的数据会保存在二级缓存中。c、不同的NameSpace查出的数据会放在对应的缓存(Map)中,比如:text1查询的对象会放在test1中,test2查询的对象会放在test2中使用二级缓存(默认是关闭状态):a、开启全局二级缓存配置 在mybatis-config.xml 中<stting name="cacheEnabled" value="true"/>b、在testMapper.xml中使用二级缓存 使用<cach>标签c、实体类对象需要实现实例化接口 Serializable;
缓存的原理机制(二级缓存开启时):1 每一个会话都会先查询二级缓存;2 如果二级缓存没有查询一级缓存;3 如果二级和一级缓存都没有数据才查询数据库
整合第三方缓存框架(Ehcache)步骤: 使用maven
查看官网教程地址: https://github.com/mybatis/
点击 See the docs
在pom.xml文件中配置
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.1.0</version>
</dependency>在textMapper.xml中使用第三方缓存框架
<cache type="org.mybatis.caches.ehcache.EhcacheCache" />
创建ehceche.xml文件,设置缓存的参数
源码讲解
运行流程
1 根据全局配置文件(mybatis-config.xml) 创建SqlSessionFactory对象
2 根据SqlSessionFactory对象获取SqlSession对象
3 获取接口的代理对象(MapperProxy)
4 执行代理对象的增删改查方法
每个步骤的具体执行内容
获取SqlSessionFactory对象的步骤
1 创建SqlSessionFactoryBuilder对象,
2 通过build()方法得到XmlConfigBuilder对象
3 XmlConfigBuilder对象创建parser解析器
4 通过parser解析器的evalNode()方法解析全局配置文件(mybatis-config.xml)内容
5 把解析的标签信息保存在Configuration对象中
6 通过XMLMapperBuilder对象解析配置文件(Mapper.xml)
7 将Mapper.xml解析的内容存储到MappedStatement对象
8 将MappedStatement对象保存到Configuration对象中
9 将Configuration对象传递给创建的DefaultSqlSession对象
10 将创建的DefaultSqlSession对象返回给SqlSessionFactoryBuilder对象
备注: 1.所有配置文件解析的内容都保存在Configuration对象中
2.MappedStatement对象代表一个增删改查的详细信息
获取SqlSession对象
1 调用DefaultSqlSession中的openSession()方法
2 openSession方法调用openSessionFromDataSource()方法拿到dafaultExecutorType类型
3 从Configuration对象中获取全局配置信息、创建事务并调用newExecutor()方法创Executor对象;备注:Executor对象是一个接口,: 叫做执行器,用来执行增删改查
4 根据Executor的全局配置类型创建SimpleExecutor(简单执行器):简单执行sql语句;ReuseExecutor(重复执行器): 重复使用执行,定义了一个Map,将执行的sql作为key,将执行的Statement作为value保存BatchExecutor(批量执行器):通过批量操作提高性能;
5 判断二级缓存是否开启,如果开启就创建CachingExecutor(executor)
6 使用interceptorChain(拦截器链) 的plugimAll()方法重新包装executor对象并返回
7 把封装好的Executor对象和Configuration对象传给DefaultSqlSession对象并返回
获取接口的代理对象(MapperProxy)
1 调用SqlSession对象中的getMapper()方法
2 调用Configuration对象的getMapper()方法
3 调用MapperRegistry(mapper注册)对象的getMapper()方法
4 根据接口类型获取MapperProxyFactory(mapper代理工厂)
5 调用MapperProxyFactory对象的newInstance(sqlSession)方法
6 创建MapperProxy对象,该对象实现了InvocationHandler(动态代理)接口
7 调用java中的Proxy(代理)的newProxyInstance()方法创建MapperProxy对象
8 把创建好的MapperProxy对象返回
执行代理对象的增删改查方法(以查询流程为例)
1 根据代理对象创建 DefaultSqlSession对象
2 根据SqlSession对象的Executor对象执行增删改查
3 Executor对象执行查询方法时会创建StatementHandler对象;备注: StatementHandler(SQL语句处理器):处理SQL语句预编译和设置参数等
4 在StatementHandler对象创建ParameterHandler对象和ResultSetHandler对象;备注:1)ParameterHandler(参数处理器):设置预编译参数, 通过DefaultParameterHandler中的TypeHandler对象的setParameter()方法设置参数;2)ResultSetHandler: 处理结果集通过DefaultResultSetHandler中的TypeHandler对象的getResult()方法处理结果集
5 调用TypeHandler对象设置参数和处理结果集并对数据库的类型和javaBean类型映射
6 最终调用原生JDBC