Use Mybatis’ dynamic SQL to solve the problem of uncertain parameter transmission


In the previous article: Basic CRUD and detailed analysis of query operations for Mybatis database operations_@ Confused Blog-CSDN Blog introduced Mybatis's use of fixed SQL statements to operate data. This article introduces a powerful feature of Mybatis: dynamic SQL.

What problem does dynamic SQL solve?

        Then when we have a lot of business logic to execute, such as inserting a row of data into the score table, and the "gender" field corresponding to the student is a non-required parameter, using dynamic SQL does not require writing two insertion statements (passing gender or not);

        In addition, when executing query logic, the number of parameters in the condition is also uncertain.

        The above situations where the incoming parameters are uncertain can be solved by using dynamic SQL.


1. <if> tag:

         The <if> tag can be used to determine whether the parameters meet the expected values, thereby determining the splicing of SQL statements;

        The following assumes that a row of data is to be inserted into the student table. The sex attribute value in the entity class corresponding to the student's sex field is null. Use the <if> tag to determine whether to insert sex during insertion:

Maper interface: 

@Mapper
public interface StudentMapper {
    // 新增学生信息
    int addStu(Student student);
}

 Insert statement:

<mapper namespace="com.example.demo.mapper.StudentMapper">
    <insert id="addStu">
        insert into student (uid, name
        <if test="sex != null and sex != '' ">
            ,sex
        </if>
        ,score
        ) values (#{uid}, #{name}
        <if test="sex != null and sex != '' ">
            ,#{sex}
        </if>
        ,#{score})
    </insert>
</mapper>

 Test Methods:

@SpringBootTest
class StudentMapperTest {
    @Autowired
    private StudentMapper studentMapper;

    @Transactional
    @Test
    void addStu() {
        Student student = new Student();
        student.setUid(1);
        student.setName("张三");
        student.setScore(98);
        // 传入的实体对象中不包含 sex
        int result = studentMapper.addStu(student);
        System.out.println("插入成功:" + result);
    }
}

! ! ! Pay attention to distinguishing attributes and fields when using them:

What needs to be judged in test is the "attribute" - from the entity class object;

The others are fields - corresponding to the database;


2. <trim> tag:

        The <trim> tag is also used in conjunction with the <if> tag, which literally means "trim".

        When there are many non-required parameters in the SQL statement, once only a few of them are passed, residual commas or parentheses will result, causing an error in the SQL statement; the <trim> tag will remove the remaining unnecessary parameters based on the actual situation. Content.

Four parameters of the <trim> tag:

        Can be added according to the scene

  • prefix: represents the entire statement block, prefixed by the value of prefix
  • suffix: represents the entire statement block, with the value of suffix as the suffix
  • prefixOverrides: indicates the prefix to be removed from the entire statement block
  • suffixOverrides: Indicates the suffixes to be removed from the entire statement block

The following demonstration: inserting a piece of student information, but passing only the student name as a parameter will result in an extra comma after the field. At the same time, if the parameters are not passed, there will be an extra pair of brackets. Use trim to modify:

Mapper interface: 

@Mapper
public interface StudentMapper {
    // 只插入学生姓名
    int addStuOnlyName(Student student);
}

SQL statement:

    <insert id="addStuOnlyName">
        insert into student
            <trim prefix="(" suffix=")" suffixOverrides=",">
                <if test="uid != null and uid != '' ">
                    uid,
                </if>
                <if test="name != null and name != '' ">
                    name,
                </if>
                <if test="sex != null and sex != '' ">
                    sex,
                </if>
                <if test="score != null and score != '' ">
                    score
                </if>
            </trim>
        values
            <trim prefix="(" suffix=")" suffixOverrides=",">
                <if test="uid != null and uid != '' ">
                    #{uid},
                </if>
                <if test="name != null and name != '' ">
                    #{name},
                </if>
                <if test="sex != null and sex != '' ">
                    #{sex},
                </if>
                <if test="score != null and score != '' ">
                    #{score}
                </if>
            </trim>
    </insert>

unit test:

@Test
    void addStuOnlyName() {
        Student student = new Student();
        student.setName("李四");
        int result = studentMapper.addStuOnlyName(student);
        System.out.println("插入成功:" + result);
    }

 


3. <where> tag:

        Directly use the example to demonstrate: query a student information based on the student uid or student name. The two query conditions here are optional.

        ① If only one of the conditions is given during the query, then the "and" in the connection after where will be added;

        ② If neither condition is used, then "where" will be added;

For the first case: you can use the <trim> tag to remove the suffix and, and place it after the parameter;

For the second situation: there are many solutions:

  1. Add 1=1 after where, and put and in front of each condition parameter, use <trim> to remove the prefix and;
            ( But this way of writing is very redundant and not a good idea)

  2. where is used as the prefix of the <trim> tag. Only if there is code in <trim>, the prefix where will be automatically added, and then the and will be removed according to the suffix removal method;

  3. Use the <where> tag to specifically solve this scenario:
        If there is content in <where>, where will be automatically generated, and if there is no content, it will not be generated.
    ​​​​​​​​​​​​​ At the same time: if there are extra and, it will also
    be removed in the same way as prefix removal.

            

 


4. <set> tag:

        The <set> tag is used to modify the scene. The <set> tag also wraps all parameters. If there is no content, no set will be added. However, it is wrong for MySQL to not have a set statement, so at least one parameter must be passed.

        <set> will automatically remove extra commas

    <update id="updateStu">
        update student
        <set>
            <if test="uid != null and uid > 0">
                uid = #{uid},
            </if>
            <if test="name != null and name != '' ">
                name = #{name},
            </if>
            <if test="sex != null and sex != '' ">
                sex = #{sex},
            </if>
            <if test="score != null and score > 0">
                score = #{score}
            </if>
        </set>
        where uid = #{uid}
    </update>

5. <foreach> tag:

        The <foreach> tag is used to traverse the passed collection. It has five options:

  1. collection: the collection in the bound method parameter, such as List, Set, Map or array object
  2. item: each object during traversal
  3. open: the string at the beginning of the statement block
  4. close: the string that ends the statement block
  5. separator: the string that separates the objects traversed each time
    // 根据 uid 批量删除
    int deleteByUids(List<Integer> uidList);
    <delete id="deleteByUids">
        delete from student
        where uid in
        <foreach collection="uidList" item="uid" open="(" close=")" separator=",">
            #{uid}
        </foreach>
    </delete>

 

Guess you like

Origin blog.csdn.net/m0_65190367/article/details/131915543