MyBatis动态sql
if标签
语法:
<if test="boolean">
    sql代码
</if>
    
在mapper文件中
<select id="selectStudent" resultType="indi.yuluo.domain.Student">
	select id, name, email, age from student
    <if test="条件">
        sql语句
    </if>    
    if标签可以有多个    
</select> 
如果条件为真时,把if中的sql语句添加到主sql语句的后面,形成一个完成的sql语句        
 
dao方法
/**
 * 动态sql之if语句
 * @param student
 * @return
 */
List<Student> selectIf(Student student);
 
mapper文件:
<select id="selectIf" resultType="indi.yuluo.domain.Student">
    select id, name, email, age from student
    /*为了语法正确,即在第一个if条件不成立时可以执行第二个if的条件要在where后面加上一个对结果不影响的sql语句*/
    where id = -1
    /*if 标签的使用 test的判断条件是对象的属性值
        通过传入的参数只进行判断 表示的是name属性为空或者为空字符串时
      */
    <if test="name != null and name != ''">
        or name = #{name}
    </if>
    <if test="age > 0">
       /*为了保证最后组合到一起的sql语句正确,最后需要加 or 或者 and
         使用大于和小于号时,大于>没问题,小于会被认为是一个标签的起始标签出现错误  需要使用实体符号替换
         */
        or age = #{age}
    </if>
</select>
 
单元测试
    @Test
    public void testSelectIf() {
        SqlSession session = MyBatisUtils.getSqlSession();
        StudentDao mapper = session.getMapper(StudentDao.class);
        // 准备参数
        Student student = new Student();
        student.setAge(21);
//        student.setName("yuluo");
        List<Student> students = mapper.selectIf(student);
        session.close();
        students.forEach(System.out::println);
    }
 
| 符号 | 含义 | 实体符号 | 
|---|---|---|
| < | 小于 | < | 
| > | 大于 | > | 
| <= | 小于等于 | <= | 
| >= | 大于等于 | >= | 
where标签
使用if标签时,容易引起sql语句语法错误,使用where标签解决if语句产生的语法问题
使用时where,里面是一个或者多个if标签,当有一个if标签 判断条件为true,where标签会转为WHERE关键字附加到sql语句的后面,如果if没有一个条件为true,或略where标签和里面的if标签
语法:
<where>
	<if test="条件1">sql语句1</if>
	<if test="条件2">sql语句2</if>
    ……
</where>
 
mapper文件
<!--where标签-->
<select id="selectWhere" resultType="indi.yuluo.domain.Student">
    select * from student
    <where>
        <if test="name != null and name != ''">
            or name = #{name}
        </if>
        <if test="age > 0">
            or age < #{age}
        </if>
    </where>
</select>
 
dao方法
/**
 * 动态sql语句的where标签
 * @param student
 * @return student
 */
List<Student> selectWhere(Student student);
 
单元测试
/**
 * 用于测试:动态sql语句的where标签
 */
@Test
public void testSelectWhere() {
    SqlSession session = MyBatisUtils.getSqlSession();
    StudentDao dao = session.getMapper(StudentDao.class);
    Student student = new Student();
    student.setName("huakai");
    student.setAge(24);
    List<Student> students = dao.selectWhere(student);
    session.close();
    students.forEach(System.out::println);
}
 
输出结果
Opening JDBC Connection
Created connection 2005733474.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@778d1062]
==>  Preparing: select * from student WHERE name = ? or age < ?
==> Parameters: huakai(String), 24(Integer)
<==    Columns: id, name, email, age
<==        Row: 1001, yuluo, yuluo829@aliyun.com, 21
<==        Row: 1002, huakai, 2457608344@qq.com, 21
<==        Row: 1003, 张三, zhangsan@qq.com, 21
<==      Total: 3
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@778d1062]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@778d1062]
Returned connection 2005733474 to pool.
学生信息{id=1001, name='yuluo', email='yuluo829@aliyun.com', age=21}
学生信息{id=1002, name='huakai', email='2457608344@qq.com', age=21}
学生信息{id=1003, name='张三', email='zhangsan@qq.com', age=21}
 
使用where标签组成的sql语句是
select * from student WHERE name = ? or age < ?
自动加了where关键字,紧跟在where之后的and或者or被删掉了
foreach标签
标签用于实现对于数组与集合的遍历。一般使用在in语句中,对其使用,需要注意
- collection表示需要遍历的集合类型:list,array等
 - open,close,separator为对遍历内容的sql拼接
 
语法:
语法:
<foreach collection="集合类型" open="开始的字符" close="结束的字符" item="集合中的成员" separator="集合成员之间的分隔符">
    #{item的值}
</foreach>
 
- collection 表示 循环的对象 数组或者list集合 如果dao接口方法的形参是数组collection=“array” 如果是list : collection=“list”.
 - open 循环开始时的字符
 - close 循环结束时的字符
 - item 集合成员,自定义的变量
 - separator 集合成员之间的分隔符
 - #{item} 获取集合成员的值
 
foreach遍历简单类型的集合
mapper文件
<!--foreach的第一种方式 简单类型
    当list集合不为空时进行这样的处理
-->
<select id="selectForeach" resultType="indi.yuluo.domain.Student">
    select * from student
    <if test="list != null and list.size() > 0">
        where id in
        <foreach collection="list" open="(" close=")" separator="," item="studentId">
            #{studentId}
        </foreach>
    </if>
</select>
 
dao文件
/**
 * 使用foreach进行动态sql语句的拼接
 * 循环简单类型的List集合
 * @param idList
 * @return list
 */
List<Student> selectForeach(List<Integer> idList);
 
单元测试
@Test
public void testForeach() {
    SqlSession session = MyBatisUtils.getSqlSession();
    StudentDao dao = session.getMapper(StudentDao.class);
    List<Integer> id = new ArrayList<>();
    id.add(1002);
    id.add(1003);
    id.add(1004);
    id = null;
    List<Student> students = dao.selectForeach(id);
    session.close();
    students.forEach(System.out::println);
}
 
foreach遍历java对象类型的集合
mapper文件
<!--foreach第二种方式 遍历对象类型集合
    取出student的id属性进行动态sql语句的拼接-->
<select id="selectForeach2" resultType="indi.yuluo.domain.Student">
    select * from student
    <if test="list != null and list.size() > 0">
        where id in
        <foreach collection="list" open="(" close=")" separator="," item="students">
            #{students.id}
        </foreach>
    </if>
</select>
 
dao方法
/**
 * foreach对对象类型的集合遍历
 * @param students
 * @return
 */
List<Student> selectForeach2(List<Student> students);
 
单元测试
/**
 * 用于测试:foreach的第二种方式
 */
@Test
public void testSelectForeach2() {
    SqlSession session = MyBatisUtils.getSqlSession();
    StudentDao mapper = session.getMapper(StudentDao.class);
    List<Student> student = new ArrayList<>();
    Student student1 = new Student();
    Student student2 = new Student();
    student1.setId(1002);
    student2.setId(1005);
    student.add(student1);
    student.add(student2);
    List<Student> students = mapper.selectForeach2(student);
    session.close();
    students.forEach(stu-> System.out.println("stu = " + stu));
}
 
代码片段
语法:
在mapper文件中定义 sql代码片段
<sql id="唯一值">部分sql语句</sql>    
在其他地方引用
<include refid="唯一值"/>    
 
mapper文件
<!--定义sql代码片段-->
<sql id="select">
    select * from student
</sql>
<!--foreach第二种方式 遍历对象类型集合
    取出student的id属性进行动态sql语句的拼接-->
<select id="selectForeach2" resultType="indi.yuluo.domain.Student">
    <include refid="select"/>
    <if test="list != null and list.size() > 0">
        where id in
        <foreach collection="list" open="(" close=")" separator="," item="students">
            #{students.id}
        </foreach>
    </if>
</select









