Mybatis学习总结
来源:互联网 发布:超时空拦截知乎 编辑:程序博客网 时间:2024/06/09 20:30
一、Mybatis介绍
Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。Mybatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。Mybatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的 Java对象)映射成为数据库中的记录。
Mybatis中的核心概念:
1)SqlSession:代表和数据库的一次会话,向用户提供了操作数据库的方法;
2)MappedStatement:代表要发往数据库执行的指令,可以理解为是Sql的抽象表示;
3)Executor:具体用来和数据库交互的执行器,接受MappedStatement作为参数;
4)映射接口:在接口中会将要执行的sql语句用一个方法来表示,具体的sql写在映射文件中;
5)映射文件:可以理解为是Mybatis编写sql的地方,通常来说每一张单表都会对应着一个映射文件,在该文件中会定义sql语句入参和出参的形式。
二、Mybatis数据持久化(以查询为例)
1.准备开发环境
①创建测试项目,如下图所示:
②添加相应的jar包,如下图所示:
③在MySQL数据库中创建数据库和表
create database mybatis;
use mybatis;
create table users(id int primary key,name varchar(10),age int);
insert into users(id,name,age) values(1,'lv',20);
insert into users(id,name,age) values(2,'ting',21);
2.使用mybatis查询表中的数据
①在com.example.xml包下创建一个NewFile.xml
NewFile.xml文件中内容如下:
②在com.example.domain包下创建一个User实体类
User类代码如下:
③在com.example.mapping包下定义users表的sql映射文件userMapper.xml
userMapper.xml文件中内容如下:
④在NewFile.xml文件中注册userMapper.xml文件
如下图所示:
⑤在com.example.test包下创建测试代码test.java,执行select语句
如下图所示:
整个项目文件结构如下图所示:
三、mybatis缓存
一级缓存
在系统代码的运行中,我们可能会在一个数据库会话中,执行多次查询条件完全相同的sql,鉴于日常应用的大部分场景都是读多写少,这重复的查询会带来一定的网络开销,同时select查询的量比较大的话,对数据库的性能还是有比较大的影响。
如果是MySQL数据库的话,在服务端和jdbc端都开启预编译的话,可以在本地jvm端缓存statement,可以在MySQL服务端直接执行sql,省去编译sql的步骤,但也无法避免和数据库之间的重复交互。
Mybatis提供了一级缓存的方案来优化在数据库会话间重复查询的问题。实现方式是每一个SqlSession中都持有了自己的缓存,一种是session级别,即在一个Mybatis会话中执行的所有语句,都会共享这一个缓存。一种是statement级别,可以理解为缓存只对当前执行的这一个statement有效。如下图所示:
每一个SqlSession中持有了自己的Executor,每一个Executor中有一个local cache。当用户发起查询时,Mybatis会根据当前执行的MappedStatement生成一个key,去local cache中查询,如果缓存命中的话,返回。反之,则写入local cache中再将结果返回给用户。
一级缓存配置:
在MyBatis的配置文件中,添加语句(<setting name="localCacheScope" value="SESSION"/>),就可以使用一级缓存。共有两个选项,SESSION和STATEMENT,默认是SESSION。
一级缓存工作流程:
①对于某个select statement,根据该statement生成key;
②判断在local Cache中,该key是否有对应的数据存在;
③如果命中,则跳过查询数据库;
④如果没命中,则去数据库中查看数据,得到查询结果,将key和查询到的结果放入到local cache中,并将查询结果返回;
⑤判断缓存级别是否为statement级别,如果是,清空缓存。
总结:
①Mybatis一级缓存的生命周期和SqlSession一致;
②Mybatis的缓存也是一个粗粒度的缓存,没有更新缓存和缓存过期的概念,同时只是使用了默认的hashmap,也没有做容量上的限定。
③Mybatis的一级缓存最大范围时SqlSession内部,有多个SqlSession或者分布式的环境下,有操作数据库写的话,会引起脏数据,建议不要去使用一级缓存。
注:一级缓存只是在数据库会话内部共享。例如:有两个会话SqlSession1和SqlSession2,在SqlSession1中更改了某一信息,而SqlSession2查询依旧是原先数据信息,因此这里出现脏数据,也证明了一级缓存只是在数据库会话内部共享这一结论。
二级缓存
在一级缓存中,其最大的共享范围是一个SqlSession内部,那么如何让多个SqlSession之间也能够共享缓存呢,答案是二级缓存。当开启二级缓存后,会使用CachingExecutor装饰Executor,在进入后续执行前,现在CachingExecutor进行二级缓存查询,具体工作流程如下:
在二级缓存的使用中,一个namespace下的所有操作语句,都影响着同一个cache,即二级缓存是被多个SqlSession共享着的,是一个全局的变量。当开启缓存后,数据的查询执行的流程就是二级缓存—>一级缓存—>数据库。
二级缓存配置:
①在Mybatis的配置文件中开启二级缓存
<setting name="cacheEnabled" value="true"/>
②在Mybatis的映射XML中配置cache
<cache/>
cache标签用于声明这个namespace使用的是二级缓存,并且可以自定义配置。
<cache-ref namespace="mapper.UserMapper"/>
cache-ref代表引用别的命名空间的cache配置,两个命名空间的操作使用的是同一个cache.
总结:
①Mybatis的二级缓存相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加的细,能够到Mapper级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。
②Mybatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用的条件比较苛刻。
③在分布式环境下,由于默认的Mybatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将Mybatis的Cache接口实现,有一定的开发成本,所以可以用radis或者memcache实现业务上的缓存。
注:Mybatis的二级缓存并不适用于映射文件存在多表查询的情况。一般来说,我们会为每一个单表创建一个单独的映射文件,如果存在涉及多个表的查询的话,由于Mybatis的二级缓存是基于namespace的,多表查询语句所在的namespace无法感应到其他namespace中的语句对表查询中涉及的表进行了修改,引发脏数据问题。
- Mybatis学习总结
- mybatis学习总结
- Mybatis学习总结
- mybatis学习总结
- Mybatis学习总结
- MyBatis学习总结一
- MyBatis学习总结(二)
- MyBatis的学习总结
- MyBatis学习总结
- MyBatis学习总结
- Mybatis学习与总结
- Mybatis学习总结
- Mybatis学习总结一
- Mybatis学习总结二
- Mybatis学习总结
- MyBatis学习总结
- Mybatis学习总结
- Mybatis学习总结二
- Java并发编程实战(二)基础构建模块
- Poj 2559 最大矩形面积
- python--threading多线程总结
- PAT乙级(Basic Level)真题-1016. 部分A+B (15)
- Linux命令记录
- Mybatis学习总结
- iOS- 来和我一起捣鼓微信支付吧
- 只能在堆或栈上创建对象
- 原码、反码、补码详解
- Java反射,几问?
- jqery将日期数字转换成日期格式
- Elasticsearch5.0 安装问题集锦
- oracle数据库新增字段报错
- 斐波那契数列