mybatis_动态SQL

Posted 一头牛这么多人放

tags:

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

 动态SQL

在实际的开发过程中,再查询的过程中有时可能会有多个条件,有时查询的条件个数可能时一个,用户再添加查询信息时,查询条件的个数是不一定的,所以可以利用动态SQL来解决该问题,动态SQL会根据传入的条件动态拼接SQL语句

if 标签

用该标签来判断用户是否输入某个条件,或用户输入是否符合查询条件

1:再StudentMapper.xml文件中编写以下内容

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.doaoao.dao.StudentDao">

    <select id="selectIf" resultType="student">
        SELECT id,name,age,score
        FROM t_student
        WHERE 1 = 1
        <if test="name != null and name != ‘‘">
            AND name like ‘%‘ #{name} ‘%‘
        </if>
        <if test="age > 0">
            AND age > #{age}
        </if>
    </select>
</mapper>

# 注:上方添加 where 1 = 1 的目的是,当用户未输入name和age两个条件是,不至于让where的条件为空,为空的话SQL语句就不正确

2:在StudentDao中添加接口(接口名称与select中的属性id名称相同)

package com.doaoao.dao;

import com.doaoao.bean.Student;

import java.util.List;

public interface StudentDao {
    List<Student> selectIf(Student student);
}

3:在测试类中进行测试

package com.doaoao.test;

import com.doaoao.bean.Student;
import com.doaoao.dao.StudentDao;
import com.doaoao.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

public class StudentTest01 {
    private StudentDao studentDao;
    private SqlSession sqlSession;
    // 执行测试方法之前会执行该方法
    @Before
    public void init(){
        sqlSession = MyBatisUtil.getSqlSession();
        studentDao = sqlSession.getMapper(StudentDao.class);
    }

    // 方法执行完成后需要关闭sqlSession
    @After
    public void closeSession(){
        if(sqlSession != null){
            sqlSession.close();
        }
    }

    @Test
    public void selectIf(){
        Student student = new Student("liu",0,0);
        List<Student> students = studentDao.selectIf(student);
        System.out.println(students);
    }
}

where 标签

where标签的作用与上方 " where 1 = 1 " 具有相同的作用

1:编写StudentMapper.xml中的内容

    <select id="selectWhere" resultType="student">
        SELECT id,name,age,score
        FROM t_student
        <where>
            <if test="name != null and name != ‘‘">
                AND name like ‘%‘ #{name} ‘%‘
            </if>
            <if test="age > 0">
                AND age > #{age}
            </if>
        </where>

    </select>

2:添加接口

    List<Student> selectWhere(Student student);

3:添加测试类

    @Test
    public void selectWhere(){
        Student student = new Student("liu",0,0);
        List<Student> students = studentDao.selectIf(student);
        System.out.println(students);
    }

choose 标签

该标签的作用就是,若 name 不为空,就利用name进行查询,若name为空,则利用 age 进行查询;若age也为空可利用默认的进行查询

1:编写StudentMapper.xml中的内容

    <select id="selectChoose" resultType="student">
        SELECT id,name,age,score
        FROM t_student
        <where>
            <choose>
                <when test="name != null and name != ‘‘">
                    name like ‘%‘ #{name} ‘%‘
                </when>
                <when test="age >= 0">
                    age > #{sge}
                </when>
            </choose>
        </where>
    </select>

 2:添加接口

    List<Student> selectChoose(Student student);

3:编写测试类

    @Test
    public void selectChoose(){
        Student student = new Student("liu",0,0);
        List<Student> students = studentDao.selectIf(student);
        System.out.println(students);
    }

 foreach标签

当用户想要查询 1,3,5,7,9这几条数据时,在sql语句中我们可以用以下方式实现

select id,name,age from t_student where id in(1,3,5,7,9)

在mybatis中我们可以使用foreact来实现

1:修改StudentMapper.xml中的内容

   <!-- 遍历数组 --> 
  <select id="selectForeachArray" resultType="student">
        SELECT id,name,age,score
        FROM t_student
        <if test="array != null and array.length > 0">
            WHERE id in 
            <foreach collection="array" open="(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </if>
    </select>
<!-- 遍历集合 --
>   <select id="selectForeachList" resultType="student"> SELECT id,name,age,score FROM t_student <if test="list != null and list.length > 0"> WHERE id in <foreach collection="list" open="(" close=")" item="id" separator=","> #{id} </foreach> </if> </select

2:添加接口

// 遍历数组接口
List<Student> selectForeachArray(Object[] ids);

// 遍历集合接口
List<Student> selectForeachList(Object[] ids);

3:编写测试类

// 数组测试类
@Test
public void selectForeachArray(){
    Object[] ids = new Object[]{1,3,5,7,9};

    List<Student> students = studentDao.selectForeachArray(ids);
     System.out.print(students)
}

// 集合测试类 @Test public void selectForeachList(){ List<Integer> list = new ArrayList<>(); list.add(5); list.add(6); list.add(10); list.add(15); List<Student> students = studentDao.selectForeachList(list); System.out.print(students) }

sql 标签 

该标签用来定义一个可被复用的sql片段

1:在mapper中配置并使用该标签

    <!-- 定义该标签 -->
  <sql id="selectSql"> SELECT id,name,age,score FROM t_student </sql>
   <select id="selectForeach" resultType="student">
    <!-- 使用该标签 -->
    <include refid="selectSql">   <if test="array != null and array.length > 0">   WHERE id in   <foreach collection="array" open="(" close=")" item="id" separator=",">   #{id}   </foreach>   </if> </select>

...

动态SQL使用注意事项

例如:

<!-- 不报错 -->
<when test="age >= 0">
       age > #{sge}
</when>

<!-- 报错 -->
<when test="age >= 0">
       age < #{sge}      “<”   会被误认为是尖括号的开头,所有报错
</when>

解决的第一种方式:实体符号代替的使用

原符号      实体符号
  <         &lt;
  <=        &lt;=
  >         &gt;
  >=        &gt;=
  &         &amp;
  "         &quot;&apos;

解决的第二种方式: CDATA

可以将特殊的符号放在 < ! [ CDATA[ ] ]>中

    <if test="age>=0">
        AND age <![CDATA[ <  ]]> #{age}
    </if>

 ...

 本笔记参考自:小猴子老师教程 http://www.monkey1024.com

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

MyBatis动态SQL标签用法

mybatis学习(39):动态sql片段

mybatis动态sql片段与分页,排序,传参的使用

Mybatis -- 动态Sql概述动态Sql之<if>(包含<where>)动态Sql之<foreach>sql片段抽取

mybatis动态sql之利用sql标签抽取可重用的sql片段

Mybatis动态sql