目录
前言
动态标签用法
一、if标签
二、where标签
三、trim标签
四、set标签
五、foreach标签
六、choose、when、otherwise标签
七、bind标签
八、include标签
MyBatis提供了10种动态SQL标签:trim、where、set、foreach、if、choose、when、otherwise、bind、include;其执行原理为,使用OGNL从SQL参数对象中计算表达式的值,根据表达式的值动态拼接SQL,以此来完成动态SQL的功能。
通过test属性中的表达式去判断内容是否有效,有效则将if中的sql片段拼接执行。
例如:在人员信息表,根据姓名,年龄,地址,性别等条件查询人员信息。
dao层:
User sqlUse(@Param("name") String name, @Param("age") int age,
@Param("address") String address, @Param("sex") String sex);
xml(注释已在代码):
操作日志:
问题:若是上述条件都不满足会出现select * from where...的情况,亦或name条件不满足则会出现select * from where and...的语法错误,导致sql报错无法进行,那么该如何修改sql?
解释:只需要在where语句后加上1=1的恒成立条件,并且在每个if的sql前面加上and即可;但是接下来介绍的
where标签特性:
需要注意的是:where标签只会智能的去除首个满足条件语句的前缀,所以建议在使用where标签时,每个语句都最好写上 and 前缀或者 or 前缀。否则会出现以下问题:
生成的sql语句如下:
select * from user WHERE name = ? age = ? sex = ?
很明显,sql语法是有问题的,所以在使用where标签时,建议将所有条件都添加上and或or;正确的使用方法如下:
例如:在人员信息表,根据姓名,年龄,地址,性别等条件查询人员信息。
trim标签参数说明:
例如:在人员信息表,根据姓名,年龄,地址,性别等条件查询人员信息。
使用prefix增加前缀(where),prefixOverrides去除多余前缀(and | or)实现查询功能
例如:根据人员信息表主键id,更新人员姓名、年龄、地址、性别等信息。
使用prefix增加前缀(set),suffixOverrides去除多余后缀(,),suffix增加后缀(where id = #{id})实现更新用户信息功能
update user
name= #{name},
age= #{age},
sex= #{sex},
address= #{address},
例如:人员信息表插入数据。
使用prefix增加前缀((),suffixOverrides去除多余后缀(,),suffix增加后缀()),实现插入用户信息功能。
INSERT INTO user
id,
name,
age,
sex,
address,
#{id},
#{name},
#{age},
#{sex},
#{address},
使用set标签可以动态配置SET关键字,和剔除追加到条件末尾的任何不相关的逗号。
例如:根据人员信息表主键id,更新人员姓名、年龄、地址、性别等信息。
update user
name= #{name},
age= #{age},
sex= #{sex},
address= #{address},
where id = #{id}
通过控制台日志可以发现address后面的逗号被去除!
foreach 标签属性主要有 item,index,open,separator,close,collection。
foreach 标签的 collection 属性在接受参数名时,有两种情况:
匿名参数
当在 java 方法中没有通过 @Param 注解指定参数名时,列表类型默认参数名为 ”list“,数组类型默认参数名为 ”array“,Map 对象没有默认值。
具名参数
java 方法中使用了 @Param 注解指定了参数名称,则 foreach 中的 collection 属性必须为参数名。
例如:根据主键Id集合查询所有符合的人员信息。
dao层:
//如下两种入参均可用selectAllUser语句
List selectAllUser(@Param("ids") List ids);
List selectAllUser(@Param("ids") String[] ids);
xml:
在使用foreach批量更新、插入数据时,mybatis 会根据XML文件配置,动态生成多条 SQL。而要让 mybatis 成功执行多条语句,须开启允许批量查询设置,即在 jdbc-url 连接信息中添加 &allowMultiQueries=true,否则无法批量执行sql语句!!!如下所示。
例如:批量更新人员信息。
dao层:
int updateAllUser(List users);
xml:
update user
name= #{user.name},
age= #{user.age},
sex= #{user.sex},
address= #{user.address},
where id = #{user.id}
例如:批量插入人员信息。
dao层:
int insertAllUser(List users);
xml:
INSERT INTO user (id, name, age, address, sex) VALUES
(#{user.id}, #{user.name}, #{user.age}, #{user.address}, #{user.sex})
上述传参类型都是List、数组类型,如果入参类型是Map,那么foreach又该如何处理呢?
Map集合在foreach由于没有默认键可用,故需要使用 @Param 注解手动指定一个标识,后面将在foreach中将其作为键使用。该标识任意指定即可,这里使用"maps"
//dao层方法
User selectAllUserByMap(@Param("maps") Map maps);
传入参数为集合时,映射文件的sql标签parameterType属性可省略。由于是Map集合,index、item属性分别表示为该Map集合中的key、value,故可以分别用${k},#{v}来获取该Map集合中的key、value。
Map maps = new HashMap<>();
maps.put("name","萨摩耶");
maps.put("sex","1");
User user = animalInformationDao.selectAllUserByMap(maps);
//xml层方法
操作日志如下:
MyBatis 中动态语句 choose-when-otherwise 类似于 Java 中的 switch-case-default 语句。由于 MyBatis 并没有为 if 提供对应的 else 标签,如果想要达到
//dao层
List selectUserInfo(User user);
//xml
bind标签可以从OGNL(对象图导航语言)表达式中创建一个变量并将其绑定到上下文
Mybatis中使用Mysql的模糊查询字符串拼接(like) 中也涉及到bind的使用。
//dao层
List findUser(@Param("name") String name);
//xml
include标签引用,可以复用SQL片段,sql标签中id属性对应include标签中的refid属性,通过include标签将sql片段和原sql片段进行拼接成一个完整的sql语句进行执行。
id,name,age,address,sex
user
等同于: