蒙圈的备忘录:MyBatis动态 SQL

MyBatis动态 SQL

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

常用的动态 SQL 标签有 if、where、choose、foreach等。

在 mapper 的动态 SQL 中若出现大于号(>)、小于号(<)、大于等于号(>=),小于等于号(<=)等符号,最好将其转换为实体符号。否则,XML 可能会出现解析出错问题。
特别是对于小于号(<),在 XML 中是绝不能出现的。否则解析 mapper 文件会出错。
实体符号表:
在这里插入图片描述

if

Dao接口定义方法

/*
对于该标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片断拼接到其所在的 SQL 语句中。
语法:<if test=”条件”> sql 语句的部分 </if>
*/
List<Student> selectStudentIf(Student student);

sql映射文件

<!-- if
         <if:test="使用参数java对象的属性值作为判断条件,语法 属性=XXX值">
    -->
<select id="selectStudentIf" resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student
 where 1=1
 <if test="name != null and name !='' ">
 and name = #{name}
 </if>
 <if test="age > 0 ">
 and age &gt; #{age}
 </if>
</select>

测试方法:

@Test
public void testSelect() throws IOException {
 Student param = new Student();
 param.setName("李力");
 param.setAge(18);
 List<Student> studentList = studentDao.selectStudentIf(param);
 for(Student stu:students){
            System.out.println("if==="+stu);
        }
}

where

Dao接口定义方法

/*
<if/>标签的中存在一个比较麻烦的地方:需要在 where 后手工添加 1=1 的子句。因为,若 where 后
的所有<if/>条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,SQL
出错。所以,在 where 后,需要添加永为真子句 1=1,以防止这种情况的发生。但当数据量很大时,会
严重影响查询效率。
使用<where/>标签,在有查询条件时,可以自动添加上 where 子句;没有查询条件时,不会添加
where 子句。需要注意的是,第一个<if/>标签中的 SQL 片断,可以不包含 and。不过,写上 and 也不错,
系统会将多出的 and 去掉。但其它<if/>中 SQL 片断的 and,必须要求写上。否则 SQL 语句将拼接出错
。
语法:<where> 其他动态 sql </where>
*/
List<Student> selectStudentWhere(Student student);

sql映射文件

<!--
     where: <where> <if> <if>...</where>
    -->
    <select id="selectStudentWhere" resultType="com.bjpowernode.domain.Student">
        select id,name,email,age from student
        <where>
            <if test="name !=null and name !='' ">
                name = #{name}
            </if>
            <if test="age > 0">
                or age > #{age}
            </if>
        </where>
    </select>

测试方法:

@Test
public void testSelectWhere() throws IOException {
 Student param = new Student();
 param.setName("李力");
 param.setAge(18);
 List<Student> studentList = studentDao.selectStudentWhere(param);
 studentList.forEach( stu -> System.out.println(stu));
}

foreach

在这里插入图片描述

1. foreach遍历 List<简单类型>

表达式中的 List 使用 list 表示,其大小使用 list.size 表示。
需求:查询学生 id 是 1002,1005,1006
Dao接口定义方法

List<Student> selectStudentForList(List<Integer> idList);

sql映射文件

<!--foreach使用1 , List<Integer>-->
    <select id="selectForeachOne" resultType="com.bjpowernode.domain.Student">
        select * from student where id in
        <foreach collection="list" item="myid" open="(" close=")" separator=",">
                  #{自定义}
        </foreach>
    </select>

测试方法:

@Test
public void testSelectForList() {
 List<Integer> list = new ArrayList<>();
 list.add(1002);
 list.add(1005);
 list.add(1006);
 List<Student> studentList = studentDao.selectStudentForList(list);
 studentList.forEach( stu -> System.out.println(stu));
}

2. 遍历 List<对象类型>

Dao接口定义方法

List<Student> selectStudentForList2(List<Student> stuList);

sql映射文件

<select id="selectForeachTwo" resultType="com.bjpowernode.domain.Student">
        select * from student where id in
        <foreach collection="list" item="stu" open="("  close=")" separator=",">
                 #{stu.id}
        </foreach>

    </select>

测试方法:

@Test
public void testSelectForList2() {
 List<Student> list = new ArrayList<>();
 Student s1 = new Student();
 s1.setId(1002);
 list.add(s1);
 s1 = new Student();
 s1.setId(1005);
 list.add(s1);
 List<Student> studentList = studentDao.selectStudentForList2(list);
 studentList.forEach( stu -> System.out.println(stu));
}

动态 SQL 之代码片段

Dao接口定义方法

List<Student> selectStudentSqlFragment(List<Student> stuList);

sql映射文件

<!--
<sql/>标签用于定义 SQL 片断,以便其它 SQL 标签复用。而其它标签使用该 SQL 片断,需要使用
<include/>子标签。该<sql/>标签可以定义 SQL 语句中的任何部分,所以<include/>子标签可以放在动态 SQL
的任何位置。
-->
<!--创建 sql 片段 id:片段的自定义名称--> 
<sql id="studentSql">
 select id,name,email,age from student
</sql> 
<select id="selectStudentSqlFragment" resultType="com.bjpowernode.domain.Student">
 <!-- 引用 sql 片段 -->
 <include refid="studentSql"/>
 <if test="list !=null and list.size > 0 ">
 where id in
 <foreach collection="list" open="(" close=")" item="stuobject" separator=",">
 #{stuobject.id}
 </foreach>
 </if>
</select>

测试方法:

@Test
public void testSelectSqlFragment() {
 List<Student> list = new ArrayList<>();
 Student s1 = new Student();
 s1.setId(1002);
 list.add(s1);
 s1 = new Student();
 s1.setId(1005);
 list.add(s1);
 List<Student> studentList = studentDao.selectStudentSqlFragment(list);
 studentList.forEach( stu -> System.out.println(stu));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值