MyBatis动态SQL

一、概念和使用场景

        使用MyBatis进行数据持久化的过程中,除了基于基本的纯SQL语句查询外,动态SQL也是MyBatis的强大特性之一。许多情况下,我们需要根据不同的条件动态的组装SQL语句,这时候就需要用到动态SQL。

        动态SQL一般是根据用户输入或者外部条件动态组合的SQL语句块,能够灵活的发挥SQL强大的功能、方便解决一些其他方法难以解决或解决方法繁琐的问题。动态SQL常用的标签如下:

标签作用备注
if判断语句单条件判断

choose、when、otherwise

相当于java中的switch、case、default多条件判断
thrim、where辅助元素用于处理一些SQL拼装问题
foreach循环用于批量插入、删除,或者in语句

二、标签用法

1、if标签:条件判断

用于根据条件判断是否执行对应的sql。

示例如下,可用于多字段筛选,只筛选有值的条件。

<select id="getList" parameterType="java.util.Map" resultType="com.simon.model.baseModel.ADAccount">
	select * from ADAccount where 1=1
	<where>
		<if test="map.corp != null and map.corp!=''">
			and corp=#{map.corp}
		</if>
		<if test="map.account != null and map.account != ''">
			and account=#{map.account}
		</if>
		<if test="map.name != null and map.name != ''">
			and name=#{map.name}
		</if>
		<if test="map.departmentTrace != null and map.departmentTrace != ''">
			and departmentTrace=#{map.departmentTrace}
		</if>
		<if test="map.email != null and map.email != ''">
			and email=#{map.email}
		</if>
		<if test="map.mobile !=null and map.mobile != ''">
			and mobile=#{map.mobile}
		</if>
		<if test="map.status != null and map.status != ''">
			and status=#{map.status}
		</if>
	</where>
</select>

2、where标签

用于where语句,上述示例已有它的用法

3、set标签

用于update更新语句。常与if标签连用,根据条件更新对应字段

示例如下,根据字段是否为空,判断是否更新该字段。

<update id="updateUser">
    update user
    <set>
        <if test="name != null">name=#{name},</if>
        <if test="phone != null">phone=#{phone},</if>
    account=#{account}
    </set>
    where id=#{id}
</update>

4、choose、when、otherwise标签

用于选择多个条件中的某一个条件执行。

示例如下,根据条件选择id、username、phone、account中的一个字段进行筛选。依次判断when语句中的条件是否成立,若成立,则只执行当前语句;否则继续判断下一个。

<select id="getUserList" resultType="java.util.Map" parameterType="com.simon.model.baseModel.ADAccount">
  select * from user
  <where>
	  <choose>
		  <when test="id !='' and id != null">
			  id=#{id}
		  </when>
		  <when test="username !='' and username != null">
			  and username=#{username}
		  </when>
		  <when test="phone  !='' and phone  != null">
			  and phone =#{phone }
		  </when>
		  <otherwise>
			  and account=#{account}
		  </otherwise>
	  </choose>
  </where>
</select>

5、trim标签

用于在增加或删除语句的前后缀。有四个属性,分别为:

prefix:为语句增加指定前缀。

prefixOverrides:为语句去除指定前缀。

suffix:为语句增加指定后缀。

suffixOverrides:为语句去除指定后缀。

例如,可将1中的语句改成如下语句,在语句中增加指定前缀“where”,同时去除第一条语句的前缀“and”。同理3中的语句也可以改为增加指定前缀“set”,同时去除最后一条语句的后缀“,”。

<select id="getList" parameterType="java.util.Map" resultType="com.simon.model.baseModel.ADAccount">
	select * from ADAccount
	<trim prefix="where" prefixOverrides="and">
		<if test="map.corp != null and map.corp!=''">
			and corp=#{map.corp}
		</if>
		<if test="map.account != null and map.account != ''">
			and account=#{map.account}
		</if>
		<if test="map.name != null and map.name != ''">
			and name=#{map.name}
		</if>
		<if test="map.departmentTrace != null and map.departmentTrace != ''">
			and departmentTrace=#{map.departmentTrace}
		</if>
		<if test="map.email != null and map.email != ''">
			and email=#{map.email}
		</if>
		<if test="map.mobile !=null and map.mobile != ''">
			and mobile=#{map.mobile}
		</if>
		<if test="map.status != null and map.status != ''">
			and status=#{map.status}
		</if>
	</where>
</select>

6、foreach标签

用于遍历集合,同时可以设置对遍历的每条语句之前增加分隔符,也可以对整体遍历的结果增加前后缀。有如下属性:

collection:需要遍历的集合。

item:当前遍历出的元素所赋值的变量。

index:当前遍历出的元素的索引。

open:最终遍历结果所需增加的前缀。

close:最终遍历结果所需增加的后缀。

separator:遍历出的每条语句之间的分隔符。

示例如下:

<select id="findAll" resultType="Student" parameterType="Integer">
    <include refid="selectvp"/> WHERE sid in
    <foreach item="ids" collection="array"  open="(" separator="," close=")">
        #{ids}
    </foreach>
</select>

7、sql和include标签

sql标签主要用于设置公共的语句,而include标签则用于引用sql标签所定义的语句。

开发过程中总会重复编写一些相同的sql语句,而这就可以用sql标签来统一定义;而之后在需要的地方用include标签来引用即可,避免重复编码相同语句。

示例如下:

<sql id="Base_Column_List">
	ID, AZID, EID, badge, Name, Joindate, WorkBeginDate, BalType, Term, TakeDate, ExpiredDate, 
	TotalBal, TotalDec, Bal, xUnit, SeqID, totalbal2, totalbal3, hjbadge
</sql>
<select id="selectByExample" parameterType="com.simon.model.ehrModel.AbalanceExample" resultMap="BaseResultMap">
	select
	<if test="distinct">
	  distinct
	</if>
	'true' as QUERYID,
	<include refid="Base_Column_List" />
	from aBalance
	<if test="_parameter != null">
	  <include refid="Example_Where_Clause" />
	</if>
	<if test="orderByClause != null">
	  order by ${orderByClause}
	</if>
</select>

如果要在不同的文件中引用sql标签,则需要在include标签的refid属性中填写sql标签的具体路径,例如:

<include refid="com.xxx.dao.xxMapper.Base_Column_List"></include>

三、关联查询

        一般情况下的关联查询,只需要使用对应关联sql语句就可以。但如果遇到一对多的情况,在使用对应的sql语句之外,还需用到mybatis的关联查询的结果映射。如下:

<resultMap id="BaseResultMap" type="com.simon.model.ehrModel.Abalance">
	<id column="ID" jdbcType="INTEGER" property="id" />
	<result column="AZID" jdbcType="INTEGER" property="azid" />
	<result column="EID" jdbcType="INTEGER" property="eid" />
	<result column="badge" jdbcType="VARCHAR" property="badge" />
	<result column="Name" jdbcType="NVARCHAR" property="name" />
	<result column="Joindate" jdbcType="TIMESTAMP" property="joindate" />
	<collection property="list" ofType="workInfo">
        <result property="company" column="company"/>
        <result property="startDate" column="startDate"/>
		<result property="endDate" column="endDate"/>
    </collection>
</resultMap>

四、注意

        当然,动态SQL虽然可以根据条件动态的调整sql语句,从而增加代码开发的便利,但有时候并不能增加执行性能,而如果使用不当的话,更有可能存在sql注入的风险。需要谨慎使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值