动态SQL
动态查询
select * from cities where city="" and id>=""
,查询输入条件可能只有city和province中的一个
由于xml文件中不识别 大于、小于等符号,需要进行转义
原符号 | 替换符号 |
---|---|
< | < |
<= | <= |
> | > |
>= | >= |
& | & |
' | & |
" | " |
映射文件
-
查询传入的city不为空,查询该city
-
查询传入的province不为空,查询 <=province
<!--多条件查询[动态SQL],会自动组合成一个正常的where语句 city和id会从map中自动获取--> <select id="findByCondition" parameterType="map" resultMap="citiesMap"> select * from cities <where> <if test="city!=null"> city=#{city} </if> <if test="id!=null"> and id>=#{id} </if> </where> </select>
DAO层方法
动态修改
update cities set city="",province="" where id=""
,修改字段可能只有city和province中的一个
映射文件
<!-- 动态更新,不要忘记更新多个字段时,字段间的逗号 --> <update id="updateByCondition" parameterType="map"> UPDATE cities <set> <if test="city!=null"> city=#{city},</if> <if test="province!=null"> province=#{province}</if> </set> WHERE id=#{id}; </update>
动态删除(批量删除)
delete from cities where id in (...)
,同时删除几条数据
映射文件
<!--动态删除(批量删除)--> <delete id="deleteByCondition" parameterType="int"> <!-- foreach用于迭代数组元素 open表示开始符号 close表示结束符合 separator表示元素间的分隔符 item表示迭代的数组,属性值可以任意,但提倡与方法的数组名相同 #{ids}表示数组中的每个元素值 --> delete from cities where id in <foreach collection="array" open="(" close=")" separator="," item="ids"> #{ids} </foreach> </delete>
DAO层代码
public void deleteByCondition(int... ids){ ... }
动态新增
insert into cities(id,city,province,country) values(?,?,?)
,新增数据的字段可能只有city和province中的一个,有两部分是不确定的,values会根据插入的字段而变化
SQL代码块是不能像之前那样帮我们自动去除多余的逗号的,因此我们需要使用 trim 标签来自己手动去除后缀
映射文件
<!--SQL片段,有两个SQL片段:key和value--> <sql id="key"> <trim suffixOverrides=","> <if test="city!=null">city,</if> <if test="province!=null">province</if> </trim> </sql> <sql id="value"> <trim suffixOverrides=","> <if test="city!=null">#{city},</if> <if test="province!=null">#{province}</if> </trim> </sql> <insert id="insertByCondition" parameterType="mybatis_test.Cities"> INSERT INTO cities(id,<include refid="key"/>,country) values(#{id},<include refid="value"/>,#{country}) </insert>
动态SQL的标签
参考 https://mybatis.org/mybatis-3/zh/dynamic-sql.html
if
<select id="findByCondition" parameterType="map" resultMap="citiesMap"> SELECT * FROM cities WHERE city=#{city} <if test="province!=null"> AND id<=#{id} </if> </where> </select>
如果不传入id,则根据传入的city查询;如果传入id,根据city和id查询
choose(<when>、<otherwise>)
<select id="findByCondition" parameterType="map" resultMap="citiesMap"> SELECT * FROM cities <choose> <when test="city!=null">city=#{city}</when> <when test="province!=null">AND province=#{province}</when> <otherwise>AND id=#{id}</otherwise> </choose> </select>
类似Java的switch语句
如果传入了city就按city查询,传入了province就按province查询,两个都没有,就按id查询
where、set、trim
-
where
<select id="findByCondition" parameterType="map" resultMap="citiesMap"> SELECT * FROM cities <where> <if test="city!=null">AND city=#{city} </if> <if test="province!=null"> AND id<=#{id} </if> </where> </select>
where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除
-
set
<update id="updateByCondition" parameterType="map"> UPDATE cities <set> <if test="city!=null"> city=#{city},</if> <if test="province!=null"> province=#{province}</if> </set> WHERE id=#{id}; </update>
set 元素可以用于动态包含需要更新的列,忽略其它不更新的列
-
trim
一般用于sql语句中去除或添加 前缀、后缀,如去除and关键字、逗号 ,给sql语句前添加“where“、“set“、“values“ ,可用于选择性插入、更新、删除或者条件查询等操作
属性:
-
prefix:给sql语句拼接的前缀
-
suffix:给sql语句拼接的后缀
-
prefixOverrides:去除sql语句前面的关键字或者字符,假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND"
-
suffixOverrides:去除sql语句后面的关键字或者字符
如使用trim完成where的功能,去除前缀 "AND"
<trim prefix="WHERE" prefixOverrides="AND"> <if test="state != null"> state = #{state} </if> <if test="title != null"> AND title like #{title} </if> </trim>
使用trim去除SQL片段的后缀
<sql id="key"> <trim suffixOverrides=","> <if test="city!=null">city,</if> <if test="province!=null">province</if> </trim> </sql>
foreach
<delete id="deleteByCondition" parameterType="int"> delete from cities where id in <foreach collection="array" open="(" close=")" separator="," item="ids" index="index"> #{ids} </foreach> </delete>
open 表示开始符号,close 表示结束符号,separator 表示元素间的分隔符,item 表示迭代的数组,属性值可以任意,但提倡与方法的数组名相同 ,#{ids}表示数组中的每个元素值
指定一个集合,声明可以在元素体内使用的集合项(ids)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。
可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,ids 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,ids 是值。
bind
bind标签中,value对应传入实体类的某个字段,city属性既给对应字段取的变量名。在value属性中可以使用字符串拼接等特殊处理,用作 like 模糊查询。
<bind city="xxx" value="'%'+ id + '%'"/>