mybatis mapper special character transfer and dynamic SQL conditional query

foreword

We know that the use of database query before project development is based on jdbcconnection query, and then advanced jdbcTemplatequery, but we found that it is not very convenient, there are a lot of repeated sql statements, coupled with code, low efficiency, so it is derived Out of ORMthe framework, such Mybatis,Hibernate,as SpringBoot,Spring Data JPA

conditional query

We know that mybatis mapperconditional query characters in the file, such >=,<,as the like, cannot be written directly and will report an error. You need to transfer the following chart

Detailed content reference

Common conditional query operations are

We use the unique tags provided by mybatis to make conditional judgments to achieve dynamic splicing sqlstatements

if tag where tag choose when otherwise tag foreach tag

quick start

if tag

grammar:

<if test="xxx != null and xxx != ''">

Write the judgment condition parameter in the test, directly paramN or alias multiple conditions to use andor orconnect

As long as the condition is true, it will be spliced ​​in the Sql statement, and if it is true, all will be spliced

Note that 1=1 is added to the where clause to avoid the risk of and

For example:

<select id="selg" resultType="log">
    select * from log where 1=1
    <if test="param1!=null and param1!=''">
    and outno=#{param1}
    </if>
    <if test="param2!=null and param2!=''">
    and inno=#{param2}
    </if>
</select>

where tag

After processing the above iflabel condition judgment connection, it will automatically add keywords to the statement and remove the first onewhereSqlwhereand

The above sql can be transformed into the following:

<select id="selg" resultType="log">
      select * from log 
  <where>
       <if test="param1!=null and param1!=''">
      and outno=#{param1}
      </if>
      <if test="param2!=null and param2!=''">
      and inno=#{param2}
      </if>
  </where>
     
</select>

choose when otherwise Tags

Similar to Javagrammar, case,switchsentence judgment

As long as one of the conditions is established, the other will not be judged. If no conditions are met, otherwisethe content in progress will be executed by default

The above sql can be transformed into the following:

<select id="selg" resultType="log">
      select * from log 
  <where>
    <choose>
       <when test="param1!=null and param1!=''">
      and outno=#{param1}
      </when>
      <when test="param2!=null and param2!=''">
      and inno=#{param2}
      </when>
      <otherwise>
        and 1=1
      </otherwise>
    </choose>
  </where>
     
</select>

foreach tag

grammar:

  <foreach collection="idList" item="id" open="(" separator="," close=")">
</foreach>
  1. collection: the collection object to traverse
  2. item: record the result of each traversal
  3. open: add content to the left of the result
  4. separator: the content between the result and the result
  5. close: the content added at the end

It is often used in inqueries and batch 插入operations as follows:

<select id="selF" parameterType="list" resultType="account">
    select * from account where ano in
    <foreach collection="list" item="item" open="(" separator="," close=")">
    #{item}
    </foreach>
   </select>


<insert id="insertBatch">
        INSERT INTO t_user
        (id, name, password)
        VALUES
        <foreach collection ="userList" item="user" separator =",">
            (#{user.id}, #{user.name}, #{user.password})
        </foreach >
    </insert>

Other tags use reference click to enter·

Scenario

  1. When we need to perform complex dynamic conditional queries on the associated data of multiple tables, we need to use iflabels to judge as follows

According to the user's mobile phone number, name, age, gender, etc., dynamic condition retrieval is performed. At this time, we need to dynamically adjust the splicing. sqlWhen the condition meets the sql statement and the corresponding condition is slightly different

<select id="findUsersByUser" resultType="cn.soboys.kmall.sys.entity.User">
        select tu.USER_ID,tu.USERNAME,tu.SSEX,td.DEPT_NAME,tu.MOBILE,tu.EMAIL,tu.STATUS,tu.CREATE_TIME,
        td.DEPT_ID
        from t_user tu left join t_dept td on tu.DEPT_ID = td.DEPT_ID
        where tu.ADMIN_TYPE_ID  &gt;= 0 AND tu.ADMIN_TYPE_ID  &lt;= #{userParams.adminType}
        <if test="userParams.roleId != null and userParams.roleId != ''">
           and (select group_concat(ur.ROLE_ID)
            from t_user u
            right join t_user_role ur on ur.USER_ID = u.USER_ID,
            t_role r
            where r.ROLE_ID = ur.ROLE_ID
            and u.USER_ID = tu.USER_ID and r.ROLE_ID=#{userParams.roleId})
        </if>


        <if test="userParams.mobile != null and userParams.mobile != ''">
            AND tu.MOBILE =#{userParams.mobile}
        </if>
        <if test="userParams.username != null and userParams.username != ''">
            AND tu.USERNAME   like CONCAT('%',#{userParams.username},'%')
        </if>
        <if test="userParams.ssex != null and userParams.ssex != ''">
            AND tu.SSEX  =#{userParams.ssex}
        </if>
        <if test="userParams.status != null and userParams.status != ''">
            AND tu.STATUS =#{userParams.status}
        </if>
        <if test="userParams.deptId != null and userParams.deptId != ''">
            AND td.DEPT_ID =#{userParams.deptId}
        </if>
        <if test="userParams.createTime != null and userParams.createTime != ''">
            AND DATE_FORMAT(tu.CREATE_TIME,'%Y%m%d') BETWEEN substring_index(#{userParams.createTime},'#',1) and substring_index(#{userParams.createTime},'#',-1)
        </if>
    </select>

The method corresponding to the mapper

<T> IPage<User> findUsersByUser(Page<T> page, @Param("userParams") SearchUserParams userParams);

Corresponding parameter entity object

@Data
public class SearchUserParams {
    
    
    private String username;
    private String mobile;
    private String status;
    private String ssex;
    private Long deptId;
    private String createTime;
    private long adminType;
    private String roleId;
}

Use ifthe label to judge whether the condition is satisfied, and if it is satisfied, it will be spliced ​​​​to correspondsql

Note that the first conditional splicing we mentioned above is wherea connection, rather than andavoiding and risking to ensure that the sql syntax is correct as follows

<select id="findSearchCouponsPage" parameterType="cn.soboys.kmall.bean.web.params.SearchCouponParams" resultType="coupon">
        select *
        from coupon c
        left join user_coupon uc on c.coupon_id = uc.coupon_id
        WHERE 1 = 1
        <if test="couponParams.userId != null and couponParams.userId != ''">
           and uc.user_id =#{couponParams.userId}
        </if>
        <if test="couponParams.status != null and couponParams.status != ''">
            and c.status =#{couponParams.status}
        </if>
        <if test="couponParams.couponId != null and couponParams.couponId != ''">
            and c.coupon_id =#{couponParams.couponId}
        </if>
        <if test="couponParams.couponType != null and couponParams.couponType != ''">
            and c.type =#{couponParams.couponType}
        </if>
    </select>

We can WHERE 1 = 1solve it by assuming to give him a default condition, or by nesting wheretags

Guess you like

Origin blog.csdn.net/u011738045/article/details/120449564