目录
一. 动态sql
1. if元素
if标签:对test属性中的元素进行判断,满足条件执行,不满足不执行
<select id="findStudents" resultType="Student" parameterType="Student">
select * from student where 1=1 <!--或者有一个默认条件-->
<if test="name!=null">
and name = #{name}
</if>
<if test="num!=0">
and num = #{num}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
</select>
2. where元素
where标签:如果if标签中有一个满足条件,就会在sql中自动拼接一个where关键字,并且将where后面的多余关键字去掉
<select id="findStudents" resultType="Student" parameterType="Student">
select * from student
<where>
<if test="name!=null">
and name = #{name}
</if>
<if test="num!=0">
and num = #{num}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
</where>
</select>
3. trim元素
trim标签:让我们添加一个指定的关键字,还可以去除指定的关键字
<select id="findStudents" resultType="Student" parameterType="Student">
select * from student
<trim prefix="where" prefixOverrides="and|or">
<if test="name!=null">
or name = #{name}
</if>
<if test="num!=0">
and num = #{num}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
</trim>
</select>
案列中如果有if满足条件,会自动添加where并且会去除where后面的and和or
4. choose,when,otherwise元素
when和otherwise就相当于if,else if, else的用法但when标签和otherwise标签必须放在choose标签中使用
<select id="findStudents" resultType="Student" parameterType="Student">
select * from student
<where>
<choose>
<when test="name!=null">
name = #{name}
</when>
<when test="num!=null">
and num = #{num}
</when>
<otherwise>
and name = '赵六'
</otherwise>
</choose>
</where>
</select>
5. set元素
set标签,当if中有一个满足条件时会在update后面加一个set,并去除最后一个逗号
<update id="updateStudents" parameterType="int">
update student
<set>
<if test="name!=null">
name = #{name},
</if>-->
<if test="num!=null">
num = #{num},
</if>
<if test="gender!=null">
gender = #{gender},
</if>
</set>
where id = #{id}
</update>
6. foreach元素
foreach标签:用于循环构建sql语句,里面有很多属性,如下
item:集合中每个元素在迭代时的别名
index:每次迭代时的索引
collection:这个值是必须要指定的,如果传入的是一个集合用list,如果传入的是一个数组,用array
open:表示在循环开始时拼接一个符号
close:表示在循环结束时拼接一个符号
separator:在每次迭代之间以什么作为分隔符
<!--
批量删除
-->
<delete id="deleteStudent">
delete from student where id in
<foreach item="a" collection="list" open="(" close=")" separator=",">
#{a}
</foreach>
</delete>
<!--
按需查询
-->
<select id="findStudentByColumn" resultType="Student">
select
<foreach item="c" collection="list" separator=",">
${c}
</foreach>
from student
</select>
二. 特殊符号处理
我们有时候在用sql进行查询时,难免会用到一些比较运算符等,作为条件进行条件查询,但是在xml文件中往往不能识别这些符号会报错,需要通过一些方法来转义
1. 转义字符
通过转义来达到条件查询的目的
<select id="findStudents1" resultType="Student" parameterType="integer">
select * from student where num < #{num}
</select>
这样查询num小于一定条件的数据了
2. <![CDATA[ 特殊符号 ]]>标签
只需要将需要用到的符号写在这个标签中即可
<select id="findStudents1" resultType="Student" parameterType="integer">
select * from student where num <![CDATA[ < ]]> #{num}
</select>
三. 模糊查询
在mybatis中要想进行模糊查询,不能直接用#{name}%的方式,因为mybatis会用预编译的方式将#{name}当做?后面的%多余了就会报错,也就是说这两个不是一个整体
1. 使用$拼接字符串
<select id="finStudents2" resultType="Student" parameterType="string">
select * from student where name like '${name}%' 字符串拼接
</select>
但这种方式不建议用,因为${name}是进行字符串的拼接,会有安全问题,sql注入
2. concat(str 1,str2,...)函数拼接
利用数据库中的concat(str 1,str2,...)函数进行字符串的拼接
<select id="finStudents2" resultType="Student" parameterType="string">
select * from student where name like concat(#{name},'%')
</select>
3. 直接在传参时拼接字符串
import com.ffyc.mybatis.dao.StudentDao;
import com.ffyc.mybatis.model.Student;
import com.ffyc.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.ArrayList;
import java.util.List;
public class Test5 {
public static void main(String[] args) {
//直接在传参时拼接字符串
System.out.println(studentDao.finStudents2("张%"));
}
}
<select id="finStudents2" resultType="Student" parameterType="string">
select * from student where name like #{name}
</select>
4. 在#{name}前后任意加"%"
<select id="finStudents2" resultType="Student" parameterType="string">
select * from student where name like #{name}"%"
</select>
四. mybatis中提供的缓存机制
1. 为什么需要缓存
随着当代互联网的发展,有大量的电商平台有各种促销秒杀活动或者会存在某一时刻数据访问量过大的问题,而我们知道数据库也是一个服务器,它能承载的用户连接是有限的,并且数据库是将数据存储在硬盘上,而硬盘的读写是没有内存快的,所以当用户请求量过大时,会给数据库带来很大的压力,为了减缓这种压力,我们就要提到缓存的概念
缓存:在与数据库第一次建立连接时,可以将一些不经常改变,或者与数据库交互频繁的信息临时存到内存中,下次在查询相同信息时,直接从内存中读取,这样就会减少与数据库的连接,从而缓解数据库的压力
mybatis为我们提供了一级缓存和二级缓存,可以使我们减少与数据库的交互
2. mybatis中的一级缓存
mybatis中的一级缓存是相对于同一个sqlSession对象而言的,也就是说我们如果在不关闭sqlSession对象或者不对缓存中的数据进行操作的前提下,向数据库请求两次相同的数据,那么只会和数据库进行一次交互,在第一次交互时就会将数据保存到一级缓存的sqlSession对象中,第二次直接从sqlSession对象中取,但是mybatis中的一级缓存很少使用,因为我们基本不会用同一个sqlSession对象进行两次相同的查询
public class Test6 {
public static void main(String[] args) {
/*
mybatis也是提供了缓存功能
一级缓存:是sqlSession级别的,在同一个SqlSession中相同的两次查询,只查询数据库一次
将第一次查询到的数据存储在sqlSession对象中,第二次直接从sqlSession对象中取即可
*/
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
studentDao.findStudents1(103);
studentDao.findStudents1(103);
}
}
用同一个sqlSession对象进行了两次相同数据的查询,可以通过日志看到只与数据库交互了一次
2.1 一级缓存失效
缓存失效:指的是缓存中的数据被清理,缓存中没有数据,当发生缓存失效后,再向数据库发送请求就需要再次建立连接去执行操作,以下情况会导致缓存失效
- 执行删除,修改,新增后会清空一级缓存数据
- 执行sqlSession对象中的clearCache()方法,强制清空一级缓存
- 执行sqlSession对象中的close()方法,关闭连接对象
3. mybatis中的二级缓存
二级缓存:是sqlSessionFactory级别的(sqlSessionFactory对象只有一个),即使一个sqlSession对象关闭了连接,用另一个sqlSession对象依旧可以查到缓存中的数据
3.1 二级缓存的配置
mybatis中二级缓存默认是不开启的,需要我们自己去配置
1. 启用二级缓存
在mybatis.xml 中启用二级缓存,如下代码所示,当cacheEnabled设置为true时启用二级缓存,设置为false时禁用二级缓存.
<setting name="cacheEnabled" value="true"/>
2. 对象序列化
将所有的POJO(简单的普通对象)类实现序列化接口Java.io.Serializable.
3. 配置映射文件
在Mapper映射文件中添加<cache></cache>标签,表示此mapper开启二级缓存.当SqlSeesion关闭时,会将数据存入到二级缓存
<!--
设置二级缓存配置
1. size:设置缓存对象数量
2. flushInterval:设置二级缓存有效时间,单位是毫秒
3. readOnly:设置缓存中的数据只读
4. eviction:配置到期后的淘汰策略
-->
<cache></cache>
这个标签有一些属性可以对二级缓存进行一些设置,可以参考官方API
size:设置缓存对象数量
flushInterval:设置二级缓存有效时间,单位是毫秒
readOnly:设置缓存中的数据只读
eviction:配置到期后的淘汰策略