MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。
动态SQL可以从两方面来剖析,传入参数的条件和返回数据上根据业务需求进行变化。
一.动态SQL用于实现动态SQL的元素:
1、if 标签
使用 if 元素 判断,如果值为 null 或等于空字符串,我们就不进行此条件的判断,增加灵活性。
参数为实体类:User。将实体类中所有的属性均进行判断,如果不为空则执行判断条件。
<!-- 添加 if(判断参数) - 将实体类 User 不为空的属性作为 where 条件 -->
<select id="getUserList" resultMap="resultMap_User" parameterType="com.yiibai.pojo.User">
SELECT u.username,
u.password,
u.sex,
u.birthday,
u.photo,
u.score,
u.sign
FROM user u
WHERE
<if test="username !=null ">
u.username LIKE CONCAT(CONCAT('%', #{username, jdbcType=VARCHAR}),'%')
</if>
<if test="sex!= null and sex != '' ">
AND u.sex = #{Sex, jdbcType=INTEGER}
</if>
<if test="birthday != null ">
AND u.birthday = #{birthday, jdbcType=DATE}
</if>
<if test="userId != null and userId != '' ">
AND id.user_id = #{userId, jdbcType=VARCHAR}
</if>
</select>
2、foreach 标签
foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合,用于传入一个list参数。
public void delQuestion(@Param("idList") List<String> idList);
<where> AND id IN
<foreach collection="idList" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</where>
3、include 标签
在数据库的使用中,查询的时候时候不要使用*号,*是查询所有,这样如果改动表,或者对查询的效率都有非常大的影响,在MyBatis中有很多的查询语句,如果每个都列出字段,显得十分麻烦,这样就可以用include来拼接SQL语句。
<resultMap id="BaseResultMap" type="com.uama.microservices.provider.base.model.data.FocusInfoBatch">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="title" jdbcType="VARCHAR" property="title" />
<result column="small_pic" jdbcType="VARCHAR" property="smallPic" />
<result column="intime" jdbcType="TIMESTAMP" property="intime" />
<result column="status" jdbcType="TINYINT" property="status" />
<result column="inuser" jdbcType="VARCHAR" property="inuser" />
<result column="org_name" jdbcType="VARCHAR" property="orgName" />
<result column="org_id" jdbcType="VARCHAR" property="orgId" />
<result column="online_from_date" jdbcType="TIMESTAMP" property="onlineFromDate" />
<result column="online_to_date" jdbcType="TIMESTAMP" property="onlineToDate" />
<result column="source_type" jdbcType="TINYINT" property="sourceType" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
<result column="org_type" jdbcType="TINYINT" property="orgType" />
</resultMap>
<sql id="result_column">
id,title,small_pic,intime,status,inuser,org_name,org_id,online_from_date,online_to_date,source_type,update_time,org_type
</sql>
<select id="getFocusInfoBatchById" resultMap="BaseResultMap">
select
<include refid="result_column"/>
from
focus_info_batch
where
id = #{id}
</select>
4、trim 标签
trim标记是一个格式化的标记,可以完成set或者是where标记的功能,自定义格式。
5、前置动态拼接dynamic标签
dynamic元素可以包含多个条件比较元素,并且按照条件比较元素的表述对参数值进行比较,来组装动态SQL。
<update id="updateActivityType" parameterClass="java.util.Map">
UPDATE activity_type
<dynamic prepend="set">
<isNotEmpty prepend="," property="typeName">
type_name = #typeName#
</isNotEmpty>
<isNotEmpty prepend="," property="status">
status = #status#
</isNotEmpty>
<isNotEmpty prepend="," property="parentId">
parent_id = #parentId#
</isNotEmpty>
<isNotEmpty prepend="," property="updateUser">
update_time = now(),update_user = #updateUser#
</isNotEmpty>
</dynamic>
WHERE id = #id#
</update>
二.辅助元素条件
1、<![CDATA[ sql 语句 ]]> 特殊字符
在mapper文件中写sql语句时,遇到特殊字符时,不被解析器解析。
<select id="allUserInfo" parameterType="java.util.HashMap" resultMap="userInfo1">
<![CDATA[
SELECT newsEdit,newsId, newstitle FROM shoppingGuide WHERE 1=1 AND newsday > #{startTime} AND newsday <= #{endTime}
]]>
<if test="query.abnormalFlag != null">
<![CDATA[AND abnormal_flag != #{query.abnormalFlag} and contro_com = #{query.controCom}]]>
</if>
</select>
2、判断是否不为空并拼接
(1)isNotEmpty、isNotNull标签,直接上代码展示:
<isNotEmpty property="communityId" prepend="and">
community_id = #communityId#
</isNotEmpty>
<isNotNull prepend="and" property="regFromDate">
<![CDATA[fdate>=#regFromDate#]]>
</isNotNull>
(2)isEqual标签,当传来的值与compareValue元素的值一样时,就执行
<isEqual property="startCount" compareValue="1">
<![CDATA[having sum(a2.count) = 0]]>
</isEqual>