MyBatis:动态sql语句

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis:动态sql语句相关的知识,希望对你有一定的参考价值。

文章目录

1. 动态sql语句

1.1 动态sql语句概述

​ Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了。

参考的官方文档,描述如下:

官网地址:https://mybatis.org/mybatis-3/zh/dynamic-sql.html

1.2 动态 SQL之 if标签

我们根据实体类的不同取值,使用不同的 SQL语句来进行查询。比如在 id如果不为空时可以根据id查询,如果username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。

如下图:

<select id="findByCondition" parameterType="student" resultType="student">
    select * from student
    <where>
        <if test="id!=0">
            and id=#id
        </if>
        <if test="username!=null">
            and username=#username
        </if>
    </where>
</select>

当查询条件id和username都存在时,控制台打印的sql语句如下:

 //获得MyBatis框架生成的StudentMapper接口的实现类
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student condition = new Student();
condition.setId(1);
condition.setUsername("lucy");
Student student = mapper.findByCondition(condition);

当查询条件只有id存在时,控制台打印的sql语句如下:

//获得MyBatis框架生成的UserMapper接口的实现类
StudentMapper mapper = sqlSession.getMapper( StudentMapper.class);
Student condition = new Student();
condition.setId(1);
Student student = mapper.findByCondition(condition);

总结语法:

<where>:条件标签。如果有动态条件,则使用该标签代替 where 关键字。
	<if>:条件判断标签。
	<if test=“条件判断”>
		查询条件拼接
	</if>
</where>

1.3 动态 SQL之 foreach标签

循环执行sql的拼接操作,例如:SELECT * FROM student WHERE id IN (1,2,5)。

<select id="findByIds" parameterType="list" resultType="student">
    select * from student
    <where>
        <foreach collection="array" open="id in(" close=")" item="id" separator=",">
            #id
        </foreach>
    </where>
</select>

测试代码片段如下:

//获得MyBatis框架生成的UserMapper接口的实现类
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
int[] ids = new int[]2,5;
List<Student> sList = mapper.findByIds(ids);
System.out.println(sList);

总结语法:

<foreach>:循环遍历标签。适用于多个参数或者的关系。

<foreach collection=“”open=“”close=“”item=“”separator=“”>
获取参数
</foreach>

参数说明

参数说明
collection参数容器类型, (list-集合, array-数组)。
open开始的 SQL 语句。
close结束的 SQL 语句。
item参数变量名。
separator分隔符。

1.4 SQL片段抽取 sql标签

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的

<!--抽取sql片段简化编写-->
<sql id="selectStudent" >SELECT * FROM student</sql>

<select id="findById" parameterType="int" resultType="student">
    <include refid="selectStudent"></include> where id=#id
</select>
<select id="findByIds" parameterType="list" resultType="student">
    <include refid="selectStudent"></include>
    <where>
        <foreach collection="array" open="id in(" close=")" item="id" separator=",">
            #id
        </foreach>
    </where>
</select>

总结语法:

我们可以将一些重复性的 SQL 语句进行抽取,以达到复用的效果。

<sql>:抽取 SQL 语句标签。 
<include>:引入 SQL 片段标签。 
<sql id=“片段唯一标识”>抽取的 SQL 语句</sql> <include refid=“片段唯一标识”/>

1.5 动态sql之 choose标签

<select id="selectConditionWhen" resultType="student" parameterType="student">
    <include refid="select"/>
    <where>
        <choose>
            <when test="id != null">
                id = #id
            </when>
            <when test="name != null">
                AND name = #name
            </when>
            <when test="age != null">
                AND age = #age
            </when>
            <otherwise></otherwise>
        </choose>
    </where>
</select>

测试代码如下:

InputStream inputStream = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student stu =new Student();
stu.setId(2);
List<Student> list = mapper.selectCondition(stu);
for (Student student : list) 
    System.out.println(student);

sqlSession.close();
inputStream.close();

choose会实现如下功能:

  1. 多个 when 标签中,只能执行一个。也就是说:当一个 when 条件满足并执行后,其它的 when 将不再执行。
  2. 当所有 when 都不满足条件时,执行 otherwise 标签。

if 与 choose 的区别:if 相当于java中的if语句; choose相当于java中的switch语句。

1.6 trim标签

trim标签可以在自己包含的内容中加上某些前缀或后缀,与之对应的属性是:prefix、suffix。 还可以把包含内容的开始内容覆盖,即忽略。也可以把结束的某些内容覆盖,对应的属性是:prefixOverrides、suffixOverrides

<insert id="insertTrim" parameterType="student">
    insert into student
    <trim prefix="values(" suffix=")" suffixOverrides=",">
        <if test="id!=null and id!=''">
            id,
        </if>
        <if test="name!=null and name!=''">
            name,
        </if>
        <if test="age!=null and age!=''">
            age,
        </if>
    </trim>
</insert>
@Test
public void InsertTrim() throws Exception 
    InputStream inputStream = Resources.getResourceAsStream("MyBatisConfig.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Student stu = new Student();
    stu.setId(2);
    stu.setName("taoge");
    stu.setAge(18);
    int num = mapper.insertTrim(stu);
    sqlSession.close();
    inputStream.close();

注意:

  1. prefix与suffix可以在sql语句中拼接出一对小括号。
  2. suffixOberrides可以将最后一个逗号去掉。

2. 项目链接

https://download.csdn.net/download/weixin_45525272/85883118

以上是关于MyBatis:动态sql语句的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis:动态sql语句

mybatis--MyBatis动态SQL语句

mybatis 动态SQL .2

mybatis 详解------动态SQL

mybatis 详解------动态SQL

Mybatis之动态构建SQL语句