动态sql

作者: 桑鱼nicoo | 来源:发表于2020-03-13 14:18 被阅读0次

if判断

查询时携带了哪个字段where条件就按照什么来查询

mapper 接口

public interface EmployMapperDynamicSQL {
    // 携带了哪个字段查询条件就带上这个字段的值
    public List<Employee> getEmpsByConditionIf(Employee employee);
}

mapper.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">
<!--namespace:名称空间,对应mapper接口-->
<mapper namespace="com.sangyu.mapper.EmployMapperDynamicSQL">
    <!--查询员工,要求,携带了哪个字段查询条件在查询的时候就带上这个字段的值-->
    <select id="getEmpsByConditionIf" resultType="com.sangyu.bean.Employee">
        select * from tbl_employee
        where
        <if test="id!=null">
            id=#{id}
        </if>
        <if test="lastName!=null &amp;&amp; lastName!= &quot;&quot;">
            and last_name like #{lastName}
        </if>
        <if test="email != null and email.trim() != &quot;&quot;">
            and email = #{email}
        </if>
        <if test="gender==0 or gender == 1">
           and gender = #{gender}
        </if>
    </select>
</mapper>

where查询条件

前面的例子中通过if 条件增加判断where按照什么条件去查询,但是会有一个问题,当传递的参数中前面的没有值where条件 也会在前面加上and

针对上面的问题,可以查询条件中增加 where 1= 1,剩余的if判断语句中都用and

还有一种方式就是使用where标签,mybatis将所有的查询条件拼装sql,多出来的and或者or去掉(只会去掉第一个多出来的and或者or)

Trim标签

使用where条件只会去掉第一个多出来的and或者or,如果后面多出的and或者or,使用where并不能解决。mybatis提供了Trim标签,

<?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">
<!--namespace:名称空间,对应mapper接口-->
<mapper namespace="com.sangyu.mapper.EmployMapperDynamicSQL">
    <!--查询员工,要求,携带了哪个字段查询条件在查询的时候就带上这个字段的值-->
    <select id="getEmpsByConditionIf" resultType="com.sangyu.bean.Employee">
        select * from tbl_employee
        -- where 1 = 1
        <!--        <where>-->
--         prefix = "" 前缀,trim标签体中是整个字符串拼串后的结果,prefix给拼串后的整个字符串加上一个前缀
--         prefixOverrides = "" 前缀覆盖,去掉整个字符串前面多余的字符
--         suffix = "" 后缀 给拼串后的整个字符串加一个后缀
--         suffixOverrides = "" 后缀覆盖 ,去掉整个字符串后多余的字符
        <trim prefix="where" suffixOverrides="and">
            <if test="id!=null">
                id=#{id} and
            </if>
            <if test="lastName!=null &amp;&amp; lastName!= &quot;&quot;">
                last_name like #{lastName} and
            </if>
            <if test="email != null and email.trim() != &quot;&quot;">
                email = #{email} and
            </if>

            <if test="gender==0 or gender == 1">
                gender = #{gender} and
            </if>
        </trim>
        <!--        </where>-->
    </select>
</mapper>

choose分支选择(when ,otherwise)

mybaits中的分支选择相当于java中的switch-case

<?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">
<!--namespace:名称空间,对应mapper接口-->
<mapper namespace="com.sangyu.mapper.EmployMapperDynamicSQL">
    <select id="getEmpsByConditionChoose" resultType="com.sangyu.bean.Employee">
        select * from tbl_employee
        -- 如果带了id就用id查,如果带了lastName就用lastName查,只会进入其中一个
        -- 当所有条件都不满足的时候就输出 otherwise 中的内容
        <where>
            <choose>
                <when test="id!=null">
                    id=#{id}
                </when>
                <when test="lastName!=null">
                    last_name like #{lastName}
                </when>
                <when test="email!=null">
                    email = #{email}
                </when>
                <otherwise>
                    gender = 0
                </otherwise>
            </choose>
        </where>
    </select>
</mapper>

set和if结合的动态更新

<?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">
<!--namespace:名称空间,对应mapper接口-->
<mapper namespace="com.sangyu.mapper.EmployMapperDynamicSQL">
    <select id="updateEmp">
        update tbl_employee
        <set>
            <if test="lastName!=null">
                last_name=#{lastName},
            </if>
            <if test="email != null">
                email = #{email},
            </if>
            <if test="gender!= null">
                gender = #{gender}
            </if>
            where id = #{id}
        </set>
    </select>
</mapper>

foreach 遍历集合

在foreach遍历集合时,如果集合传递的是List(就是在mapper中接口方法定义的参数类型)那么,mybatis会将List封装到map中,map的key默认是list,如果在定义方法的时候定义了@param那么key就是定义的参数名称。foreach标签中的collectin属性值根据是否定义@param决定属性值的内容

<!--   collection : 执行要遍历的集合-->
    <!--   list类型的参数会特殊处理封装在map中,map的key就叫list-->
    <!--   item : 将当前遍历出的元素赋值给指定的变量-->
    <!--   separator : 每个元素之间的分隔符-->
    <!--   open : 遍历出所有结果拼接一个开始的字符-->
    <!--        遍历出所有结果拼接一个结束的字符-->
    <!--   索引,遍历list的时候index就是索引,item 就是当前值-->
    <!--        遍历map的时候index表示的就是map的key,item就是map的值-->
    <!--   #{变量名}就能取出变量的值也就是当前遍历出的元素-->
    <select id="getEmpsByConditionForeach" resultType="com.sangyu.bean.Employee">
        select * from tbl_employee
        <foreach collection="ids" item="item_id" separator=","
                 open="where id in(" close=")">
            #{item_id}
        </foreach>
    </select>

foreach 批量保存

// mapper接口定义
public interface EmployMapperDynamicSQL {
    public void addEmps(@Param("emps") List<Employee> emps);
}
<!--批量保存 -->
<select id="addEmps">
    insert into tbl_employee(last_name,email,gender,d_id)
    values
    <foreach collection="emps" item = "emp" separator=",">
        (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
    </foreach>
</select>
image.png

另一种批量保存的方式

dbconfig.properties 修改数据库连接属性allowMultiQueries=true,使用Mysql的批量保存

jdbc.driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis?useUnicode=true&useSSL=false&allowMultiQueries=true
jdbc.username = root
jdbc.password = abcd123456
<!--    使用Mysql的批量保存,可以foreach遍历,mysql支持value(),(),()语法-->
<select id="addEmps">
    <foreach collection="emps" item="emp" separator=";">
        insert into tbl_employee(last_name,email,gender,d_id) values
        (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
    </foreach>
</select>

bind 绑定

<!--    bind,可以将OGNL表达式的值绑定到一个变量中,方便后面引用这个变量的值,_parameter参数保存了com.sangyu.bean.Employee这个对象。
    所以可以通过OGNL表达式从_parameter参数中获取到Employee的对应属性值
    (也就是把_parameter看作了users的别名)。-->
<select id="getEmpsTestInnerParameter" resultType="com.sangyu.bean.Employee">
    <bind name="_lastName" value="'%' +lastName+'%'"/>
        select * from tbl_employee
    <if test="_parameter != null">
        where last_name like #{_lastName}
  </if>
</select>

执行测试代码

@Test
public void Test21() throws IOException {
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 
    SqlSession session = sqlSessionFactory.openSession();
    try {
        EmployMapperDynamicSQL mapper = session.getMapper(EmployMapperDynamicSQL.class);
        Employee employee = new Employee();
        employee.setLastName("e");
        List<Employee> list = mapper.getEmpsTestInnerParameter(employee);
        for(Employee employee1 : list){
            System.out.println(employee1);
        }
    } finally {
        session.close();
    }
}

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3e3yxq742w2so

相关文章

  • MyBatis学习:动态sql

    1.动态sql 动态sql是mybatis中的一个核心,什么是动态sql?动态sql即对sql语句进行灵活操作,通...

  • 第十三章 使用动态SQL(一)

    第十三章 使用动态SQL(一) 动态SQL简介 动态SQL是指在运行时准备并执行的SQL语句。在动态SQL中,准备...

  • 第八章 动态SQL

    动态SQL中的元素介绍 动态SQL有什么作用 MyBatis提供了对SQL语句动态组装的功能 动态SQL中的元素 ...

  • 关于Mybatis的一些问题讨论

    Mybatis动态sql是做什么的?都有哪些动态sql?简述一下动态sql的执行原理 动态sql的用途 Mybat...

  • MyBatis5-动态 SQL

    动态 SQL 什么是动态 SQL 就是动态的对 SQL 进行组装 拼接. : 可以自动去...

  • geoserver动态颜色参数样式、动态sql配置实现

    geoserver动态颜色参数样式、动态sql配置实现 动态颜色参数样式、动态sql 访问方式: http://l...

  • 强大的动态SQL

    1 动态SQL# 那么,问题来了: 什么是动态SQL? 动态SQL有什么作用? 传统的使用JDBC的方法,相信大家...

  • MyBatis:动态 SQL

    1. 动态 SQL 简而言之,动态 SQL 就是在 Mapper 中使用分支、循环等逻辑。常见的动态 SQL 元素...

  • 无标题文章

    ### 一、简答题 #### 1、Mybatis动态sql是做什么的?都有哪些动态sql?简述一下动态sql的执行...

  • 五,MyBatis动态SQL

    一,含义:动态SQL是指根据参数数据动态组织SQL的技术 二,动态SQL的应用场景:比如淘宝搜索的时候,可以动态的...

网友评论

      本文标题:动态sql

      本文链接:https://www.haomeiwen.com/subject/nbzcjhtx.html