【MyBatis】_动态SQL
目录
1. 增
1.1 XML方式
1.2 注解方式
1.3 相关标签
2. 查
2.1 XML方式
2.2 相关标签
3. 改
3.1 XML方式
3.2 相关标签
4. 删
4.1 XML方式
4.2 相关标签
为实现传递参数个数的灵活选择,MyBatis可以使用动态SQL方式操作数据库。
本文介绍为实现增删查改基本操作的常用标签。
动态SQL方式也有注解方式和XML方式两种方式,
本文采用XML方式,在增操作中进行注解方式的示例。
1. 增
1.1 XML方式
在mapper包下创建UserInfo2Mapper接口,实现方法声明:
package com.zhouyou.mybatisdemo1.mapper;
import com.zhouyou.mybatisdemo1.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserInfo2Mapper {
Integer insertByXML(UserInfo userInfo);
}
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhouyou.mybatisdemo1.mapper.UserInfo2Mapper">
<insert id="insertByXML">
insert into userinfo
<trim suffixOverrides="," prefix="(" suffix=")">
<if test="username!=null">
username,
</if>
<if test="password!=null">
password,
</if>
<if test="age!=null">
age,
</if>
<if test="gender!=null" >
gender,
</if>
<if test="phone!=null">
phone
</if>
</trim>
values
<trim suffixOverrides="," prefix="(" suffix=")">
<if test="username !=null">
#{username},
</if>
<if test="password !=null">
#{password},
</if>
<if test="age !=null">
#{age},
</if>
<if test="gender !=null">
#{gender},
</if>
<if test="phone !=null">
#{phone}
</if>
</trim>
</insert>
</mapper>
生成测试类并实现测试方法:
package com.zhouyou.mybatisdemo1.mapper;
import com.zhouyou.mybatisdemo1.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
class UserInfo2MapperTest {
@Autowired
private UserInfo2Mapper userInfo2Mapper;
@Test
void insertByXML() {
UserInfo userInfo=new UserInfo();
userInfo.setUsername("demo10");
userInfo.setPassword("demo10");
userInfo.setAge(21);
userInfo.setPhone("186123400010");
Integer result=userInfo2Mapper.insertByXML(userInfo);
log.info("insertByXML method");
}
}
1.2 注解方式
在UserInfo2Mapper接口中实现insert方法声明:
package com.zhouyou.mybatisdemo1.mapper;
import com.zhouyou.mybatisdemo1.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserInfo2Mapper {
// 新增
@Select("<script>" +
"insert into userinfo(username,password,age," +
"<if test='gender!=null'> gender, </if>" +
"phone)" +
"values (#{username},#{password},#{age}," +
"<if test='gender !=null'> #{gender}, </if>" +
"#{phone})" +
"</script>")
Integer insert(UserInfo userInfo);
}
编写测试方法:
@Test
void insert() {
UserInfo userInfo=new UserInfo();
userInfo.setUsername("demo8");
userInfo.setPassword("demo8");
userInfo.setAge(20);
userInfo.setPhone("18612340008");
Integer result=userInfo2Mapper.insert(userInfo);
log.info("insert method");
}
1.3 相关标签
1、<if> 标签可实现条件判断,常用test属性表示该SQL语句中是否传参java对象的属性:
使用方式为 <if test='xxxx !=null'> java对象属性或数据表字段待传参数 </if>
2、若使用注解方式,<if>标签要编写在<script>标签下。
3、当一个SQL语句中所有参数都可以不传时,可能会由于逗号而导致SQL语句形式错误,此时可以使用<trim>标签添加或去除指定的字符:
在上例中,对于以下代码:
insert into userinfo
<trim suffixOverrides="," prefix="(" suffix=")">
<if test="username!=null">
username,
</if>
<if test="password!=null">
password,
</if>
<if test="age!=null">
age,
</if>
<if test="gender!=null" >
gender,
</if>
<if test="phone!=null">
phone
</if>
</trim>
若最后一个参数phone未传参,则会导致SQL语句最后多了一个逗号,此时采用trim的suffixOverrides属性指定逗号,表示若最后一个字符为逗号则自动去除,且在属性前后加上括号;
2. 查
2.1 XML方式
在UserInfo2Mapper接口中,实现selectByConditionByXML方法声明:
package com.zhouyou.mybatisdemo1.mapper;
import com.zhouyou.mybatisdemo1.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserInfo2Mapper {
List<UserInfo> selectByConditionByXML(UserInfo userInfo);
}
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhouyou.mybatisdemo1.mapper.UserInfo2Mapper">
<sql id="selectTable">
select* from userinfo
</sql>
<select id="selectByConditionByXML" resultType="com.zhouyou.mybatisdemo1.model.UserInfo">
<include refid="selectTable"></include>
<!-- where-->
<!-- <trim prefixOverrides="and">-->
<!-- <if test="username!=null">-->
<!-- username=#{username}-->
<!-- </if>-->
<!-- <if test="password !=null">-->
<!-- and password=#{password}-->
<!-- </if>-->
<!-- <if test="gender !=null">-->
<!-- and gender=#{gender}-->
<!-- </if>-->
<!-- </trim>-->
<where> 1=1
<if test="username!=null">
and username=#{username}
</if>
<if test="password !=null">
and password=#{password}
</if>
<if test="gender !=null">
and gender=#{gender}
</if>
</where>
</select>
</mapper>
实现测试方法:
@Test
void selectByConditionByXML() {
UserInfo userInfo=new UserInfo();
userInfo2Mapper.selectByConditionByXML(userInfo);
log.info("selectByConditionByXML");
}
2.2 相关标签
1、在实现查询操作时,常会用到where子句使用and并连多个条件,此时可以采用<trim>及相关属性实现SQL语句的正确表达,如防止username未传参而导致的以and开头:
<trim prefixOverrides="and">
也可以采用<where></where>标签,自动实现where子句的正确格式化;
2、采用专用的<where>标签还可以避免where子句条件为空导致的SQL语句格式错误:
3、由于在工程开发中不建议使用*进行全列查询,故在编写SQL语句时可能出现指定多列的情况,频繁这样写较为麻烦,可以使用<sql>标签和<include>实现重复使用的SQL语句的复用,如:
<sql id="selectTable">
select* from userinfo
</sql>
<select id="selectByConditionByXML" resultType="com.zhouyou.mybatisdemo1.model.UserInfo">
<include refid="selectTable"></include>
表示封装select* from userinfo语句,并为其设置id为selectTable,需要使用可以使用<include>标签 的refid标签指明复用的SQL语句的id。
3. 改
3.1 XML方式
在UserInfo2Mapper接口中,实现updateByXML方法声明:
package com.zhouyou.mybatisdemo1.mapper;
import com.zhouyou.mybatisdemo1.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserInfo2Mapper {
Integer updateByXML(UserInfo userInfo);
}
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhouyou.mybatisdemo1.mapper.UserInfo2Mapper">
<update id="updateByXML">
update userinfo
<!-- set-->
<!-- <trim suffixOverrides=",">-->
<!-- <if test='username !=null'>-->
<!-- username=#{username},-->
<!-- </if>-->
<!-- <if test='age !=null'>-->
<!-- age=#{age},-->
<!-- </if>-->
<!-- <if test='gender !=null'>-->
<!-- gender=#{gender}-->
<!-- </if>-->
<!-- </trim>-->
<set>
<if test='username !=null'>
username=#{username},
</if>
<if test='age !=null'>
age=#{age},
</if>
<if test='gender !=null'>
gender=#{gender}
</if>
</set>
where id=15;
</update>
</mapper>
实现测试方法:
@Test
void updateByXML() {
UserInfo userInfo=new UserInfo();
userInfo.setUsername("demo11");
log.info("updateByXML");
}
3.2 相关标签
在实现修改/更新操作时,常会有多列查询修改的情况,此时可以采用<trim>及相关属性实现SQL语句的正确表达,如防止gender未传参而导致的以,结尾:
<trim suffixOverrides=",">
也可以采用<set></set>标签,自动实现set子句的正确格式化;
4. 删
4.1 XML方式
在UserInfo2Mapper接口中,实现updateByXML方法声明:
package com.zhouyou.mybatisdemo1.mapper;
import com.zhouyou.mybatisdemo1.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserInfo2Mapper {
Integer batchDelete(@Param("ids") List<Integer> ids);
}
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhouyou.mybatisdemo1.mapper.UserInfo2Mapper">
<delete id="batchDelete">
delete from userinfo where id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</delete>
</mapper>
实现测试方法:
@Test
void batchDelete() {
List<Integer> ids = Arrays.asList(17,18,19);
userInfo2Mapper.batchDelete(ids);
}
4.2 相关标签
在删除时可能会出现删除多行的情况,此时可以使用<foreach>标签对删除条件进行遍历,如以上程序实现的SQL语句即:
DELETE from userinfo where id in(17,18,19)
为了实现(17,18,19)的遍历,使用了<foreach>标签:
<foreach collection="ids" open="(" close=")" item="id" separator=",">
表示当前遍历的集合参数名为ids,分别以()开头和结尾,遍历的每一个元素为id;