关于Mybatis

Mybatis是一个半ORM(对象关系映射)的框架,内部封装了JDBC,使用时可只注意便携SQL语句,不需要手动创建链接等操作。但是SQL语句编写工作量大,且不能随意更改数据库。

关于Mybatis的执行流程

首先在maven中我们导入了mybatis-spring-boot的起步依赖,然后在application.properties/application.yml中配置了mybatis的相关配置,包括mybatis的配置文件路径、数据库连接信息等。创建完依赖后我们会构建会话工厂SqlSessionFactory,然后我们就可以通过SqlSessionFactory来创建会话对象,然后我们操作数据库接口,Executor执行器,同时负责查询缓存的维护。Executor接口中有MappedStatement类型的参数,封装了映射信息。最后我们输入参数映射并等待输出结果映射。(说实话没听懂)

关于Mybatis传递多个参数

1.参数可以像数组一样用下标传递,如#{0}则代表传递第0个参数
2.可以使用@Param注释来指定参数,在方法中例如public void addUser(@Param(“name”) String name, @Param(“age”) int age)来对参数进行标注,当需要的时候直接在SQL语句中注入,例如 select * from user where name = #{name} and age = #{age}
3.使用Map传递参数
4.可以直接使用bean对象作为参数,例如User user,然后在SQL语句中直接使用#{user.name}来引用属性值

#{}和${}的区别

在使用#{}时,Mybatis会在SQL执行前将占位符替换为 ? ,并使用参数值来代替 ? 。
在使用${}时,参数的值会直接替换到SQL语句中,不会进行任何处理。例如参数是1 or 1=1

1
2
3
4
SELECT * FROM user WHERE id = ${id}
例如输入的参数是**1 or 1=1**,则SQL会变成
SELECT * FROM user WHERE id = 1 or 1=1
会导致查询所有用户的结果

所以我们一般推荐使用#{}

关于Mybatis的延迟加载

延迟加载就是在需要用到该数据时才会进行加载,不用就不加载,可以提高性能。但是延迟加载在mybatis中是默认关闭的。
Mabatis的延迟加载主要是使用了CGLIB创建目标对象的代理对象,调用目标方法时首先会进入拦截器invoke方法。如果拦截器发现目标方法get到的值为null,就证明这个数据还没被加载,这时才会执行sql语句。获取数据后再把代理对象中的值set进目标对象中。

关于Mybatis的二级缓存

一级缓存是基于PerpetualCache的HashMap的本地缓存,作用域为session,session flush或者close后就会把cache清空,mybatis默认开启一级缓存。
二级缓存也是基于PerpetualCache的HashMap的本地缓存,但是二级缓存不依赖session,也就是说,同一个SqlSession的查询,即使不关闭,二级缓存也会存在。mybatis默认不开启二级缓存。
在一级或二级缓存进行增删改操作后,默认将该作用域的缓存清空。

关于Mybatis的批量加载

1.使用foreach标签
使用foreach标签进行遍历,将collection的属性值改成目标参数的属性值,然后在SQL语句中使用#{item}来引用属性值。

1
2
3
4
5
6
<select id="selectUsers" resultType="User">
SELECT * FROM user WHERE id IN
<foreach collection="ids" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>

2.使用batch批处理方法
不太熟悉。

关于Mybatis实现分页

1.我们可以运用分页拦截器,拦截待执行的SQL,然后在SQL语句中添加分页的相关参数,然后再执行SQL。

1
2
3
4
拦截前
select * from student
拦截后
select * from student limit #{page},#{size}

2.我们也可以使用PageHelper实现分页。我们引入PageHelper依赖,然后在配置文件中配置PageHelper的相关参数。然后我们就可以在方法中直接调用PageHelper的startPage(page,size)来实现分页。