Mybatis入门笔记
Mybatis
这个学习资料来源就忘了,好像还是B站老杜?
简介
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
官方中文文档:mybatis – MyBatis 3 | 入门
是一款持久层框架
Mybatis的底层:使用动态代理
Mybatis的本质:使用动反射机制
持久化
持久化就是将程序的数据在持久状态和瞬时状态转化的过程
- 内存:断电即失
- 数据库(jdbc):io文件持久化
为什么需要持久化
- 部分对象不可丢失
- 内存比存储贵
持久层
Dao层、Service层、Controller层
- 完成持久化工作的代码块
- 层界限十分明显
特点
- 方便
- JDBC代码复杂、需要简化、框架、自动化
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件。通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
- 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射。
- 提供对象关系映射标签,支持对象关系组建维护。
- 提供xml标签,支持编写动态sql。
第一个程序
搭建环境 -> 导入Mybatis -> 编写代码 -> 测试
流程:
- 首先创建简单的sql maven项目
- 依赖引入,包括mysql、mybatis、junit
- 创建实体类:Dept:实体类须包含数据库内各个字段且名称能一一对应
- 创建接口dao:DeptMapper 主要用于方法映射,第一个方法为 List
getAllDept(); - 创建工具函数MybatisUtils:主要用于取出sqlSession对象和关闭该对象,其中需要引入mybatis-config.xml文件
- 创建mybatis-config.xml文件,该文件用于数据库连接和数据库配置,其中需要引入DeptMapper.xml文件,用于数据库的增删改查语句执行
- 该文件包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)
- name=”driver”
- name=”url”
- name=”username”
- name=”password”
- 用作连接数据库相关配置
用于映射数据库操作文件
- 创建DeptMapper.xml文件,要引入对应的接口文件作为命名空间:namespace=”org.example.dao.DeptMapper”
- 在DeptMapper.xml书写sql语句,绑定的id为DeptMapper接口对应方法,resultType为返回类型,一般是实体类,parameterType为查询对象
- 在test中编写将sqlsession创建并执行,遇到增删改的相关操作,需要提交事务(commit)
配置解析
核心配置文件
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
环境配置(environment)
1 | <!--todo 环境变量--> |
属性(properties)
1 | <!--todo 读取属性文件(jdbc.properties)--> |
1 | driver=com.mysql.cj.jdbc.Driver |
类型别名(typeAliases)
1 | <!--todo 类型别名--> |
1 | <!--todo 包别名--> |
设置(settings)
其他配置
plugins插件:
- mybatis plus
- 通用mapper
映射器(mappers)
使用相对于类路径的资源引用
1
2
3
4
5
6<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>使用完全限定资源定位符(URL) – 不建议使用
1
2
3
4
5
6<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>使用映射器接口实现类的完全限定类名
1
2
3
4
5<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>将包内的映射器接口实现全部注册为映射器
1
2
3<mappers>
<package name="org.mybatis.builder"/>
</mappers>
注意:在使用方法三和四时,须遵循以下规则,否则报错
- 接口和该mapper配置文件必须同名
- 接口和该mapper配置文件必须处于同一包下
建议:不论采用哪种方式,都遵循上面配置点(规范来着)
生命周期和作用域
mybatis – MyBatis 3 | 入门- 生命周期
Mybatis生命周期和作用域_小小代码熊的博客-CSDN博客_mybatis生命周期和作用域
Mybatis执行流程
Mybatis执行流程_知知之之的博客-CSDN博客_mybatis执行流程
MyBatis 的执行流程_azhou的代码园的博客-CSDN博客_mybatis执行流程
日志工厂
指定 MyBatis 所用日志的具体实现,未指定时将自动查找
类型
- SLF4J
- LOG4J(3.5.9 起废弃)
- LOG4J2
- JDK_LOGGING
- COMMONS_LOGGING
- STDOUT_LOGGING(常用)
- NO_LOGGING
1 | <settings> |
log4j
通过log4j,我们可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码
实践略过,已废弃
分页
mybatis分页
xml:
1 | <!--todo 分页查询--> |
test:
1 |
|
其他相关插件
注解开发
使用注解开发,免去xml配置的麻烦,但
使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。
选择何种方式来配置映射,以及是否应该要统一映射语句定义的形式,完全取决于你和你的团队。 换句话说,永远不要拘泥于一种方式,你可以很轻松地在基于注解和 XML 的语句映射方式间自由移植和切换。
第一步:配置config.xml
1 | <mappers> |
第二步:编写DeptMapper接口的注解查询
1 | // todo 查询全部部门 |
第三步:测试,同之前一样
1 |
|
增
1
2
3//todo 增加部门
int insertOne(int deptno, String name, String loc);删
1
2
3
4//todo 删除部门
// 当只有一个参数时,可以省略不写,但是建议还是写上注解
int deleteOne(int deptno);改
1
2
3//todo 修改部门
int updateOne(int deptno, String name, String loc);param
- 基本类型的参数或者String类型需要加上
- 引用类型不需要加
- 如果只有一个基本类型可以忽略(但不建议)
- 在SQL引用的就是param()中设定的属性名
LomBok
Lombok项目是一个java库,它可以自动插入到编辑器和构建工具中,增强java的性能。不需要再写getter、setter或equals方法,只要有一个注解,你的类就有一个功能齐全的构建器、自动记录变量等等
- idea引入插件
- maven引入依赖
多对一查询
-> Mybatis07
一对多查询
-> Mybatis08
动态SQL
动态SQL是根据不同条件生成不同SQL语句
-> Mybatis09
其他直接看官方文档
trim
1 | <trim prefix="WHERE" prefixOverrides="AND |OR "> |
prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。
缓存
-> Mybatis10
- 什么是缓存[ Cache ]
- 存在内存中的临时数据。
- 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
- 为什么使用缓存?
- 减少和数据库的交互次数,减少系统开销,提高系统效率。
- 什么样的数据能使用缓存?
- 经常查询并且不经常改变的数据。[可以使用缓存]
学习名词:主从复制、读写分离、高并发
Mybatis缓存
MyBatis内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。 为了使它更加强大而且易于配置,我们对 MyBatis 3 中的缓存实现进行了许多改进。
默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:
1 | <cache/> |
一级缓存
测试注意点
- 开启日志
- 在一个session中查询两次
- 查看日志输出
缓存失效情况
- 查询不同东西
- 增删改操作,以为会涉及到数据的改变
- 查询不同的mapper.xml
- 手动清理缓存
一级缓存是默认开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段,一级缓存相当于一个Map
二级缓存
- 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
- 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
- 工作机制
- 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中
- 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中
- 新的会话查询信息,就可以从二级缓存中获取内容
- 不同的mapper查出的数据会放在自己对应的缓存(map) 中
- 对应的实体类要序列化,否则会报错
总结:
- 只要开启了二级缓存,在同一个Mapper下就有效
- 所有的数据都会存放在一级缓存中
- 只有当会话提交或者关闭的时候,才会提交到二级缓存中
缓存原理
还需完善
自定义缓存-ehcache
Ehcache 入门详解 - 王旌羽 - 博客园 (cnblogs.com)
面试题
MyBatis面试题(总结最全面的面试题) - 掘金 (juejin.cn)
- MySQL引擎
- InnoDB底层原理
- 索引
- 索引优化
Mybatis执行流程剖析