foreword
We know that the use of database query before project development is based on jdbc
connection query, and then advanced jdbcTemplate
query, 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 ORM
the framework, such Mybatis,Hibernate,
as SpringBoot,Spring Data JPA
conditional query
We know that mybatis mapper
conditional 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 sql
statements
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 and
or or
connect
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 if
label condition judgment connection, it will automatically add keywords to the statement and remove the first onewhere
Sql
where
and
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 Java
grammar, case,switch
sentence judgment
As long as one of the conditions is established, the other will not be judged. If no conditions are met, otherwise
the 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>
- collection: the collection object to traverse
- item: record the result of each traversal
- open: add content to the left of the result
- separator: the content between the result and the result
- close: the content added at the end
It is often used in in
queries 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
- When we need to perform complex dynamic conditional queries on the associated data of multiple tables, we need to use
if
labels 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. sql
When 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 >= 0 AND tu.ADMIN_TYPE_ID <= #{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 if
the 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
where
a connection, rather thanand
avoiding 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 = 1
solve it by assuming to give him a default condition, or by nesting where
tags