Mybatis use of dynamic SQL to perform complex queries foreach

A, foreach Overview

For some SQL statements contained in condition requires an iterative set of conditions to produce a situation, we need to use foreach tag to implement an iterative SQL conditions. foreach mainly used in building in the conditions, it can iterate a set of SQL statements. Its main attribute item, index, collection, separator, close, open

Two, foreach iteration of the array type parameters

Requirements: to get a list of user information based on user roles List

public List<User> getUserByRoleId_foreach_array(Integer[] roleIds);
<select id="getUserByRoleId_foreach_array" resultMap="userMapByRole">
  select * from smbms_user where userRole in
    <foreach collection="array" item="roleIds" open="(" separator="," close=")">
      #{roleIds}
    </foreach>
</select>

<resultMap id="userMapByRole" type="User">
  <id property="id" column="id"/>
  <result property="userCode" column="userCode"/>
  <result property="userName" column="userName"/>
</resultMap> 
@Test
public void testGetUserByRoleId_foreach_array(){
    SqlSession sqlSession = null;
    List<User> userList = new ArrayList<>();
    Integer[] roleIds = {2, 3};
    try {
        sqlSession = MyBatisUtil.createSqlSession();
        userList = sqlSession.getMapper(UserMapper.class).getUserByRoleId_foreach_array(roleIds);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        MyBatisUtil.closeSqlSession(sqlSession);
    }
    logger.debug("userList.size-->" + userList.size());
    for (User user:userList){
        logger.debug("user=====>id:" + user.getId() 
                + ", userCode:" + user.getUserCode()
                + ", userName:" + user.getUserName()
                + ", userRole:" + user.getUserRole());
    }
}

 Specific information tag has the following basic properties foreach

  • item: indicates the alias iterate each element in the collection
  • index: Specifies a name for representing the iterative process, each iteration to a position
  • open: indicates that the statement to the beginning of what, in conditional statement is "(" Start 
  • separator: in between each iteration represents what the symbol as a delimiter, in a conditional statement to "," as the delimiter
  • close: indicates that the statement to what end, in a conditional statement is ")" End
  • collection: This attribute must specify, under different circumstances, the value of this attribute is not the same
    • If the parameter is a single parameter and a parameter type is List, collection attribute value list
    • If the parameter is a single parameter and the parameter type is an array, the collection property value array (here parameters passed Integer [] roleIds an array type, it is here collection attribute value to "array")
    • If the parameter passed to a multi-parameter, these need to be treated as a package Map

ParameterType profile is not configured, MyBatis it will automatically packaged into a Map passed.

Three, foreach iteration of the parameter type List

public List<User> getUserByRoleId_foreach_array(List<Integer> roleList);
<select id="getUserByRoleId_foreach_array" resultMap="userMapByRole">
  select * from smbms_user where userRole in
  <foreach collection="list" item="roleList" open="(" separator="," close=")">
    #{roleList}
  </foreach>
</select>

<resultMap id="userMapByRole" type="User">
  <id property="id" column="id"/>
  <result property="userCode" column="userCode"/>
  <result property="userName" column="userName"/>
</resultMap> 

The key test code is as follows

List<User> userList = new ArrayList<>();
List<Integer> roleList = new ArrayList<>();
roleList.add(2);
roleList.add(3);
try {
    sqlSession = MyBatisUtil.createSqlSession();
    userList = sqlSession.getMapper(UserMapper.class).getUserByRoleId_foreach_array(roleList);
}

foreach allows us to specify a set of start and end of the character, a separator can also be added to the iterator, intelligent and able to handle the delimiter does not appear the extra delimiter

Four, foreach iteration of the parameters of type Map

If a plurality of MyBatis into the reference parameters, except @Param annotations, they can be treated as a package Map

public List<User> getUserByRoleId_foreach_array(Map<String, Object> conditionMap);
<select id="getUserByRoleId_foreach_array" resultMap="userMapByRole">
  select * from smbms_user where gender=#{gender} and userRole in
  <foreach collection="roleIds" item="roleMap" open="(" separator="," close=")">
    #{roleMap}
  </foreach>
</select>

<resultMap id="userMapByRole" type="User">
  <id property="id" column="id"/>
  <result property="userCode" column="userCode"/>
  <result property="userName" column="userName"/>
</resultMap> 

Test method, the user list and gender into two packages parameters into a parametric method Map

List<User> userList = new ArrayList<>();
List<Integer> roleList = new ArrayList<>();
roleList.add(2);
roleList.add(3);
Map<String, Object> conditionMap = new HashMap<>();
conditionMap.put("gender", 1);
conditionMap.put("roleIds", roleList);
try {
    sqlSession = MyBatisUtil.createSqlSession();
    userList = sqlSession.getMapper(UserMapper.class).getUserByRoleId_foreach_array(conditionMap);
}

Since the parameters for the Map, then the SQL statement required to separately obtain a corresponding value value based key, such as the SQL statement # {gender} obtained is the Map key for the "gender" gender conditions, collection = "roleIds" the acquisition is the Map key for the role "roleIds" the id of the collection.

Single parameters may also be encapsulated into a reference to Map. MyBatis parameters is performed when the parameters, it will be packaged into a Map, and Map key is the parameter name, the corresponding parameter value is the Map value. If the parameter is the set time, Map based on the key will be passed in List or array of objects corresponding designated as "list" or "array". The advantage is that we are free to specify the key Map, as follows

public List<User> getUserByRoleId_foreach_array(Map<String, Object> roleMap);
<select id="getUserByRoleId_foreach_array" resultMap="userMapByRole">
  select * from smbms_user where userRole in
  <foreach collection="rKey" item="roleMap" open="(" separator="," close=")">
    #{roleMap}
  </foreach>
</select>

<resultMap id="userMapByRole" type="User">
  <id property="id" column="id"/>
  <result property="userCode" column="userCode"/>
  <result property="userName" column="userName"/>
</resultMap>
List<User> userList = new ArrayList<>();
List<Integer> roleList = new ArrayList<>();
roleList.add(2);
roleList.add(3);
Map<String, Object> roleMap = new HashMap<>();
roleMap.put("rKey", roleList);
try {
    sqlSession = MyBatisUtil.createSqlSession();
    userList = sqlSession.getMapper(UserMapper.class).getUserByRoleId_foreach_array(roleMap);
}

五、choose(when、otherwise)

For some queries demand, although multiple query conditions, but do not want all of the conditions, just select the query results in one case. And Java in the switch statement is similar, MyBatis offers a choose element to meet this demand

Requirements: a can, if the first three conditions did not provide default provides the last condition according to any of the conditions (user name, user role, user code) (creation time, within the specified year) to complete the query operation 

public List<User> getUserList_choose(@Param("userName") String userName,
                                     @Param("userRole") Integer roleId,
                                     @Param("userCode") String userCode,
                                     @Param("creationDate") Date creationData);
<select id="getUserList_choose" resultType="User">
  select * from smbms_user where 1=1
  <choose>
    <when test="userName!=null and userName!=''">
      and userName like connect('%', #{userName}, '%')
    </when>
    <when test="userCode!=null and userCode!=''">
      and userCode like connect('%', #{userCode}, '%')
    </when>
    <when test="userRole!=null">
      and userRole = #{userRole}
    </when>
    <otherwise>
      and YEAR(creationDate) = YEAR(#{creationDate})
    </otherwise>
  </choose>
</select>
String userName="";
Integer roleId=null;
String userCode="";
Date creationDate = new SimpleDateFormat("yyyy-MM-dd").parse("2019-01-01");
userList = sqlSession.getMapper(UserMapper.class).getUserList_choose(userName, roleId, userCode, creationDate);

generally choose when, otherwise supporting the use.

when element: when its condition is satisfied in the test properties, will when element contents in the output. Java in the switch with the effect is almost the same conditions in order to be processed, as when once the conditions are met, it will jump choose, that is, when all the conditions and otherwise, only one condition is output.

otherwise element: when all the conditions are not met when, it will automatically output the contents otherwise elements

The reason behind the SQL statement added "where 1 = 1" is that we do not need to go to dispose of excess "and".

Guess you like

Origin www.cnblogs.com/yanguobin/p/11716024.html