Explain Mybatis in simple terms (7) dynamic sql

Comprehensive query of this sql for the previous user information

<!-- User information comprehensive query -->
    <select id="findUserList" parameterType="userQueryVo" resultType="userCustom">
        select * from user where user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'
    </select>

If the parameter we pass in is empty, then there will be a problem.

At this time, we need to use our if condition judgment.

<!-- User information comprehensive query -->
    <select id="findUserList" parameterType="userQueryVo" resultType="userCustom">
        select * from user
         <where>
             <if test="userCustom != null">
                 <if test="userCustom.sex != null">
                     <!-- The and of the first condition can be omitted, it doesn't matter if it is written, the where tag will automatically remove the first and -->
                    and user.sex = #{userCustom.sex}
                 </if>
                 <if test="userCustom.username != null">
                     and user.username like '%${userCustom.username}%'
                 </if>
             </if>
         </where>

    </select>

have a test:

The result is the same

[User{id=10, username='Zhang San', birthday=Wed Mar 07 08:00:00 CST 2018, sex='1', addr='Chengdu'}, User{id=39, username='Zhang Four', birthday=Wed Mar 21 08:00:00 CST 2018, sex='1', addr='Beijing'}]

sql snippet:

When one of our query conditions is shared by multiple SQLs, we need to extract the conditions to form a separate SQL segment, which is convenient for multiple SQL statements to share.

First you need to define the sql fragment:

<!-- define sql fragment
            id: unique identifier of the sql fragment
            Experience: SQL fragments are defined based on a single standard, so that the reusability of SQL fragments is high
     -->
    <sql id="query_user_where">
        <if test="userCustom != null">
            <if test="userCustom.sex != null">
                and user.sex = #{userCustom.sex}
            </if>
            <if test="userCustom.username != null">
                and user.username like '%${userCustom.username}%'
            </if>
        </if>
    </sql>

Then you can directly cite it wherever you need it

<!-- User information comprehensive query -->
    <select id="findUserList" parameterType="userQueryVo" resultType="userCustom">
        select * from user
         <where>
             <!-- Refer to the defined sql fragment, if it is not in this mapper, you need to add namespace -->
             <include refid="query_user_where"/>
         </where>

    </select>



foreach:

Suppose we need to query user information with id 1 or 10 or 16.

Add a new property to UserQueryVo and generate get and set methods


Add a foreach in mapper.xml

<sql id="query_user_where">
        <if test="userCustom != null">
            <if test="userCustom.sex != null">
                and user.sex = #{userCustom.sex}
            </if>
            <if test="userCustom.username != null">
                and user.username like '%${userCustom.username}%'
            </if>
            <!-- Use foreach to iterate over the incoming ids
                collection: specifies the collection property in the input object
                item: each traversal generates an object
                open: the string spliced ​​when starting the traversal
                close: the string spliced ​​when the traversal ends
                separator: the string that needs to be spliced ​​in the two objects traversed
                Use the following sql splicing to achieve:
                and (id=1 or id=10 or id=16)
             -->
            <foreach collection="ids" item="user_id" open="and (" close=")" separator="or">
                  id=#{user_id}
            </foreach>
        </if>
    </sql>

test it

@Test
    public void testfindUserList() throws Exception{
        SqlSession sqlSession = factory.openSession();
        //Get the proxy object of UserMapper through reflection
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        UserQueryVo userQueryVo = new UserQueryVo();
        UserCustom userCustom = new UserCustom();
        //Query all users whose gender is 1 and sex Zhang
        userCustom.setSex("1");
        userCustom.setUsername("张");
        userQueryVo.setUserCustom(userCustom);
        List<Integer> ids = new ArrayList<>();
        ids.add(1);
        ids.add(10);
        ids.add(16);
        userQueryVo.setIds(ids);
       List user = userMapper.findUserList(userQueryVo);
        System.out.println(user);

    }
}
Successfully output the user information whose gender is 1, sex sheet, and id is in the three numbers (1, 10, 16).

[User{id=10, username='Zhang San', birthday=Wed Mar 07 08:00:00 CST 2018, sex='1', addr='Chengdu'}]

Another implementation of the above foreach

            <!-- Implement and id in (1,10,16) splicing-->
            <foreach collection="ids" item="user_id" open="and id in (" close=")" separator=",">
                <!-- Strings that need to be spliced ​​for each traversal -->
                #{user_id}
            </foreach>
The result is the same as above


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325474721&siteId=291194637