MyBatis之动态SQL

Posted 一梦先知

tags:

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

利用动态 SQL可以很方便地根据不同条件拼接 SQL 语句

我们先搭建MyBatis配置:

接口类

package com.jd.userinfo.dao;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.jd.vo.UserInfo;

public interface IUserInfoDao {
    List<UserInfo> select(@Param("userName")String userName,@Param("age")Integer age);
    boolean delete(List<Integer>  list);
    boolean update(UserInfo userInfo);
}

mybatis_config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="jdbc.properties"></properties>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
        <typeAlias type="com.jd.vo.UserInfo" alias="UserInfo"/>
    </typeAliases>
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.userName}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
        <mapper resource="./sql/user_info.xml"/>
    </mappers>
</configuration>

Userinfo.java

package com.jd.vo;

public class UserInfo {

    private int id;
    private String userName;
    private String password;
    private String realName;
    private String age;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getRealName() {
        return realName;
    }
    public void setRealName(String realName) {
        this.realName = realName;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    
}

user_info.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.jd.userinfo.dao.IUserInfoDao">

    <resultMap type="com.jd.vo.UserInfo" id="userInfo">
        <id property="id" column="id"/>
        <result property="userName" column="user_name"/>
        <result property="password" column="password"/>
        <result property="age" column="age"/>
        <result property="realName" column="real_name"/>
    </resultMap>

  <!-- ——————————————————————————此处添加待测试动态sql—————————————————————————— -->
</mapper>

测试类

public class Test {

    public static void main(String[] args) {
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis_config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);//为true自动提交,默认false开启事务需要手动commit
            IUserInfoDao userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
       //——————————————————————————————————此处添加待测试代码—————————————————————————————————————————————————— sqlSession.close(); }
catch (IOException e) { e.printStackTrace(); } } }

 

<if>:常用于根据条件拼接where 子句

我们在user_info.xml中添加如下代码并测试:可见当满足标签中test属性的条件时,将会拼接if中的语句,否则不会

<select id="select" resultMap="userInfo">
    select id,user_name,password,real_name,age 
    from user_info
    where 1=1
        <if test="userName!=null">
        and user_name like #{userName}
        </if>
        <if test="age!=null">
            and age = #{age}
        </if>
</select>

测试代码及测试结果:

List<UserInfo> list = userInfoDao.select("%zzj%", null);
System.out.println(list.size());

 

 <where>:元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句;而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。

我们在user_info.xml中添加如下代码并测试:可见当后面所有语句均不存在时,where不会拼接在sql语句中

<select id="select" resultMap="userInfo">
    select id,user_name,password,real_name,age 
    from user_info
    <where>
        <if test="userName!=null">
            and user_name like #{userName}
        </if>
        <if test="age!=null">
            and age = #{age}
        </if>
    </where>
</select>

测试代码及结果:

List<UserInfo> list = userInfoDao.select(null, null);
System.out.println(list.size());

 

 <choose>:元素类似 Java 中的 switch 语句

我们在user_info.xml中添加如下代码并测试:所有when标签中按顺序,只要有一个满足条件就会选择该sql语句拼接,其余的不拼接

<select id="select" resultMap="userInfo">
    select id,user_name,password,real_name,age 
    from user_info
    <where>
        <choose>
            <when test="userName!=null">
                and user_name like #{userName}
            </when>
            <when test="age!=null">
                and age = #{age}
            </when>
        </choose>
    </where>
</select>

测试代码及结果:

List<UserInfo> list = userInfoDao.select("zzj", 12);
System.out.println(list.size());

 

 <set>: 元素可以用于动态包含需要更新的列,而删掉无关的逗号

我们在user_info.xml中添加如下代码并测试:

<update id="update">
    update user_info
    <set>
        <if test="realName!=null">
        real_name=#{realName},
        </if>
        <if test="password!=null">
            password=#{password}
        </if>
    </set>
    where id=#{id}
</update>

测试代码及结果:

UserInfo userInfo = new UserInfo();
userInfo.setId(1);
userInfo.setRealName("Jerry");
System.out.println(userInfoDao.update(userInfo));

 

 

<foreach>:foreach元素用于对一个集合进行遍历,构建 IN 条件语句时常用该元素;foreach 元素允许指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量,也允许指定开头与结尾的字符串以及在迭代结果之间放置分隔符。

我们在user_info.xml中添加如下代码并测试实现批量删除:

<delete id="delete">
    delete from user_info
    where id in
    <!-- 声明可以在元素体内使用的集合项(item)和索引(index)变量,指定开头与结尾的字符串以及在迭代结果之间放置分隔符。 -->
    <foreach item="id" collection="list" open="(" close=")" separator=",">
        #{id}
    </foreach>
</delete>

测试代码及结果如下:

List<Integer> list = new ArrayList<Integer>();
list.add(2);
list.add(3); System.out.println(userInfoDao.delete(list));

 

 

 

 

 

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

Mybatis 学习笔记总结

MyBatis-05-笔记

Mybatis -- 动态Sql 环境搭建

MyBatis动态SQL标签用法

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

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