Mybatis learning (C) - Dynamic SQL


If we have a complex business, we need a more complex SQL statements, often require stitching, and stitching SQL statements, little attention because of the quotes, such as lack of space will lead to error, and Mybatis provide dynamic SQL statements SQL makes stitching becomes easily.

Dynamic SQL or similar elements and JSTL XML-like text-based processor. In previous versions of MyBatis, there are many elements need to take time to understand. MyBatis 3 greatly streamlined the element type, are only half of the original elements can learn. MyBatis employs powerful OGNL based expressions to eliminate most of the other elements

1, if the label

if statement applies if the label inside java and we are the same, the following code in the test is to determine the expression, when determining whether the conditions established back

<select id="getStu" parameterType="com.tulun.bean.Student" resultType="com.tulun.bean.Student">
        select * from student
        where
        <if test="id != null">
            id = #{id}
        </if>
        <if test="name != null &amp;&amp; name != &quot;&quot;">
            and name = #{name}
        </if>
    </select>
@Test
    public void test(){
        StudentDynamicSql mapper = session.getMapper(StudentDynamicSql.class);
        Student stu = mapper.getStu(new Student(1, "", "123456"));
        System.out.println(stu);
    }

Here Insert Picture Description
From the results, the second tag if the statement is not true, and finally we generated SQL statements nor the second condition.

2, where the label

Or the above example, this time we set the id to null to see what happens?

@Test
    public void test(){
        StudentDynamicSql mapper = session.getMapper(StudentDynamicSql.class);
        Student stu = mapper.getStu(new Student(null, "wjm", "123456"));
        System.out.println(stu);
    }

Here Insert Picture Description
It throws an exception and print out a bunch of logs as follows, when the first condition is not satisfied, this mosaic statement by the problem. Here I have to say about the label.
Label is our SQL statement where, if where sql statement, then when the first condition is not met, then the front and rear of the conditions will be a plus and, SQL statements will be mistakes, if the latter statement is generated for to begin with and or or, then the tag will automatically get the beginning of the take down and, or.
We modify the mapping file, or the id set to null, we look at what happens?

<select id="getStu" parameterType="com.tulun.bean.Student" resultType="com.tulun.bean.Student">
        select * from student
        <where>
            <if test="id != null">
                id = #{id}
            </if>
            <if test="name != null &amp;&amp; name != &quot;&quot;">
                and name = #{name}
            </if>
        </where>
    </select>

Here Insert Picture Description
SQL statements generated no problem, the statement to help us dispose of the front and

3, trim label

and where not dispose of or behind other elements, are also provided herein mybatis another tag, which tag is provided so few elements

element Features
prefix To add a string of splicing prefix can add any value where, set, etc.
suffix To the character after stitching add a suffix
prefixOverrides Override prefix in front of the tag body in excess characters removed
suffixOverride Suffix cover, the excess label material in the later characters removed

By labeling, we can write the original code like this

 <select id="getStu" parameterType="com.tulun.bean.Student" resultType="com.tulun.bean.Student">
        select * from student
        <trim prefix="where" suffixOverrides="and">
            <if test="id != null">
                id = #{id} and
            </if>
            <if test="name != null &amp;&amp; name != &quot;&quot;">
                name = #{name}
            </if>
        </trim>
    </select>

Here Insert Picture Description

4, choose the label

choose: (when, otherwise) branch selection, with the equivalent of a switch case break
when: the equivalent of Case
otherwise: the equivalent of default
will only enter one, if conditions are not met entered otherwise, then the above example we can change again a bit.

    <select id="getStu" parameterType="com.tulun.bean.Student" resultType="com.tulun.bean.Student">
        select * from student
        <trim prefix="where" suffixOverrides="and">
            <choose>
              <when test="id != null">
                  id = #{id}
              </when>
              <when test="name != null &amp;&amp; name != &quot;&quot;">
                  name = #{name}
              </when>
              <otherwise>
                  pssward = #{passward}
              </otherwise>
            </choose>
        </trim>
    </select>
@Test
    public void test(){
        StudentDynamicSql mapper = session.getMapper(StudentDynamicSql.class);
        Student stu = mapper.getStu(new Student(null, "", "wjmpwd"));
        System.out.println(stu);
    }

Look at what happened.
Here Insert Picture Description
In the case of the two conditions are not met the label, enter the label otherwise.

5, foreach tag

Another commonly used dynamic SQL operation demand is set to traverse a, usually when building IN conditional statement.
foreach tag of several parameters

parameter Features
collection Specifies the collection to traverse
List List special handling type parameter encapsulated in the map, map the key list is called
item The current traversing the elements assigned to the variable specified
separator Separator between each element
open All the characters traverse a result of splicing begins
close All the characters traverse a result of the end of the stitching

Now we re-write an interface and look for student information by batch id

    /**
     * 批量获取学生信息
     * @param list
     * @return
     */
    public List<Student> getStus(List<Integer> list);
<select id="getStus" parameterType="com.tulun.bean.Student" resultType="com.tulun.bean.Student">
        select * from student
        <trim prefix="where">
           id in
           <foreach collection="list" item="item" open="(" close=")" separator=",">
               #{item}
           </foreach>
        </trim>
    </select>

    @Test
    public void test(){
        StudentDynamicSql mapper = session.getMapper(StudentDynamicSql.class);
       /**
         * 批量获取学生信息
         */
        List<Student> stus = mapper.getStus(Arrays.asList(1, 2, 3, 4));
        for (Student stu:stus){
            System.out.println(stu);
        }
   }

Here Insert Picture Description
Finally, the generated SQL statement is select * from student where id in ( ?,?,?,?).
We analyze,

  • collection: our approach is that list of parameters
  • item: each cycle of the extracted data into this variable
  • open: open string loop start stitching, in our SQL statement it is "("
  • close:循环结束拼接的字符串,在我们这个SQL语句中就是“)”
  • separator:就是遍历过程中每个元素之间的分割符

你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给 foreach 作为集合参数。collection是传入的可迭代对象参数。当使用可迭代对象或者数组时,index 是当前迭代的次数,item 的值是本次迭代获取的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

6、两个内置参数

① _parameter: 代表整个参数

  • 单个参数:_parameter 就是这个参数
  • 多个参数:参数会被封装成map,_parameter就代表这个map。当多个参数时,可以通过_parameter.get(0)来获取参数
    获取单个学生那个例子,我们继续修改它
 <select id="getStu" parameterType="com.tulun.bean.Student" resultType="com.tulun.bean.Student">
        select * from student
          <if test="_parameter != null">
              <trim prefix="where">
                 <choose>
                     <when test="id != null">
                         id = #{_parameter.id}
                     </when>
                     <when test="name != null &amp;&amp; name !=  &quot;&quot;">
                         id = #{_parameter.name}
                     </when>
                     <otherwise >
                         pssward = #{_parameter.passward}
                     </otherwise>
                 </choose>
              </trim>
          </if>
    </select>

Here Insert Picture Description
② _databaesId:如果配置了这个_databaesIdProvider标签,_databaesId 就是代表当前数据库的别名

7、bind

绑定一个表达式给一个变量,可以用这个变量来代替这个表达式
我们增加一个这样的接口

public Student getStu2();
<select id="getStu2" resultType="com.tulun.bean.Student">
        <bind name="n" value="'wjm'"></bind>
        select * from student where name = #{n}
    </select>

我们将"wjm" 这个表达式绑定给了n这个变量,表示在后面我们可以通过n这个变量来代替wjm,看看结果吧!
Here Insert Picture Description

8、sql 标签和include标签

① sql标签:抽取可重用的sql片段,方便后面使用
② include:引用已经抽取的sql 查询,还可以定义一些property ,sql标签内部就能使用自定义的属性,使用${property}引用
我们来看一个小例子,修改一下我们刚刚写的那个方法。

 	<sql id="l">
        id,name,pssward
    </sql>
    
    <select id="getStu2" resultType="com.tulun.bean.Student">
        <bind name="n" value="'wjm'"></bind>
        select
        <include refid="l"/>
        from student where name = #{n}
    </select>

看看结果
Here Insert Picture Description

Summarize
actually write dynamic sql statement is often a mosaic of the problem, in order to ensure accurate splicing, we'd better first to write sql statement native out, and then change the shining through mybatis dynamic sql, prevent errors in.

Guess you like

Origin blog.csdn.net/Alyson_jm/article/details/91977338