我们容易忽视慢变量,但慢变量才是牵引历史进程的火车头。 - 何帆/变量
- Mybatis 持久层:简化工作量、灵活
- Spring 粘合剂:整合框架 AOP IOC DI
- SpringMvc 表现层:方便前后端数据的传输
Mybatis:
- 1.是对jdbc的封装,
- 2.将sql语句放在映射文件中(xml),
- 3.自动将输入参数映射到sql语句的动态参数上,
- 4.自动将sql语句执行的结果映射成java对象
入门示例:
1.创建项目mubatis-01
2.导入jar:
- mybatis-3.2.8
- mysql-connect
- log4j-1.2.17
3.加入配置文件
(1)db.properties
|
|
(2)log4j.properties
https://blog.csdn.net/sinat_30185177/article/details/73550377
|
|
(3) mybatis核心配置文件:mybatis-config.xml
(4) BlogMapper.xml
包:com.jingbin.mybatis.mapper
4.编写接口:BlogMapper
5.创建pojo:Blog
6.创建工具类:MyBatisUtil
7.编写测试类:
|
|
8.列名和属性名不一致的情况
数据库里的列名为author_id,属性名为authorId。在BlogMapper.xml里:
1.使用别名
select author_id as authorId from Blog where id=#{id}
2.使用 resultMap
|
|
9.模糊查询之#
和$
的区别
模糊查询:根据博客名字查询博客列表
1)使用#
传参
2)使用$
传参
#
是占位符?,$
是字符串拼接。
mybatis定义:
- 使用
$
。如果参数是单指类型(简单类型),并且只有一个参数,则花括号里只能写value占位。 - 使用
$
可以直接将%
写里面,可能有sql注入的风险,建议最好使用#
。参数是字符串要使用 ‘’ - 当参数表示表名或列名的时候,只能使用
$
|
|
10.查询排序
需求:按照某一列排序
select * from blog order by CONVERT(${value} USING gbk)
gbk:输入中文时排序成功,否则会失败。且使用gbk规避魅族(gb2313)不排序问题。
11.分页-多参数传递
需求:查询分页数据
- 1)使用索引
按照参数的顺序,从0开始
select * from blog limit #{0}, #{1}
- 2)使用注解
注解的value值要和mapper的占位参数一致。
|
|
- 3)使用map(常用)
注意:mapper中的参数占位符要和测试中的map的key一一对应
|
|
12.插入功能和获取刚刚插入的id
- 1)插入记录
需求:新增一个博客记录
|
|
- 2)获取自增id
方式1:在mapper中配置insert
节点的属性useGeneratedKeys
和keyProperty
节点1<insert id="insertBlog" parameterType="Blog" useGeneratedKeys="true" keyProperty="id"/>
方式2:在全局配置文件中配置setting
方式3:适用于没有自增主键的数据库
|
|
13.修改功能和修改部分字段注意的问题
|
|
注意:如果没有为对象设置所有的要修改的属性,那么未设置的属性会用成员变量的默认值填充。
解决:
方式1:数据库查一遍,再返回的数据修改。缺点:又执行了一遍数据库操作
方式2:查询语句里增加if else。
14.删除记录
|
|
动态sql
批量删除:使用动态sql实现
if、[choose、when、otherwise]、where、set、trim、foreach、sql片段
15.if
需求:
- 1.查询已激活的并且博客的名字是包含某个查询字符串的记录
- 2.如果用户没有输入任何查询字符串,那么就显示所有已激活的记录
// 如果用户输入了查询字符串
select * from blog
where state = ‘ACTIVE’
and title like ‘%o%’
// 用户没有输入查询字符串
select * from blog
where state = ‘ACTIVE’
|
|
16.choose、when、otherwise
需求:
- 1、查询已激活的
- 2、如果用户输入了标题的查询关键字,则根据关键字查询
- 3、否则根据blog风格样式查询
- 4、如果什么都没有输入,则显示推荐的博客
|
|
17.where
需求:多条件查询,根据状态,标题,是否被推荐
自动修补查询条件,查询语句中的where关键字使用
|
|
18.set
需求:按需修改,修改执行的列,未指定的不修改
set 会自动去掉if语句后面的逗号
|
|
19.trim
|
|
20.foreach
需求:批量删除
|
|
21.sql片段
|
|
22 23.逆向功工程-代码的生成
使用 Mybatis 官方工具直接生成对应的mapper文件
全部生成 - 无实际意义,具体项目中不适用
24.缓存 - mybatis的一级缓存
一级缓存:
是session级别的缓存,一级缓存默认存在。
当在同一个session范围内执行查询的时候,如果执行相同的查询,那么第二次查询会从缓存中获取数据。
|
|
25.缓存 - 一级缓存被刷新的情况
如果两次查询中间有增删改操作,sql session缓存区会被自动清空,说明下一次查询会重新执行sql语句。
|
|
26.缓存 - 开启二级缓存
默认不开启。如果在不同的session范围内执行相同的数据查询,那么每次查询将会执行独立的数据库检索过程。
|
|
开启二级缓存
1.在mapper文件中设置
2.在实体类中实现序列化接口
|
|
27.缓存 - 二级缓存被刷新的情况
和一级缓存相同,中间有增删改则二级缓存会被清空
|
|
28.嵌套查询 - 一对一和多对一
高级结果映射
一、关联映射(适用于一对一和多对一的情况)
1).创建pojo
(1)在Blog中创建Author对象
|
|
(2)创建Author的pojo
2).配置mapper
BlogMapper.java
|
|
AuthorMapper.java
|
|
3) 接口
(1) Blog
|
|
(2) Author
|
|
4) 测试
查询Blog列表时,执行的sql语句是 1+n,但是如果blog关联的author有重复的数据,那么从一级缓存中查询。
|
|
29.嵌套查询 - 显示信息列表
|
|
30.嵌套查询-一对多的配置 31.嵌套查询-一对多的查询配置
执行流程:1.先执行单表查询,2.再利用单表查询的结果继续执行其他单表查询,3.最后组装结果映射。
通过post的id 查询post表的内容,同时通过此id查询评论表 comment 里的数据列表,即这篇文章的评论列表
sql:
|
|
PostMapper.xml
|
|
CommentMapper.xml
|
|
测试:
|
|
32.高级结果映射-嵌套结果
1).先执行关联查询,一次性将所有数据都查询出来
2).再将所有查询出来的列组织成嵌套的结果对象
|
|
|
|
BlogMapper.xml
|
|
33.为什么要做扩展结果集|34.扩展结果的实现
1).mapper
BlogCustomMapper.xml
|
|
BlogCustomMapper.java
|
|
2)vo.BlogCustom.java
|
|
3)测试
|
|
35.高级结果映射 - 构造方式映射
|
|
36.鉴别器
|
|
|
|
pojo
|
|
测试:
|
|
37.延迟加载 - 不配置延迟加载的情况
测试一:
没有配置任何选项,执行两遍查询,性能比较低
无论是否查询blog的任意属性,都会执行author的任何查询,就是说 始终会执行两次查询。
|
|
38.延迟加载 - 配置lazyloadingenabled
测试二:
如果不查询blog的任意属性,那么不会执行author的查询
配置了全局属性:
|
|
测试:
|
|
日志打印:
|
|
39.延迟加载 - 测试用例1和2的比较
40.延迟加载 - 积极的延迟加载
延迟加载:用属性就加载,不用就不加载。
积极的延迟加载:只要用属性,就把所有要查询的属性sql全部执行一遍。
测试三:
只要查询bolg的任意属性,都会执行author数据的查询
配置了全局属性(同测试2的配置):
|
|
测试:
|
|
41.延迟加载 - 非积极延迟加载
测试四:
延迟加载,并且是非积极的。如果需要访问blog的非author属性,则不执行关联的author查询。
配置了全局属性:
配置后,没有调用 blog.getAuthor() 属性,就只会执行一次,调用 blog.getAuthor() 属性才回再执行查询author表一次。
|
|
测试:
|
|
打印:
|
|
测试五:
配置了全局属性 同配置四
延迟加载,并且是不积极的。如果访问了blog的author属性,则执行关联的author查询
测试:
|
|
打印:
|
|