mybatis动态SQL常用语法总结(mybatis动态sql常用语法总结汇总)
ztj100 2024-11-02 14:29 13 浏览 0 评论
在 mybatis 的 xml 文件里写的 sql 语句实际用的是一门叫做 OGNL 的表达式语言,OGNL 全称 Object Graph Navigation Language 对象图导航语言,是常应用于 Java 中的一个开源的表达式语言(Expression Language),它被集成在 Spring、Mybatis、Struts2 等 Java 框架中,通过简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现类型转化等功能。
在书写动态 SQL 时经常需要借助各种标签,下面是一些在 mybatis 中常用的标签:
if 标签
- 没有 else、else if 标签
- if 标签可以嵌套
- if 标签判断条件 test 中可以用 or 的,我们经常看到用 and
- 对于 number 类型,0 或者浮点型 0.00 会被当成 false(和 js 类似)
- 对于字符串类型才需要判断 != '',其他类型直接判断 != null 就行了
- 对于空字符串 "" 会被当成 false
- 单引号内只有一个字符时,OGNL 会识别成 java 中的 char 类型,然后数据如果是 String 类型时会导致判断失效,可以直接将 test 的引号改成单引号,然后里面的字符串用双引号
if 标签的 test 中常用判断:
* 相等:==
* 不等:!=
* 条件或:or
* 条件与:and
* 条件非:!,也可以用 not
* 包含:in
* 不包含:not in
* 小于:<
* 小于等于:<=
* 大于:>
* 大于等于:>=
choose、when、otherwise 标签
相当于 if、else if、else,间接实现了上面 if 标签不支持的 else 效果
where 标签
用于拼接 SQL 语句中的 where 子句,条件成立时才会加上 where 关键字,可以避免拼接出多余的and、or
set 标签
- 用于拼接SQL语句中的set子句,与 update 语句配合使用,条件成立时才会加上 set 关键字,可以避免拼接出多余的逗号,如果有多余的标签 set 标签会自动去掉
- 一定会加上 set 关键字,所以要保证至少有一个条件成立,否则会报 SQL 语法错误
<update id="updateUserInfo" parameterType="UserInfo">
update t_user_info
<set>
<if test="userName != null and userName != ''">
user_name = #{userName},
</if>
<if test="age != null">
age = #{age},
</if>
</set>
where user_id = #{userId}
</update>
trim 标签
可以间接实现 where 和 set 标签一样的功能
foreach 标签
遍历集合类数据,标签属性:
- collection:要被遍历解析的对象,集合名或者数组名
- item:集合或数组中每一个迭代元素的别名
- index:在 list 和数组中为元素序号,在 map 中为元素的 key
- open:开始符号
- close:结束符号
- separator:连接每一项的分割符号
collection 接收的参数:
- 匿名参数:当在 java 方法中没有通过 @Param 注解指定参数名时,列表类型默认参数名为 list,数组为 array,注意 Map 无默认值需要自己指定具名参数
- 具名参数:java 方法中使用了 @Param 注解指定了参数名称,则 foreach 中的 collection 属性必须为指定的参数名
示例1:匿名参数
<!-- mapper -->
int insertUsers(List<User> users);
int updateUsers(List<User> users);
<!-- xml -->
<insert id="insertUsers">
insert into t_user (id, user_name, age) values
<foreach collection="list" separator="," item="user">
(#{user.user_id}, #{user.user_name}, #{user.age})
</foreach>
</insert>
<update id="updateUsers">
<foreach collection="list" separator=";" item="user">
update t_user
<set>
<if test="user.userName != null and user.userName != ''">
user_name= #{user.userName},
</if>
<if test="user.age != null">
age= #{user.age},
</if>
</set>
where user_id = #{user.userId}
</foreach>
</update>
示例2:具名参数
<!-- mapper -->
List<User> selectUsers(@Param("userIds") String[] userIds);
<!-- xml -->
<select id="selectUsers" resultType="User">
select * from t_user where user_id in
<foreach collection="userIds" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
更多参数传递可以参考后面的 mybatis 参数章节。
sql、include 标签
可以在 sql 标签里定义语句,然后在需要的地方用 include 标签引入进去,可以实现代码片段复用。
selectKey 标签
用于配合插入数据成功后返回的数据,一般用来返回 id 之类的。
mybatis 中参数传递
主要有以下 5 种传参方式:
- 匿名参数
- 具名参数,需用 @Param 注解
- List、Array、Set 参数
- Map 参数
- Java Bean 参数
- JSON 参数
1、匿名参数
单个简单类型参数
xml 获取的时候可以随便写,mybatis 会去自动处理,反正只有一个参数干脆就让你写啥都无所谓,不过推荐还是写个有意义的形参:
<!-- mapper -->
User getUserByUsername(String userName);
<!-- xml -->
<select id="getUserByUsername" resultType="User">
select * from t_user where user_name = #{xxoo}
</select>
多个简单类型参数
多个匿名参数的时候只能通过 mybatis 内置的 param1、param2 按传参顺序对应:
<!-- mapper -->
List<User> selectByuserNameAndAge(String userName, Integer age);
<!-- xml -->
<select id="selectByuserNameAndAge" resultMap="BaseResultMap" >
select * from t_user where user_name = #{param1} and age = #{param2}
</select>
2、具名参数
具名参数需要用 @Param 注解来指定
<!-- mapper -->
List<User> selectByuserNameAndAge(@Param("name") String userName, @Param("age") Integer age);
<!-- xml -->
<select id="selectByuserNameAndAge" resultMap="BaseResultMap" >
select * from t_user where user_name = #{name} and age = #{age}
</select>
3、List、Array、Set 参数
List 类型参数默认值 list,Array 类型参数默认值 array,注意 Set 类型的默认值并不是 set 而是 collection,除此之外的集合默认值也是 collection,当然我们也可以用 @Param 注解来自己指定
<!-- mapper -->
List<User> selectByAgeList(List ages);
<!-- xml -->
<select id="selectByList" resultMap="BaseResultMap" >
SELECT * from t_user where age in
<foreach collection="list" open="(" separator="," close=")" item="age">
#{age}
</foreach>
</select>
4、Map 参数
使用 Map 参数时,可以直接用键名引用
Map params = new HashMap<>();
params.put("userName", "周小黑");
params.put("age", 18);
List<User> result = userMapper.selectByMapParams(params);
<!-- mapper -->
List<User> selectByMapParams(Map params);
<!-- xml -->
<select id="selectByMapParams" resultMap="BaseResultMap" parameterType="map">
select * from t_user where user_name = #{userName} and age = #{age}
</select>
5、Java Bean 参数
和上面的 Map 比较类似,不过这里的 parameterType 要指定为对应的 Bean 实体类型:
<!-- mapper -->
List<User> selectByBeans(User user);
<!-- xml -->
<select id="selectByBeans" resultMap="BaseResultMap" parameterType="User">
select * from t_user where user_name = #{userName} and age = #{age}
</select>
6、JSON 参数
和上面的 Map、Bean 参数类似,一般是直接把前端传递过来的 json 参数直接传入 Mapper 中进行查询,parameterType 为 JSONObject
<!-- mapper -->
List<User> selectByJSON(JSONObject params);
<!-- xml -->
<select id="selectByJSON" resultMap="BaseResultMap" parameterType="com.alibaba.fastjson.JSONObject">
select * from t_user where user_name = #{userName} and age = #{age}
</select>
常见属性设置:
- resultMap:当查询的结果需要进行复杂的映射,例如将结果映射到具有复杂关系的对象上时,resultMap允许自定义结果集的映射规则。如果 xml 文件内有使用 resultMap 标签定义好结果集数据,需要返回的时候直接写 resultMap="BaseResultMap" 就行了,mybatis 会智能地自动给你映射过去。
- resultType: 当查询的结果可以简单地映射到一个 POJO 对象或基本数据类型/包装类时,使用resultType,MyBatis会尝试自动将结果集映射到resultType指定的类型的对象上。
- parameterType: 用于指定传入SQL语句的参数类型,MyBatis会根据parameterType的类型,将方法参数自动转换为SQL语句所需的类型
常用转义符
XML 文件和我们常见的 HTML 类似,都是通过标签来定义数据,而尖括号本身就是表示标签符号的开始和结束,所以在 mybatis 的 xml 文件中相关符号最好用转义符,尤其小于符号 "<",这样可以避免解析时报错,常用转义符:
字符名称 sql符号 转义字符
大于号 > >
小于号 < <
大于等于号 >= >=
小于等于号 <= <=
单引号 ' '
双引号 " "
常用 jdbcType类型对应的 Java 类型
jdbcType JavaType
CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC BigDecimal
DECIMAL BigDecimal
BOOLEAN boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
FLOAT double
DOUBLE double
DATE Date
TIME Time
TIMESTAMP Timestamp
相关推荐
- Vue 技术栈(全家桶)(vue technology)
-
Vue技术栈(全家桶)尚硅谷前端研究院第1章:Vue核心Vue简介官网英文官网:https://vuejs.org/中文官网:https://cn.vuejs.org/...
- vue 基础- nextTick 的使用场景(vue的nexttick这个方法有什么用)
-
前言《vue基础》系列是再次回炉vue记的笔记,除了官网那部分知识点外,还会加入自己的一些理解。(里面会有部分和官网相同的文案,有经验的同学择感兴趣的阅读)在开发时,是不是遇到过这样的场景,响应...
- vue3 组件初始化流程(vue组件初始化顺序)
-
学习完成响应式系统后,咋们来看看vue3组件的初始化流程既然是看vue组件的初始化流程,咋们先来创建基本的代码,跑跑流程(在app.vue中写入以下内容,来跑流程)...
- vue3优雅的设置element-plus的table自动滚动到底部
-
场景我是需要在table最后添加一行数据,然后把滚动条滚动到最后。查网上的解决方案都是读取html结构,暴力的去获取,虽能解决问题,但是不喜欢这种打补丁的解决方案,我想着官方应该有相关的定义,于是就去...
- Vue3为什么推荐使用ref而不是reactive
-
为什么推荐使用ref而不是reactivereactive本身具有很大局限性导致使用过程需要额外注意,如果忽视这些问题将对开发造成不小的麻烦;ref更像是vue2时代optionapi的data的替...
- 9、echarts 在 vue 中怎么引用?(必会)
-
首先我们初始化一个vue项目,执行vueinitwebpackechart,接着我们进入初始化的项目下。安装echarts,npminstallecharts-S//或...
- 无所不能,将 Vue 渲染到嵌入式液晶屏
-
该文章转载自公众号@前端时刻,https://mp.weixin.qq.com/s/WDHW36zhfNFVFVv4jO2vrA前言...
- vue-element-admin 增删改查(五)(vue-element-admin怎么用)
-
此篇幅比较长,涉及到的小知识点也比较多,一定要耐心看完,记住学东西没有耐心可不行!!!一、添加和修改注:添加和编辑用到了同一个组件,也就是此篇文章你能学会如何封装组件及引用组件;第二能学会async和...
- 最全的 Vue 面试题+详解答案(vue面试题知识点大全)
-
前言本文整理了...
- 基于 vue3.0 桌面端朋友圈/登录验证+60s倒计时
-
今天给大家分享的是Vue3聊天实例中的朋友圈的实现及登录验证和倒计时操作。先上效果图这个是最新开发的vue3.x网页端聊天项目中的朋友圈模块。用到了ElementPlus...
- 不来看看这些 VUE 的生命周期钩子函数?| 原力计划
-
作者|huangfuyk责编|王晓曼出品|CSDN博客VUE的生命周期钩子函数:就是指在一个组件从创建到销毁的过程自动执行的函数,包含组件的变化。可以分为:创建、挂载、更新、销毁四个模块...
- Vue3.5正式上线,父传子props用法更丝滑简洁
-
前言Vue3.5在2024-09-03正式上线,目前在Vue官网显最新版本已经是Vue3.5,其中主要包含了几个小改动,我留意到日常最常用的改动就是props了,肯定是用Vue3的人必用的,所以针对性...
- Vue 3 生命周期完整指南(vue生命周期及使用)
-
Vue2和Vue3中的生命周期钩子的工作方式非常相似,我们仍然可以访问相同的钩子,也希望将它们能用于相同的场景。...
- 救命!这 10 个 Vue3 技巧藏太深了!性能翻倍 + 摸鱼神器全揭秘
-
前端打工人集合!是不是经常遇到这些崩溃瞬间:Vue3项目越写越卡,组件通信像走迷宫,复杂逻辑写得脑壳疼?别慌!作为在一线摸爬滚打多年的老前端,今天直接甩出10个超实用的Vue3实战技巧,手把...
- 怎么在 vue 中使用 form 清除校验状态?
-
在Vue中使用表单验证时,经常需要清除表单的校验状态。下面我将介绍一些方法来清除表单的校验状态。1.使用this.$refs...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Vue 技术栈(全家桶)(vue technology)
- vue 基础- nextTick 的使用场景(vue的nexttick这个方法有什么用)
- vue3 组件初始化流程(vue组件初始化顺序)
- vue3优雅的设置element-plus的table自动滚动到底部
- Vue3为什么推荐使用ref而不是reactive
- 9、echarts 在 vue 中怎么引用?(必会)
- 无所不能,将 Vue 渲染到嵌入式液晶屏
- vue-element-admin 增删改查(五)(vue-element-admin怎么用)
- 最全的 Vue 面试题+详解答案(vue面试题知识点大全)
- 基于 vue3.0 桌面端朋友圈/登录验证+60s倒计时
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- node卸载 (33)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- exceptionininitializererror (33)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)