【8】Mybatis动态sql【if、where、set、choose(when,otherwise)】

13, dynamic SQL

What is dynamic SQL

What is dynamic SQL: Dynamic SQL refers to generating different Sql statements according to different query conditions.

官网描述:
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。
动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。

  -------------------------------
  - if
  - choose (when, otherwise)
  - trim (where, set)
  - foreach
  -------------------------------

The SQL statements we wrote before are relatively simple. If there is a more complex business, we need to write complex SQL statements, which often need to be spliced, and splicing SQL, a little carelessness, missing quotation marks, spaces, etc. may cause errors.

So how to solve this problem? This requires the use of mybatis dynamic SQL. Through tags such as if, choose, when, otherwise, trim, where, set, foreach, etc., it can be combined into a very flexible SQL statement, thereby improving the accuracy of the SQL statement while also greatly improving Improve the efficiency of developers.

The so-called dynamic SQL is essentially a SQL statement, but we can execute a logic code at the SQL level

Set up the environment

Just use the previous employee entity class directly.

  1. Import lombok dependencies

  2. New Pojo entity class employee

  3. Create the EmployeeMapper interface and write several abstract methods

  4. Create and write EmployeeMapper.xml in the resource package

  5. Bind the EmployeeMapper.xml resource in the core configuration file mybatis-config.xml file

  6. Write test class

if

    <select id="getEmployeeDynamicSQL" parameterType="map" resultType="Employee">
        select * from employee where 1 = 1
        <if test="age != null">
            and age = #{age}
        </if>
        <if test="dept_id != null">
            and dept_id = #{dept_id}
        </if>
    </select>
    @Test
    public void getEmployeeDynamicSQL(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("age",20);
//        map.put("dept_id",1);
        List<Employee> employees = mapper.getEmployeeDynamicSQL(map);
        for (Employee employee : employees) {
    
    
            System.out.println(employee);
        }
    }

Insert picture description here

This method is relatively rigid. The where in the sql statement must be brought and activated. If the if conditions are not met, the full table query is performed, and if both are met, the conditional union query

choose (when, otherwise)

    <select id="getEmployeeDynamicSQL3" parameterType="map" resultType="Employee">
        select * from employee
        <where>
            <choose>
                <when test="age != null">
                    age = #{age}
                </when>
                <when test="dept_id != null">
                    dept_id = #{dept_id}
                </when>
                <otherwise>
                    id = #{id}
                </otherwise>
            </choose>
        </where>

    </select>
    @Test
    public void getEmployeeDynamicSQL3(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
        HashMap<String, Object> map = new HashMap<String, Object>();
//        map.put("age",20);
//        map.put("dept_id",1);
        map.put("id",7);
        List<Employee> employees = mapper.getEmployeeDynamicSQL3(map);
        for (Employee employee : employees) {
    
    
            System.out.println(employee);
        }
    }

Insert picture description here

This kind of selection of one of the executions according to the conditions requires comparison and memory with the previous if.

trim (where, set)

where used with if

<select id="getEmployeeDynamicSQL2" parameterType="map" resultType="Employee">
    select * from employee
    <where>
        <if test="age != null">
            and age = #{age}
        </if>
        <if test="dept_id != null">
            and dept_id = #{dept_id}
        </if>
    </where>
</select>
    @Test
    public void getEmployeeDynamicSQL2(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("age",20);
        map.put("dept_id",1);
        List<Employee> employees = mapper.getEmployeeDynamicSQL2(map);
        for (Employee employee : employees) {
    
    
            System.out.println(employee);
        }
    }

Insert picture description here

set modification execute modification sql

<update id="updateEmployeeDynamicSQL" parameterType="map">
    update employee
    <set>
        <if test="name != null">name = #{name},</if>
        <if test="age != null">age = #{age},</if>
        <if test="dept_id != null">dept_id = #{depid}</if>
    </set>
    where id = #{id}
</update>
    @Test
    public void updateEmployeeDynamicSQL(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
        HashMap<String, Object> map = new HashMap<String, Object>();
//        map.put("age",20);
//        map.put("dept_id",1);
        map.put("id",7);
        map.put("name","王炸炸");
        map.put("age",18);
        mapper.updateEmployeeDynamicSQL(map);

    }

Insert picture description here

SQL fragment

Sometimes, we may extract some functional parts to facilitate reuse!

  1. Use sql tags to extract common parts

        <sql id="age-dept_id">
            <if test="age != null">
                and age = #{age}
            </if>
            <if test="dept_id != null">
                and dept_id = #{dept_id}
            </if>
        </sql>
    
  2. Use the include tag reference where you need to use it

        <select id="getEmployeeDynamicSQL2" parameterType="map" resultType="Employee">
            select * from employee
            <where>
                <include refid="age-dept_id"/>
            </where>
        </select>
    

foreach

Guess you like

Origin blog.csdn.net/weixin_43215322/article/details/109565314