MyBatis动态SQL

2020-05-04  本文已影响0人  JBryan

动态 SQL 是 MyBatis 的强大特性之一。根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
DynamicSQLDemo.java

package com.ljessie.mybatisdemo.dao;

import com.ljessie.mybatisdemo.entity.Student;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface DynamicSQLDemo {

    List<Student> getStudentByConditionIf(Student student);

    List<Student> getStudentByConditionTrim(Student student);

    List<Student> getStudentByConditionChoose(Student student);

    void updateStudent(Student student);

    void addStudents(@Param("students")List<Student> students);

}

DynamicSQLDemo.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.ljessie.mybatisdemo.dao.DynamicSQLDemo">

<!--    查询Student,要求:携带了哪个字段,就带上哪个字段的值-->
<!--    List<Student> getStudentByConditionIf(Student student);-->
    <select id="getStudentByConditionIf" resultType="Student">
        select * from student
<!--         使用where标签,解决多出来的and问题-->
        <where>
            <!--test:判断表达式(OGNL表达式参照官方文档)
                从参数中取值进行判断
                有一个问题就是:如果传入的参数中,没有id,后面的第一个条件是and ***,就会出现语法错误-->
            <if test="id != 0">
                id = #{id}
            </if>
            <if test="name != null and name != ''">
                and name = #{name}
            </if>
            <!--ONGL会自动转换字符串与数字:例如"0"==0是成立的-->
            <if test="age != 0">
                and age = #{age}
            </if>
        </where>
    </select>

<!--    List<Student> getStudentByConditionTrim(Student student);-->
    <select id="getStudentByConditionTrim" resultType="Student">
        select * from student
        <!--where标签,没有办法解决and或or在条件后面的情况
        prefix="" :前缀,给拼成的字符串加个前缀
        prefixOverrides="":前缀覆盖,整个字符串前面多余的串给去掉
        suffix="":后缀,给拼成的字符串加个后缀
        suffixOverrides="":后缀覆盖,整个字符串后面多余的串给去掉-->
        where
        <trim suffixOverrides="and">
            <if test="id != 0">
                id = #{id} and
            </if>
            <if test="name != null and name != ''">
                name = #{name} and
            </if>
            <!--ONGL会自动转换字符串与数字:例如"0"==0是成立的-->
            <if test="age != 0">
                age = #{age}
            </if>
        </trim>
    </select>

<!--如果带了id,就用id查,如果带了lastName,就用lastName查。只会进入其中一个-->
<!--    getStudentByConditionChoose-->
    <select id="getStudentByConditionChoose" resultType="Student">
        select
            <include refid="selectColumn"></include>
        from student
        <where>
            <choose>
                <when test="id!=0">
                    id = #{id}
                </when>
                <when test="name!=null">
                    name = #{name}
                </when>
                <otherwise>
                    1 = 1
                </otherwise>
            </choose>
        </where>
    </select>

<!--    场景:带了哪一列的值,就更新哪一列-->
<!--set封装修改条件-->
<!--    updateStudent-->
    <update id="updateStudent" >
        update student
        <set>
            <if test="name != null">
                name = #{name}
            </if>
            <if test="age != 0">
                age = #{age}
            </if>
        </set>
        <where>
            id = #{id}
        </where>
    </update>

<!--批量保存-->
<!--    addStudents-->
<!--    MySQL支持insert into student () values (),(),()这种语法,可以用这一种方式-->
    <insert id="addStudents">
        insert into student (name,age,department_id)
        values
        <foreach collection="students" item="student" separator=",">
            (#{student.name},#{student.age},#{student.department.id})
        </foreach>
    </insert>

<!--    其他数据库用这种方式-->
<!--    <insert id="addStudents">-->
<!--        <foreach collection="students" item="student" separator=";">-->
<!--            insert into student (name,age,department_id)-->
<!--            values (#{student.name},#{student.age},#{student.department.id})-->
<!--        </foreach>-->
<!--    </insert>-->

<!--    两个内置参数:
        不只是方法传递过来的参数可以用来判断,取值。
        MyBatis默认还有两个内置的参数:
        _parameter:代表整个参数。
            方法传来单个参数:_parameter就是这个参数。
            方法传来多个参数:参数会被封装为一个map;_parameter就是这个map

        _databaseId:如果配置了databaseIdProvider标签,_databaseId就是代表当前数据库的别名
    -->

<!--sql标签:抽取可重用的sql片段,方便后面引用
        1、经常将要查询的列名,或者插入用的列名抽取出来,方便引用
        2、include标签来引用已经抽取的sql片段-->
    <sql id="selectColumn">
        id,name,age,department_id
    </sql>
    
</mapper>
上一篇 下一篇

猜你喜欢

热点阅读