精华内容
下载资源
问答
  • mybatis的动态标签

    2020-11-01 23:49:40
    参考资料:1、mybatis动态SQL中的动态标签

    参考资料:1、mybatis动态SQL中的动态标签
    2、MyBatis动态SQL(认真看看, 以后写SQL就爽多了)

    一、mybatis的动态标签

    1.1、if 标签

    常常放在条件查询where后的,部分条件中。

    1.1.1、 可以进行非空判断(属性test中只有一个字段)

        <select id="selectByAll" resultType="com.xuecheng.domain.Tab1">
            SELECT * FROM tab1
            where size = 11
            <if test="id != null">
                and id = #{id}
            </if>
        </select>
    

    可能会报错:org.apache.ibatis.reflection.ReflectionException
    解决办法有两种:
    1、在参数前加注解

        public List<Tab1> selectByAll(@Param("id") int id);
    

    2、在标签test属性中,用_parameter

            <if test="_parameter != null">
                and id = #{id}
            </if>
    

    1.1.2、 可以进行非空判断(属性test中只有两个字段)

        <select id= "findActiveBlogLike"
                resultType= "Blog" >
            SELECT * FROM BLOG WHERE state = 'ACTIVE'
            <if test= "title != null" >
                AND title like #{title}
            </ if >
            
            <if test= "author != null and author.name != null" >
                AND author_name like #{author.name}
            </ if >
        </select>
    

    2.2、include标签<include id =" ">

    有SQL语句被多次使用后,可以用该标签。其中的属性refid的值是指向<sql id=" ">标签的属性id值

    2.3、 choose 标签

    choose when otherwise 标签可以帮我们实现 if else 的逻辑。一个 choose 标签至少有一个 when, 最多一个otherwise。

    
        <select id="selectByIdOrName" resultType="xuecheng.domain.Student" parameterType="xuecheng.domain.Student">
            select
            *
            from student
            where 1=1
            <choose>
                <when test="studentId != null">
                    and student_id=#{studentId}
                </when>
                <when test="name != null and name != ''">
                    and name=#{name}
                </when>
                <otherwise>
                    and 1=2
                </otherwise>
            </choose>
        </select>
    

    2.4、 trim 标签

    where 标签和 set 标签 都只是trim 标签的一种

    2.4.1、trim标签的属性

    prefix: 当 trim 元素包含有内容时, 增加 prefix 所指定的前缀

    prefixOverrides: 当 trim 元素包含有内容时, 去除 prefixOverrides 指定的 前缀

    suffix: 当 trim 元素包含有内容时, 增加 suffix 所指定的后缀

    suffixOverrides: 当 trim 元素包含有内容时, 去除 suffixOverrides 指定的后缀

    2.5、 foreach 标签

    2.5.1、foreach 标签的几个属性

    ollection: 必填, 集合/数组/Map的名称.

    item: 变量名。 即从迭代的对象中取出的每一个值

    index: 索引的属性名。 当迭代的对象为 Map 时, 该值为 Map 中的 Key.

    open: 循环开头的字符串

    close: 循环结束的字符串

    separator: 每次循环的分隔符

    2.5.2、可以批量插入

    插入数据是:同一个类型的集合/数组

    2.5.3、可以用在where in 后面

    2.6、 bind 标签

    bind 标签是通过 OGNL 表达式去定义一个上下文的变量, 这样方便我们使用。
    注意:在 MySQL 中, 该函数支持多参数, 但在 Oracle 中只支持两个参数。 那么我们可以使用 bind 来让该 SQL 达到支持两个数据库的作用

    <if test="name != null and name !=''">
         <bind name="nameLike" value="'%'+name+'%'"/>
         and name like #{nameLike}
    </if>
    
    展开全文
  • Mybatis的动态标签

    2015-11-29 02:06:00
    网址:http://www.360doc.com/content/14/0416/14/15113968_369456525.shtml 转载于:https://www.cnblogs.com/wql025/p/5003947.html

    网址:http://www.360doc.com/content/14/0416/14/15113968_369456525.shtml

    转载于:https://www.cnblogs.com/wql025/p/5003947.html

    展开全文
  • Mybatis 动态SQL标签

    2020-10-17 09:45:09
    Mybatis 动态SQL标签一、前言二、动态标签2.1 if 元素2.2 ...最近面试的时候被问到了几次Mybatis 的动态标签,今天就做一下整理。 二、动态标签 数据库准备: DROP DATABASE IF EXISTS `javacode2018`; CREATE DATABASE

    一、前言

    最近面试的时候被问到了几次Mybatis 的动态标签,有意想做一下整理。
    恰巧在CSDN app 上看到Mybatis系列第十讲 动态SQL,这么多种你都会?一文,个人觉得写得挺全的,故得到该博主的同意,转载至此并略作修改。

    二、动态标签

    数据库准备:

    DROP DATABASE IF EXISTS `javacode2018`;
    CREATE DATABASE `javacode2018`;
    
    USE `javacode2018`;
    
    DROP TABLE IF EXISTS t_user;
    CREATE TABLE t_user(
      id int AUTO_INCREMENT PRIMARY KEY COMMENT '用户id',
      name VARCHAR(32) NOT NULL DEFAULT '' COMMENT '用户名',
      age SMALLINT NOT NULL DEFAULT 1 COMMENT '年龄'
    ) COMMENT '用户表';
    INSERT INTO t_user VALUES (1,'路人甲Java',30),(2,'张学友',50),(3,'刘德华',50);
    

    2.1 if 元素

    相当于java 中的if 判断,语法:

    <if test="判断条件">
    	需要追加的sql
    </if>
    

    test 的值为一个判断表达式,写法上采用OGNL 表达式的方式,OGNL 在struts2 中用的比较多,本文暂时对ognl 不做详细介绍,有兴趣的可以去查一下相关资料。

    当test 成立的时候,if 体内部的sql 会被拼接上。如:

    <select id="getList1" resultType="com.javacode2018.chat05.demo8.model.UserModel" parameterType="map">
        SELECT id,name,age FROM t_user
        WHERE 1 = 1
        <if test="id!=null">
            AND id = #{id}
        </if>
        <if test="name!=null and name.toString()!=''">
            AND name = #{name}
        </if>
        <if test="age!=null">
            AND age = #{age}
        </if>
    </select>
    

    上面查询用户列表,参数为一个map,当map 中id 不为空的时候,将其作为条件查询,如果name 不为空,将name 也作为条件,如果age 不为空,将age 也作为条件进行查询。
    当只传入id 的时候,sql 如下:

    SELECT id,name,age FROM t_user WHERE 1 = 1 AND id = ? 
    

    当3 个参数都传了,sql 如下:

    SELECT id,name,age FROM t_user WHERE 1 = 1 AND id = ? AND name = ? AND age = ?
    

    上面这种写法相对于java 代码看起来是不是清爽了很多,也更方便维护。
    大家注意一下sql 中有个WHERE 1=1,如果没有这个,上面的样例单单通过if 元素就不好实现了,不过mybatis 也有对应的解决方案,稍后会说明。

    2.2 choose/when/otherwise 元素

    这个相当于java 中的if…else if…else,语法:

    <choose>
        <when test="条件1">
            满足条件1追加的sql
        </when>
        <when test="条件2">
            满足条件2追加的sql
        </when>
        <when test="条件n">
            满足条件n追加的sql
        </when>
        <otherwise>
            都不满足追加的sql
        </otherwise>
    </choose>
    
    • choose 内部的条件满足一个,choose 内部的sql 拼接就会结束
    • otherwise 属于可选的,当所有条件都不满足的时候,otherwise 将起效。

    choose 内部条件遵循最近匹配的原则,如:

    传入id、name、age 作为条件,按顺序进行判断,如果id 不为空,将id 作为条件,忽略其他条件;如果id 为空,会判断name 是否为空,name 不为空将name 作为条件;如果name 为空,再看age 是否为空,如果age 不为空,将age 作为条件。

    <select id="getList2" resultType="com.javacode2018.chat05.demo8.model.UserModel" parameterType="map">
        SELECT id,name,age FROM t_user
        WHERE 1 = 1
        <choose>
            <when test="id!=null">
                AND id = #{id}
            </when>
            <when test="name!=null and name.toString()!=''">
                AND name = #{name}
            </when>
            <when test="age!=null">
                AND age = #{age}
            </when>
        </choose>
    </select>
    
    

    如果id、name、age 都传了,sql 如下:

    SELECT id,name,age FROM t_user WHERE 1 = 1 AND id = ? 
    

    如果值传递了name、age,sql 如下:

    SELECT id,name,age FROM t_user WHERE 1 = 1 AND name = ? 
    

    name 的判断条件在age 前面,所以name 条件被匹配上了,其后面的age 条件就自动失效。

    2.3 where 元素

    上面2 个案例的sql 中都有【where 1=1】这部分代码,虽然可以解决问题,但是看起来不美观。但是如果将where 1=1 中1=1 这部分干掉,上面的两个案例又都会出问题,where后面会多一个AND符号。
    对于这个问题,mybatis 中通过where 元素来解决。
    当使用where 元素的时候,mybatis 会将where 内部拼接的sql 进行处理:
    将这部分sql 前面的AND 或者OR 给去掉,并在前面追加一个where。
    我们使用where 元素来对上面的案例1进行改造,如下:

    <select id="getList1" resultType="com.javacode2018.chat05.demo8.model.UserModel" parameterType="map">
        SELECT id,name,age FROM t_user
        <where>
            <if test="id!=null">
                AND id = #{id}
            </if>
            <if test="name!=null and name.toString()!=''">
                AND name = #{name}
            </if>
            <if test="age!=null">
                AND age = #{age}
            </if>
        </where>
    </select>
    

    where 1=1 被替换成了where 元素。

    当传入id、name的时候,where 内部的sql 会变成这样:

    AND id = ? AND name = ?
    

    mybatis 会对上面这个sql 进行处理,将前面的AND 给去掉,并在前面追加一个where,变成了下面这样

    where id = ? AND name = ?
    

    案例2 也用where 改造一下,变成了下面这样:

    <select id="getList2" resultType="com.javacode2018.chat05.demo8.model.UserModel" parameterType="map">
        SELECT id,name,age FROM t_user
        <where>
            <choose>
                <when test="id!=null">
                    AND id = #{id}
                </when>
                <when test="name!=null and name.toString()!=''">
                    AND name = #{name}
                </when>
                <when test="age!=null">
                    AND age = #{age}
                </when>
            </choose>
        </where>
    </select>
    

    这下看起来是不是舒服很多了。

    2.4 set 元素

    现在我们想通过用户id 更新用户信息,参数为UserModel 对象,对象中的属性如果不为空,就进行更新,我们可以这么写:

    <update id="update1" parameterType="com.javacode2018.chat05.demo8.model.UserModel">
        UPDATE t_user SET
        <if test="name!=null">
            name = #{name},
        </if>
        <if test="age!=null">
            age = #{age},
        </if>
        <where>
            <if test="id!=null">
                AND id = #{id}
            </if>
        </where>
    </update>
    

    我们来看一下,当所有属性都传值了,sql 变成了下面这样:

    UPDATE t_user SET name = ?, age = ?, where id = ?
    

    上面这个sql 是有问题的,where 前面多了一个逗号,得想办法将这个逗号去掉,这个逗号属于最后一个需要更新的字段后面的逗号,是多余的。
    mybatis 中提供了set 元素来解决这个问题,将上面的代码改成下面这样:

    <update id="update1" parameterType="com.javacode2018.chat05.demo8.model.UserModel">
        UPDATE t_user
        <set>
            <if test="name!=null">
                name = #{name},
            </if>
            <if test="age!=null">
                age = #{age},
            </if>
        </set>
        <where>
            <if test="id!=null">
                AND id = #{id}
            </if>
        </where>
    </update>
    

    我们将sql 中的set 去掉了,换成了set 元素。set 元素会对其内部拼接的sql 进行处理,会将这部分sql 前后的逗号给去掉并在前面加上set

    当传入id 和age 的时候,生成的sql :

    UPDATE t_user SET age = ? where id = ?
    

    2.5 trim 元素

    这个元素的功能比较强大,先看一下他的语法:

    <trim prefix="" prefixOverrides="" suffix="" suffixOverrides="">
    </trim>
    

    trim 元素内部可以包含各种动态sql,如where、chose、sql 等各种元素,使用trim 包含的元素,mybatis 的处理过程:

    1. 先对trim 内部的sql 进行拼接,比如这部分sql 叫做sql1
    2. 将sql1 字符串前面的部分中包含trim 的prefixOverrides 指定的部分给去掉,得到sql2
    3. 将sql2 字符串后面的部分中包含trim 的suffixOverrides 指定的部分给去掉,得到sql3
    4. 在sql3 前面追加trim 中prefix 指定的值,得到sql4
    5. 在sql4 后面追加trim 中suffix 指定的值,得到最终需要拼接的sql5

    了解了这个过程之后,我们使用trim 来改造一下案例1,如下:

    <select id="getList1" resultType="com.javacode2018.chat05.demo8.model.UserModel" parameterType="map">
        SELECT id,name,age FROM t_user
        <trim prefix="where" prefixOverrides="and|or">
            <if test="id!=null">
                AND id = #{id}
            </if>
            <if test="name!=null and name.toString()!=''">
                AND name = #{name}
            </if>
            <if test="age!=null">
                AND age = #{age}
            </if>
        </trim>
    </select>
    

    注意上面的prefixOverrides 的值的写法,如果有多个需要覆盖的之间用 | 进行分割,suffixOverrides 写法和prefixOverrides 的写法类似。

    我们在用trim 来改造一下上面的update,如下:

    <update id="update1" parameterType="com.javacode2018.chat05.demo8.model.UserModel">
        UPDATE t_user
        <trim prefix="SET" prefixOverrides="," suffixOverrides=",">
            <if test="name!=null">
                name = #{name},
            </if>
            <if test="age!=null">
                age = #{age},
            </if>
        </trim>
        <where>
            <if test="id!=null">
                AND id = #{id}
            </if>
        </where>
    </update>
    

    上面的prefixOverrides 和suffixOverrides 都设置的是逗号,表示trim 内部的sql 前后的逗号会被去掉,最后会在前面拼接一个prefix 指定的set。

    2.6 foreach 元素

    相当于java 中的循环,可以用来遍历数组、集合、map 等。

    语法:

    <foreach collection="需要遍历的集合" item="集合中当前元素" index="" open="" separator="每次遍历的分隔符" close="">
    	动态sql部分
    </foreach>
    
    • collection:可以是一个List、Set、Map 或者数组
    • item:集合中的当前元素的引用
    • index:用来访问当前元素在集合中的位置
    • separator:各个元素之间的分隔符
    • open 和close:用来配置最后用什么前缀和后缀将foreach 内部所有拼接的sql 给包装起来。

    案例:in 多值查询
    我们对案例1 做个改造,map 中支持放入用户的id 列表(ArrayList),对应的key 为idList,然后支持多个用户id 查询,此时我们需要用in 来查询,实现如下:

    <select id="getList1" resultType="com.javacode2018.chat05.demo8.model.UserModel" parameterType="map">
        SELECT id,name,age FROM t_user
        <where>
            <if test="id!=null">
                AND id = #{id}
            </if>
            <if test="name!=null and name.toString()!=''">
                AND name = #{name}
            </if>
            <if test="age!=null">
                AND age = #{age}
            </if>
            <if test="idList!=null and idList.size()>=1">
                <foreach collection="idList" item="id" open="AND id in (" separator="," close=")">
                    #{id}
                </foreach>
            </if>
        </where>
    </select>
    

    大家看一下上面idList 那部分判断,判断这个参数不为空,并且size() 大于1,表示这个集合不为空,然后会使用if 元素内部的foreach 元素。

    比如我们传递的idList 对应的是[1,2],最后产生的sql 如下:

    SELECT id,name,age FROM t_user WHERE id in ( 1 , 2 ) 
    

    案例:批量插入
    传入UserModel List 集合,使用foreach 实现批量插入,如下:

    <insert id="insertBatch" parameterType="list">
        INSERT INTO t_user (id,name,age) VALUES
        <foreach collection="collection" separator="," item="item">
            (#{item.id}, #{item.name}, #{item.age})
        </foreach>
    </insert>
    

    测试用例

    @Test
    public void insertBatch() throws IOException {
        try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<UserModel> userModelList = new ArrayList<>();
            for (int i = 0; i < 3; i++) {
                userModelList.add(UserModel.builder().id(10 + i).name("mybatis-" + i).age(20 + i).build());
            }
            int count = mapper.insertBatch(userModelList);
            log.info("{}", count);
        }
    }
    

    传入了3个用户信息,运行输出

    39:52.241 [main] DEBUG c.j.c.d.m.UserMapper.insertBatch - ==>  Preparing: INSERT INTO t_user (id,name,age) VALUES (?, ?, ?) , (?, ?, ?) , (?, ?, ?) 
    39:52.317 [main] DEBUG c.j.c.d.m.UserMapper.insertBatch - ==> Parameters: 10(Integer), mybatis-0(String), 20(Integer), 11(Integer), mybatis-1(String), 21(Integer), 12(Integer), mybatis-2(String), 22(Integer)
    39:52.327 [main] DEBUG c.j.c.d.m.UserMapper.insertBatch - <==    Updates: 3
    39:52.327 [main] INFO  c.j.chat05.demo8.Demo8Test - 3
    

    2.7 sql/include 元素

    这两个元素一般进行配合使用,可以实现代码重用的效果。

    sql 元素可以用来定义一段动态sql ,语法如下:

    <sql id="sql片段id">
    	各种动态sql
    </sql>
    

    其他地方需要使用的时候需要通过include 关键字进行引入:

    注意refid 值的写法:
    refid的值为mapper xml 的namespace 的值.sql_id,如果在同一个mapper 中,namespace 可以省略,直接写对应的sql_id 就可以了,如:

    <include refid="findSql"/>
    <include refid="com.javacode2018.chat05.demo8.mapper.UserMapper.findSql"/>
    

    案例:

    下面定义2 个查询,他们的查询条件一样,最后将条件抽出来用sql 元素定义了一个片段,然后进行共用。

    <sql id="findSql">
        <where>
            <if test="id!=null">
                AND id = #{id}
            </if>
            <if test="name!=null and name.toString()!=''">
                AND name = #{name}
            </if>
            <if test="age!=null">
                AND age = #{age}
            </if>
            <if test="idList!=null and idList.size()>=1">
                <foreach collection="idList" item="id" open="AND id in (" separator="," close=")">
                    #{id}
                </foreach>
            </if>
        </where>
    </sql>
    
    <select id="getList1" resultType="com.javacode2018.chat05.demo8.model.UserModel" parameterType="map">
        SELECT id,name,age FROM t_user
        <include refid="com.javacode2018.chat05.demo8.mapper.UserMapper.findSql" />
    </select>
    
    <select id="getList1Count" resultType="com.javacode2018.chat05.demo8.model.UserModel" parameterType="map">
        SELECT count(*) FROM t_user
        <include refid="findSql" />
    </select>
    

    2.8 bind元素

    bind 元素允许我们通过ognl 表达式在上下文中自定义一个变量,最后在动态sql 中可以使用这个变量。

    语法:

    <bind name="变量名称" value="ognl表达式">
    

    案例:

    对sql、include 中的案例进行扩展,添加一个按照用户名模糊查询,用户名在map 中对应的key 为likeName,主要修改上面sql 片段部分,在sql 中加入下面部分:

    <if test="likeName!=null and likeName.trim()!=''">
      <bind name="nameLike" value="'%'+likeName.trim()+'%'" />
      AND name like #{nameLike}
    </if>
    

    先判断传入的参数likeName是否不为空字符串,然后使用bind元素创建了一个变量nameLike,值为’%’+likeName.trim()+’%’。

    对应的测试用例:

    @Test
    public void getModelList() throws IOException {
        try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("likeName","java");
            List<UserModel> userModelList = mapper.getList1(paramMap);
            log.info("{}", userModelList);
        }
    }
    

    运行输出:

    06:25.633 [main] DEBUG c.j.c.d.mapper.UserMapper.getList1 - ==>  Preparing: SELECT id,name,age FROM t_user WHERE name like ? 
    06:25.671 [main] DEBUG c.j.c.d.mapper.UserMapper.getList1 - ==> Parameters: %java%(String)
    06:25.690 [main] DEBUG c.j.c.d.mapper.UserMapper.getList1 - <==      Total: 1
    06:25.691 [main] INFO  c.j.chat05.demo8.Demo8Test - [UserModel(id=1, name=路人甲Java, age=31)]
    

    注意输出中的第二部分,参数的值为%java%。

    三、# 和$

    3.1 区别

    3.1.1 处理方式

    对于#,mybatis 使用的是预编译,在处理#{}时,会将sql 中的#{} 替换为? 号,调用PreparedStatement 的set 方法来赋值。
    对于$,mybatis 不会修改或者转义字符,直接输出变量值

    3.1.2 参数是字符串

    #会对传入的字符数据加一个双引号​。
    $将传入的数据直接显示生成在sql 中​,适合于动态排序(动态字段)

    order by ${value} asc
    

    3.1.1 参数含义

    #{任意值}​,{ }中的值只是一个变量名,并无特殊含义。
    ${value} ,其中的标识符只能是value​,即将要传入sql 的值。

    3.1.1 防止Sql 注入

    #方式能够很大程度防止Sql 注入​。

    $方式无法防止Sql 注入​。

    3.2 ${} 的用法

    #{} 的用法上面已经有很多案例了,此处我们来一个${} 的案例。

    下面通过orderSql 变量传入任意的排序sql,如下:

    <select id="getList1" resultType="com.javacode2018.chat05.demo8.model.UserModel" parameterType="map">
        SELECT id,name,age FROM t_user
        <if test="orderSql">
            ${orderSql}
        </if>
    </select>
    

    传入值:

    orderSql = "order by id asc,age desc"
    

    最后运行产生的sql 如下:

    20:32.138 [main] DEBUG c.j.c.d.mapper.UserMapper.getList1 - ==>  Preparing: SELECT id,name,age FROM t_user order by id asc,age desc 
    20:32.173 [main] DEBUG c.j.c.d.mapper.UserMapper.getList1 - ==> Parameters: 
    20:32.196 [main] DEBUG c.j.c.d.mapper.UserMapper.getList1 - <==      Total: 6
    20:32.197 [main] INFO  c.j.chat05.demo8.Demo8Test - [UserModel(id=1, name=路人甲Java, age=31), UserModel(id=2, name=张学友, age=50), UserModel(id=3, name=刘德华, age=50), UserModel(id=10, name=mybatis-0, age=20), UserModel(id=11, name=mybatis-1, age=21), UserModel(id=12, name=mybatis-2, age=22)]
    

    mybatis 会对$ 包含部分直接进行sql 替换。

    至此,本文结束。我是陈冰安,一个Java学习者。欢迎关注我的公众号【暗星涌动】,愿与你一同进步。

    展开全文
  • mybatis常用动态标签

    千次阅读 2017-09-30 13:37:44
    mybatis常用的动态标签 1,用来循环容器的标签foreach 1 //mapper中我们要为这个方法传递的是一个容器,将容器中的元素一个一个的 2 //拼接到xml的方法中就要使用这个forEach这个标签了 3 public List ...

    mybatis常用的动态标签


    • if
    • choose(when,otherwise)
    • trim
    • where
    • set
    • foreach等

    1,用来循环容器的标签foreach

    复制代码
     1 //mapper中我们要为这个方法传递的是一个容器,将容器中的元素一个一个的
     2 //拼接到xml的方法中就要使用这个forEach这个标签了
     3 public List<Entity> queryById(List<String> userids);
     4 
     5 //对应的xml中如下
     6   <select id="queryById" resultMap="BaseReslutMap" >
     7       select * FROM entity
     8       where id in 
     9       <foreach collection="userids" item="userid" index="index" open="(" separator="," close=")">
    10               #{userid}
    11       </foreach>
    12   </select>
    复制代码

    2,concat模糊查詢

    复制代码
    <!-- 比如说我们想要进行条件查询,但是几个条件不是每次都要使用,那么我们就可以-->
    <!--通过判断是否拼接到sql中-->
      <select id="queryById" resultMap="BascResultMap" parameterType="entity">
        SELECT *  from entity
        <where>
            <if test="name!=null">
                name like concat('%',concat(#{name},'%'))
            </if>
        </where>
      </select>
    复制代码

     

    3,choose(when,otherwise)标签

    复制代码
    <!--  choose(判断参数) - 按顺序将实体类 User 第一个不为空的属性作为:where条件 -->  
    <select id="getUserList_choose" resultMap="resultMap_user" parameterType="com.yiibai.pojo.User">  
        SELECT *  
          FROM User u   
        <where>  
            <choose>  
                <when test="username !=null ">  
                    u.username LIKE CONCAT(CONCAT('%', #{username, jdbcType=VARCHAR}),'%')  
                </when >  
                <when test="sex != null and sex != '' ">  
                    AND u.sex = #{sex, jdbcType=INTEGER}  
                </when >  
                <when test="birthday != null ">  
                    AND u.birthday = #{birthday, jdbcType=DATE}  
                </when >  
                <otherwise>  
                </otherwise>  
            </choose>  
        </where>    
    </select> 
    复制代码

    4,selectKey标签

    复制代码
    <!-- 插入学生 自动主键-->  
    <insert id="createStudentAutoKey" parameterType="liming.student.manager.data.model.StudentEntity" keyProperty="studentId">  
        <selectKey keyProperty="studentId" resultType="String" order="BEFORE">  
            select nextval('student')  
        </selectKey>  
        INSERT INTO STUDENT_TBL(STUDENT_ID,  
                                STUDENT_NAME,  
                                STUDENT_SEX,  
                                STUDENT_BIRTHDAY,  
                                STUDENT_PHOTO,  
                                CLASS_ID,  
                                PLACE_ID)  
        VALUES (#{studentId},  
                #{studentName},  
                #{studentSex},  
                #{studentBirthday},  
                #{studentPhoto, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler},  
                #{classId},  
                #{placeId})  
    </insert>  
    复制代码

    5,if标签

    if标签可用在许多类型的sql语句中,我们以查询为例。首先看一个很普通的查询:

    <!-- 查询学生list,like姓名 -->  
    <select id="getStudentListLikeName" parameterType="StudentEntity" resultMap="studentResultMap">  
        SELECT * from STUDENT_TBL ST   
    WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')  
    </select>  

    但是此时如果studentName为null,此语句很可能报错或查询结果为空。此时我们使用if动态sql语句先进行判断,如果值为null或等于空字符串,我们就不进行此条件的判断,增加灵活性。

    参数为实体类StudentEntity。将实体类中所有的属性均进行判断,如果不为空则执行判断条件。

    复制代码
    <!-- 2 if(判断参数) - 将实体类不为空的属性作为where条件 -->  
    <select id="getStudentList_if" resultMap="resultMap_studentEntity" parameterType="liming.student.manager.data.model.StudentEntity">  
        SELECT ST.STUDENT_ID,  
               ST.STUDENT_NAME,  
               ST.STUDENT_SEX,  
               ST.STUDENT_BIRTHDAY,  
               ST.STUDENT_PHOTO,  
               ST.CLASS_ID,  
               ST.PLACE_ID  
          FROM STUDENT_TBL ST   
         WHERE  
        <if test="studentName !=null ">  
            ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%')  
        </if>  
        <if test="studentSex != null and studentSex != '' ">  
            AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}  
        </if>  
        <if test="studentBirthday != null ">  
            AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}  
        </if>  
        <if test="classId != null and classId!= '' ">  
            AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR}  
        </if>  
        <if test="classEntity != null and classEntity.classId !=null and classEntity.classId !=' ' ">  
            AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR}  
        </if>  
        <if test="placeId != null and placeId != '' ">  
            AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR}  
        </if>  
        <if test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' ">  
            AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR}  
        </if>  
        <if test="studentId != null and studentId != '' ">  
            AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR}  
        </if>   
    </select>  
    复制代码

    6,if+set实现修改语句

    当update语句中没有使用if标签时,如果有一个参数为null,都会导致错误。 
    当在update语句中使用if标签时,如果前面的if没有执行,则或导致逗号多余错误。使用set标签可以将动态的配置SET 关键字,和剔除追加到条件末尾的任何不相关的逗号。使用if+set标签修改后,如果某项为null则不进行更新,而是保持数据库原值。如下示例:

    复制代码
    <!-- 4 if/set(判断参数) - 将实体类不为空的属性更新 -->  
    <update id="updateStudent_if_set" parameterType="liming.student.manager.data.model.StudentEntity">  
        UPDATE STUDENT_TBL  
        <set>  
            <if test="studentName != null and studentName != '' ">  
                STUDENT_TBL.STUDENT_NAME = #{studentName},  
            </if>  
            <if test="studentSex != null and studentSex != '' ">  
                STUDENT_TBL.STUDENT_SEX = #{studentSex},  
            </if>  
            <if test="studentBirthday != null ">  
                STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},  
            </if>  
            <if test="studentPhoto != null ">  
                STUDENT_TBL.STUDENT_PHOTO = #{studentPhoto, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler},  
            </if>  
            <if test="classId != '' ">  
                STUDENT_TBL.CLASS_ID = #{classId}  
            </if>  
            <if test="placeId != '' ">  
                STUDENT_TBL.PLACE_ID = #{placeId}  
            </if>  
        </set>  
        WHERE STUDENT_TBL.STUDENT_ID = #{studentId};      
    </update>  
    复制代码
    展开全文
  • 一步一步学完MyBatis的动态sql标签

    千次阅读 多人点赞 2020-06-03 23:21:20
    图文并茂+例子解析,全面理解MyBatis的动态sql标签
  • 主要介绍了Mybatis动态sql标签的使用,文中通过示例代码介绍非常详细,对大家学习或者工作具有一定参考学习价值,需要朋友们下面随着小编来一起学习学习吧
  • ResultMap (1)ResultMap有什么用? 建立查询字段与实体类成员变量映射关系 即 查询字段是user_id但是Mybatis去赋值... id:ResultMap标识,标签语句中 resultMap值必须和该id一致 type:指定你要映射哪一个Jav
  • MyBatis是一个支持普通SQL查询,存储过程和高级映射优秀持久层框架,MyBatis越来越受大家喜爱了。下面给大家分享MyBatis使用动态SQL标签的小陷阱,感兴趣朋友一起看看吧
  • MyBatis 的强大特性之一便是它的动态 SQL,即拼接SQL字符串。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名...
  • mybatis的动态sql标签

    2017-05-16 09:46:10
    mybatis的动态sql 标签 1. 拼接的sql 2. and ... and ... 说明:where标签在最后会将第一个条件的"and"给去掉,以防止sql拼写异常 3. ..., ..., 说明:set标签在最后会将最后一...
  • Mybatis的动态sql标签

    2017-07-05 17:04:02
    动态SQL通过Mybatis提供各种动态标签实现动态拼接sql,使得mapper映射文件在编写SQL时更加灵活,方便。常用动态SQL标签有:if、where、foreach; If标签:作为判断入参来使用,如果符合条件,则把if标签体内...
  • MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。...
  • mybatis动态sql标签

    2019-03-12 15:47:11
    mybatis动态sql标签if标签where标签sql片段标签foreach标签trim标签背景1、prefix属性:在trim开始部分添加内容2、suffix属性:在trim结束部分添加内容3.prefixOverrides属性:去除trim开始部分内容4、...
  • 前提:建议配置mybatis的执行sql打印功能 或这种形式 mybatis动态sql可以在mapper.xml映射文件...动态标签: trim,where,set,foreach,if,choose,when,otherwise,bind 注意: 1.<where>与<if>配合使用,当...
  • 本文通过实例代码给大家介绍了MyBatis动态SQL标签用法,非常不错,具有参考借鉴价值,需要朋友参考下吧
  • 熟悉mybatis的都知道,mybatis的动态标签where加载时机是当条件有值的时候,如mybatis的官方文档的介绍一样,mybatis的where相当于以下trim(mybatis官方文档内容) 但是最近写代码的时候遇到了问题,分明使用了...
  • 使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。 如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能
  • 一、问题: <if test="carrier != null and carrier !='' and carrier !='0'"> AND CARRIER = #{carrier} <...mybatis是用OGNL表达式来解析,在OGNL表达式中,'0’会被解析成字符,jav
  • Mybatis的动态SQL标签

    2020-08-19 09:02:22
    if标签 foreach标签 sql标签
  • MyBatis动态SQL标签

    千次阅读 2016-05-31 22:45:50
    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。 MyBatis中用于实现动态SQL的元素主要有:   ifchoose(when,otherwise)trimwheresetforeach if就是简单的条件...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,787
精华内容 1,114
关键字:

mybatis的动态标签