共计 6331 个字符,预计需要花费 16 分钟才能阅读完成。
自动写代码机器人,免费开通
这篇文章将为大家详细讲解有关 MyBatis 动态 SQL 的示例,丸趣 TV 小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
动态 SQL
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。
动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
准备
首先创建 User 实体类
public class User {
private Integer id;
private String username;
private String userEmail;
private String userCity;
private Integer age;}
创建 user 表
CREATE TABLE user ( id int(11) NOT NULL AUTO_INCREMENT,
username varchar(255) DEFAULT NULL,
user_email varchar(255) DEFAULT NULL,
user_city varchar(255) DEFAULT NULL,
age int(11) DEFAULT NULL,
PRIMARY KEY (id))
if
定义接口方法
public List User findByUser(User user);
接口对应的 Mapper.xml 定义如下所示
select id= findByUser resultType= com.example.mybatis.entity.User
select
id, username, user_email userEmail, user_city userCity, age
from user
where if test= username != null and username !=
username = #{username} /if
if test= userEmail != null and userEmail !=
and user_email = #{userEmail} /if
if test= userCity != null and userCity !=
and user_city = #{userCity} /if /select
如果 if 标签上的 test 为 true,那么 if 标签里面的 SQL 语句将会被拼接。
如果 username、userEmail、userCity 都不为空,那么 SQL 将会拼接成如下所示
select id, username, user_email userEmail, user_city userCity, age
from user where username = ?
and user_email = ? and user_city = ?
如果只有 username 不为空,那么 SQL 将会拼接成如下所示
select id, username, user_email userEmail, user_city userCity, age
from user where username = ?
但是这种方式存在一个缺点,假设此时 username 为空,userEmail、userCity 都不为空。
我们来分析动态 SQL 代码,现在没有给 username 赋值,即 username==null,所以“username=#{username}”这段代码不会添加到 SQL 语句中,那么最终拼接好的动态 SQL 是这样的:
select id, username, user_email userEmail, user_city userCity, age
from user where and user_email = ? and user_city = ?
where 后面直接跟 and,很明显的语法错误,此时应该把紧跟在 where 后面的 and 删掉。为了解决这个问题,可以使用 where 标签。
where
将上面的 SQL 改成如下所示
select id= findByUser resultType= com.example.mybatis.entity.User
select
id, username, user_email userEmail, user_city userCity, age from user
where
if test= username != null and username !=
username = #{username}
/if
if test= userEmail != null and userEmail !=
and user_email = #{userEmail}
/if
if test= userCity != null and userCity !=
and user_city = #{userCity}
/if
/where
/select
如果 where 标签里面的 if 标签有满足条件的,那么 where 标签就会被拼接成 where 语句,若 if 标签拼接的 SQL 最前面有 and 语句,那么这个 and 将会被删除。使用这种方法,会自动删除 SQL 中不需要的关键字,所以一般 if 标签和 where 标签会组合起来使用。
trim
trim 标签中的 prefix 和 suffix 属性会被用于生成实际的 SQL 语句,会和标签内部的语句拼接。
如果语句的前面或后面遇到 prefixOverrides 或 suffixOverrides 属性中指定的值,MyBatis 会自动将它们删除。在指定多个值的时候,别忘了每个值后面都要有一个空格,保证不会和后面的 SQL 连接在一起。
prefix:给拼接的 SQL 语句加一个前缀
suffix:给拼接的 SQL 语句加一个后缀
prefixOverrides:拼接的 SQL 语句前面遇到 prefixOverrides,MyBatis 会自动将它们删除
suffixOverrides:拼接的 SQL 语句后面遇到 suffixOverrides,MyBatis 会自动将它们删除
下面使用 trim 标签来实现 where 标签的功能
select id= findByUser resultType= com.example.mybatis.entity.User
select
id, username, user_email userEmail, user_city userCity, age
from user trim prefix= where prefixOverrides= and
if test= username != null and username !=
username = #{username} /if
if test= userEmail != null and userEmail !=
and user_email = #{userEmail} /if
if test= userCity != null and userCity !=
and user_city = #{userCity} /if
/trim
/select
如果 username 为空,userEmail 和 userCity 不为空,那么 if 标签拼接的 SQL 语句如下所示
and user_email = #{userEmail} and user_city = #{userCity}
因为 trim 标签设置了 prefixOverrides=”and”,而上面的 SQL 前面有 and 语句,所以需要将上面的 and 语句删掉,又因为 trim 标签设置了 prefix=”where”,所以需要在拼接的 SQL 语句前面加一个 where 语句
最后 trim 标签的 SQL 语句被拼接成如下所示
where user_email = #{userEmail} and user_city = #{userCity}
choose
有时我们不想应用到所有的条件语句,而只想从中择其一项。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
select id= findByUser resultType= com.example.mybatis.entity.User
select
id, username, user_email userEmail, user_city userCity, age
from user where
choose
when test= username != null and username !=
username = #{username} /when
when test= userEmail != null and userEmail !=
and user_email = #{userEmail} /when
when test= userCity != null and userCity !=
and user_city = #{userCity} /when
/choose
/where
/select
set
set 标签用于 Update 操作,会自动根据参数选择生成 SQL 语句。
接口定义如下
public int updateUser(User user);
接口对应的 Mapper.xml 定义如下所示
update id= updateUser parameterType= com.example.mybatis.entity.User
update user set
if test= username != null and username !=
username=#{username}, /if
if test= userEmail != null and userEmail !=
user_email=#{userEmail}, /if
if test= userCity != null and userCity !=
user_city=#{userCity}, /if
if test= age != null
age=#{age} /if
/set
where id=#{id} /update
foreach
foreach 标签可以迭代生成一系列值
* 用于 SQL 的 in 语句 *
接口定义如下所示
public List User getUsersByIds(List Integer ids);
接口对应的 Mapper.xml 定义如下所示
!--
collection: 指定要遍历的集合
默认情况下
如果为 Collection 类型的,key 为 collection; 如果为 List 类型的,key 为 list
如果是数组类型,key 为 array
可以通过 @Param(ids) 来指定 key
item: 将当前遍历的元素赋值给指定的变量
open: 给遍历的结果添加一个开始字符
close: 给遍历的结果添加一个结束字符
separator: 每个元素之间的分隔符
-- select id= getUsersByIds
resultType= com.example.mybatis.entity.User
select * from user
where id in foreach collection= list item= id open= ( close=) separator= ,
#{id} /foreach /select
用于批量插入
接口定义如下所示
public int addUserList(List User users);
接口对应的 Mapper.xml 定义如下所示
insert id= addUserList
parameterType= com.example.mybatis.entity.User
insert into user
(username, user_email, user_city, age)
values foreach item= user collection= list separator= ,
(#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}) /foreach /insert !-- 返回自增主键 -- insert id= addUserList
parameterType= com.example.mybatis.entity.User
useGeneratedKeys= true
keyProperty= id
insert into user
(username, user_email, user_city, age)
values foreach item= user collection= list separator= ,
(#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}) /foreach /insert !-- 还可以这样写 -- !--
这种方式需要数据库连接属性设置 allowMultiQueries=true
这种分号分隔多个 SQL 还可以用于其他的批量操作,如修改、删除
-- insert id= addUserList
parameterType= com.example.mybatis.entity.User
foreach item= user collection= list separator=
insert into user
(username, user_email, user_city, age)
values
(#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}) /foreach /insert !-- 如果是 Oracle 数据库,则需要这样写 -- insert id= addUserList
parameterType= com.example.mybatis.entity.User
foreach item= user open= begin close= end; collection= list
insert into user
(username, user_email, user_city, age)
values
(#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}); /foreach /insert
关于 MyBatis 动态 SQL 的示例就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
向 AI 问一下细节
丸趣 TV 网 – 提供最优质的资源集合!