Dynamic sql splicing in mybatis

Posted by c-o-d-e on Sat, 20 Jun 2020 18:12:19 +0200

Before moving on to dynamic sql, let's start by saying that a user's id in real development is usually out of order, such as random generation using UUID s. Write one below.

public class UUIDGenerate {
   
    public static String getIdByUUID(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }
}

It is well known that we will encounter a kind of splicing problem in the development, such as search box, user's choice of unused labels for query, etc. The problems we often encounter are and,',', and so on. And in the second select statement, if the user does not select the first one, and X=
#{X}, so that sql statements will fail, we must consider this situation to exclude and, which can be cumbersome in previous development, but is convenient in mybatis.
Look at pojo first

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Blog {
    private String id;
    private String title;
    private String author;
    private Date createTime;//Note that the attribute name here is different from the field name of the database
    private Integer views;

}

Here's about the opening of hump naming in mybatis
<setting name="mapUnderscoreToCamelCase" value="true"/>

public interface BlogMapper {

    int addBook(Blog blog);

    List<Blog> queryBlogByIf(Map map);

    List<Blog> queryBlogByChoose(Map map);

    int updateBlogBySet(Map map);

    List<Blog> queryBlogByForEach(Map map);
}

Solve the and problem in that where

   <!-- this sql Labels are packages of statements so that they can be referenced below-->
    <sql id="if-title-author">

        <if test="title!=null">
            and title=#{title}
        </if>
        <if test="author!=null">
            and author=#{author}
        </if>
    </sql>
    <!--/*This is to use this include for reference*/-->
    <select id="queryBlogByIf" parameterType="map" resultType="blog">
        select * from blog
        <where>

        <include refid="if-title-author"></include>
        </where>

    </select>

Encapsulation is used in this piece of code, thereby using a reference to encapsulated code
<sql>This is used to wrap code, typically those if tags
<include refid="if-title-author"></include>This is used to insert encapsulated code

    <select id="queryBlogByChoose" parameterType="map" resultType="blog">

        select * from blog
        <where>
            <choose>
                <when test="id!=null">
                    id=#{id}
                </when>
                <when test="title!=null">
                    and title=#{title}
                </when>
                <when test="author!=null">
                    and author=#{author}
                </when>
                <otherwise>
                    and views=#{views}
                </otherwise>

            </choose>


        </where>

    </select>

This uses the select, when, otherwise tags. This means that the switch, case, default method will only execute one

  <update id="updateBlogBySet" parameterType="map">
    update blog
    <set>
        <if test="title!=null">
            title=#{title},
        </if>
        <if test="author!=null">
            author=#{author},
        </if>
        <if test="views!=null">
            views=#{views}
        </if>
    </set>
        where id=#{id};
    </update>

The <set>tag is used in the update statement to handle subsequent comma problems
Of course, the above <set>implements a tag for handling commas as as well.

    <insert id="addBook" parameterType="blog">

insert into blog

<trim prefix="(" suffix=")" suffixOverrides=",">
    <if test="id!=null">
        id,
    </if>
    <if test="title!=null">
        title,
    </if>
    <if test="author!=null">
        author,
    </if>
    <if test="createTime!=null">
        create_time,
    </if>
    <if test="views!=null">
        views
    </if>
</trim>

        <trim prefix="VALUES(" suffix=")" suffixOverrides=",">
            <if test="id!=null">
                #{id},
            </if>
            <if test="title!=null">
                #{title},
            </if>
            <if test="author!=null">
                #{author},
            </if>
            <if test="createTime!=null">
                #{createTime},
            </if>
            <if test="views!=null">
                #{views}
            </if>
        </trim>


    </insert>

The last tag is the one traversed by <foreach>

 <select id="queryBlogByForEach" parameterType="map" resultType="blog">
        select * from blog
        <where>
            <foreach collection="ids" item="id" open="and (" close=")" separator="or">

                id=#{id}
            </foreach>

        </where>
    </select>

It implements queries like this

select * from student where 1=1 and (id=1 or id=2 or id=3);
One such query method is to query according to your needs
 Why add 1 = 1 to ensure that you get all the results if you null later or if something goes wrong

The <where>tag in mybatis has a meaning of 1=1, so don't think about it, just the ones that follow

<foreach collection="ids" item="id" open="and (" close=")" separator="or">
From this tag we can see that we need to call this list ids, and each of them is called item (which is very similar to traversal in jsp), what opens start with, what close s end with, and what we should pay attention to is the and inside opens (don't connect, there are spaces in between!!!!
The last separator is what separates these, and we use or.

Topics: SQL Mybatis Attribute Database