MyBatis(五)动态SQL
目录
一、介绍
动态 SQL 是 MyBatis 的强大特性之一。在 JDBC 或其它类似的框架中,开发人员通常需要手动拼接 SQL 语句。根据不同的条件拼接 SQL 语句是一件极其痛苦的工作。例如,拼接时要确保添加了必要的空格,还要注意去掉列表最后一个列名的逗号。而动态 SQL 恰好解决了这一问题,可以根据场景动态的构建查询。
MyBatis 的动态 SQL 包括以下几种元素,如下表所示:
元素 | 作用 | 备注 |
---|---|---|
if | 判断语句 | 单条件分支判断 |
choose(when、otherwise) | 相当于 Java 中的 switch case 语句 | 多条件分支判断 |
trim、where | 辅助元素 | 用于处理一些SQL拼装问题 |
foreach | 循环语句 | 在in语句等列举条件常用 |
bind | 辅助元素 | 拼接参数 |
二、if标签
MyBatis if 类似于 Java 中的 if 语句,是 MyBatis 中最常用的判断语句。使用 if 标签可以节省许多拼接 SQL 的工作,把精力集中在 XML 的维护上。
测试类
@Test
public void testFindByWhere() throws IOException {
// 先加载主配置文件,加载到输入流中
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 创建SqlSessionFactory对象,创建SqlSession对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
// 创建SqlSession对象
SqlSession session = factory.openSession();
User user = new User();
user.setUsername("%熊%");
user.setSex("女");
// 条件查询
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.findByWhere(user);
for (User user1 : list) {
System.out.println(user1);
}
// 关闭资源
session.close();
inputStream.close();
}
mapper接口
public interface UserMapper {
// 条件查询
public List<User> findByWhere(User user);
}
sql语句
<select id="findByWhere" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
select * from user where 1 = 1
<if test="username != null and username != ''">
and username like #{username}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
</select>
三、where标签
where标签目的就是为了去掉 where 1=1的拼接的,where标签使用在if标签的外面。
where 标签主要用来简化 SQL 语句中的条件判断,可以自动处理 AND/OR 条件。
<!--使用where关键字-->
<select id="findByWhere" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
select * from user
<where>
<if test="username != null and username != ''">
and username like #{username}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
</where>
</select>
四、choose-when-otherwise 标签
由于 MyBatis 并没有为 if 提供对应的 else 标签,如果想要达到<if>...<else>...</else> </if> 的效果,可以借助 <choose>、<when>、<otherwise> 来实现。
<choose>
<when test="判断条件1">
SQL语句1
</when>
<when test="判断条件2">
SQL语句2
</when>
<when test="判断条件3">
SQL语句3
</when>
<otherwise>
SQL语句4
</otherwise>
</choose>
choose 标签按顺序判断其内部 when 标签中的判断条件是否成立,如果有一个成立,则执行相应的 SQL 语句,choose 执行结束;如果都不成立,则执行 otherwise 中的 SQL 语句。这类似于 Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。
举例:
<select id="selectWebsite"
parameterType="net.biancheng.po.Website"
resultType="net.biancheng.po.Website">
SELECT id,name,url,age,country
FROM website WHERE 1=1
<choose>
<when test="name != null and name !=''">
AND name LIKE CONCAT('%',#{name},'%')
</when>
<when test="url != null and url !=''">
AND url LIKE CONCAT('%',#{url},'%')
</when>
<otherwise>
AND age is not null
</otherwise>
</choose>
</select>
当网站名称不为空时,只用网站名称作为条件进行模糊查询;
当网站名称为空,而网址不为空时,则用网址作为条件进行模糊查询;
当网站名称和网址都为空时,则要求网站年龄不为空。
五、foreach标签
Mybatis foreach 标签用于循环语句,它很好的支持了数据和 List、set 接口的集合,并对此提供遍历的功能。
<!--foreach标签 select * from user where id = 1 or id = 2 or id = 3 -->
<select id="findByIds" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
select * from user
<where>
<foreach collection="ids" open="id = " separator="or id = " item="i">
#{i}
</foreach>
</where>
</select>
<!--foreach标签 select * from user where id in (1,2,3)-->
<select id="findByIds" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
select * from user
<where>
<foreach collection="ids" open="id in ( " separator="," close=")" item="i">
#{i}
</foreach>
</where>
</select>
六、set标签
在 Mybatis 中,update 语句可以使用 set 标签动态更新列。set 标签可以为 SQL 语句动态的添加 set 关键字,剔除追加到条件末尾多余的逗号。
<!--使用set元素动态修改一个网站记录 -->
<update id="updateWebsite"
parameterType="net.biancheng.po.Website">
UPDATE website
<set>
<if test="name!=null">name=#{name}</if>
<if test="url!=null">url=#{url}</if>
</set>
WHERE id=#{id}
</update>
七、trim标签
在 MyBatis 中除了使用 if+where 实现多条件查询,还有一个更为灵活的元素 trim 能够替代之前的做法。trim 一般用于去除 SQL 语句中多余的 AND 关键字、逗号,或者给 SQL 语句前拼接 where、set 等后缀,可用于选择性插入、更新、删除或者条件查询等操作。trim 语法格式如下。
属性 | 描述 |
---|---|
prefix | 给SQL语句拼接的前缀,为 trim 包含的内容加上前缀 |
suffix | 给SQL语句拼接的后缀,为 trim 包含的内容加上后缀 |
prefixOverrides | 去除 SQL 语句前面的关键字或字符,该关键字或者字符由 prefixOverrides 属性指定。 |
suffixOverrides | 去除 SQL 语句后面的关键字或者字符,该关键字或者字符由 suffixOverrides 属性指定。 |
<select id="selectWebsite" resultType="net.biancheng.po.Website">
SELECT id,name,url,age,country
FROM website
<trim prefix="where" prefixOverrides="and">
<if test="name != null and name !=''">
AND name LIKE CONCAT ('%',#{name},'%')
</if>
<if test="url!= null">
AND url like concat ('%',#{url},'%')
</if>
</trim>
</select>
<-- SELECT id,name,url,age,country FROM website where name LIKE CONCAT ('%',?,'%') AND url like concat ('%',?,'%') -->
八、提取公用的SQL语句
<!--提取公共的SQL-->
<sql id="findAllSql">
select * from user
</sql>
<!--编写sql语句(重点练习的) com.qcbyjy.mapper.UserMapper.findAll -->
<select id="findAll" resultType="com.qcbyjy.domain.User">
<include refid="findAllSql" />
/*select * from user*/
</select>
<!--使用where关键字-->
<select id="findByWhere" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
<include refid="findAllSql" />
/*select * from user*/
<where>
<if test="username != null and username != ''">
and username like #{username}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
</where>
</select>
<!--foreach标签 select * from user where id in (1,2,3)-->
<select id="findByIds" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
<include refid="findAllSql" />
/*select * from user*/
<where>
<foreach collection="ids" open="id in ( " separator="," close=")" item="i">
#{i}
</foreach>
</where>
</select>
原文地址:https://blog.csdn.net/a13641376265/article/details/145230146
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!