Spring Boot入门系列(十九)整合mybatis,使用注解实现动态Sql、参数传递等常用操作!
前面介绍了Spring Boot 整合mybatis 使用注解的方式实现数据库操作,介绍了如何自动生成注解版的mapper 和pojo类。 接下来介绍使用mybatis 常用注解以及如何传参数等数据库操作中的常用操作。
其实,mybatis 注解方式 和 XML配置方式两者的使用基本上相同,只有在构建 SQL 脚本有所区别,所以这里重点介绍两者之间的差异,以及增删改查,参数传递等注解的常用操作。
Spring Boot 整合mybatis 使用xml配置版之前已经介绍过了,不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/1657780.html。
注解介绍
mybatis 注解方式的最大特点就是取消了 Mapper 的 XML 配置,具体的 SQL 脚本直接写在 Mapper 类或是 SQLProvider 中的方法动态生成 。
mybatis 提供的常用注解有: @Insert 、@Update 、@Select、 @Delete 等标签,这些注解其实就是 MyBatis 提供的来取代其 XML配置文件的。
1、@Select 注解
@Select,主要在查询的时候使用,查询类的注解,一般简单的查询可以使用这个注解。
@Select({
"select",
"id, company_id, username, password, nickname, age, sex, job, face_image, province, ",
"city, district, address, auth_salt, last_login_ip, last_login_time, is_delete, ",
"regist_time",
"from sys_user",
"where id = #{id,jdbcType=VARCHAR}"
})
@Results({
@Result(column="id", property="id", jdbcType=JdbcType.VARCHAR, id=true),
@Result(column="company_id", property="companyId", jdbcType=JdbcType.VARCHAR),
@Result(column="face_image", property="faceImage", jdbcType=JdbcType.VARCHAR),
@Result(column="auth_salt", property="authSalt", jdbcType=JdbcType.VARCHAR),
@Result(column="last_login_ip", property="lastLoginIp", jdbcType=JdbcType.VARCHAR),
@Result(column="last_login_time", property="lastLoginTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="is_delete", property="isDelete", jdbcType=JdbcType.INTEGER),
@Result(column="regist_time", property="registTime", jdbcType=JdbcType.TIMESTAMP)
})
User selectByPrimaryKey(String id);
注意:如果是多个参数,需要将 #后面的参数和传入的变量名保持一致。
2、@Insert 注解
@Insert,插入数据时使用,直接传入数据实体类,mybatis 会属性自动解析到对应的参数。所以需要将 #后面的参数和实体类属性保持一致。
@Insert({
"insert into sys_user (id, company_id, ",
"username, password, ",
"nickname, age, sex, ",
"job, face_image, ",
"province, city, ",
"district, address, ",
"auth_salt, last_login_ip, ",
"last_login_time, is_delete, ",
"regist_time)",
"values (#{id,jdbcType=VARCHAR}, #{companyId,jdbcType=VARCHAR}, ",
"#{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, ",
"#{nickname,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{sex,jdbcType=INTEGER}, ",
"#{job,jdbcType=INTEGER}, #{faceImage,jdbcType=VARCHAR}, ",
"#{province,jdbcType=VARCHAR}, #{city,jdbcType=VARCHAR}, ",
"#{district,jdbcType=VARCHAR}, #{address,jdbcType=VARCHAR}, ",
"#{authSalt,jdbcType=VARCHAR}, #{lastLoginIp,jdbcType=VARCHAR}, ",
"#{lastLoginTime,jdbcType=TIMESTAMP}, #{isDelete,jdbcType=INTEGER}, ",
"#{registTime,jdbcType=TIMESTAMP})"
})
int insert(User record);
注意:需要将 #后面的参数和实体类属性保持一致。
3、@Update 注解
@Update,一般数据更新操作可以使用 @Update注解实现。
@Update({
"update sys_user",
"set company_id = #{companyId,jdbcType=VARCHAR},",
"username = #{username,jdbcType=VARCHAR},",
"password = #{password,jdbcType=VARCHAR},",
"nickname = #{nickname,jdbcType=VARCHAR},",
"age = #{age,jdbcType=INTEGER},",
"sex = #{sex,jdbcType=INTEGER},",
"job = #{job,jdbcType=INTEGER},",
"face_image = #{faceImage,jdbcType=VARCHAR},",
"province = #{province,jdbcType=VARCHAR},",
"city = #{city,jdbcType=VARCHAR},",
"district = #{district,jdbcType=VARCHAR},",
"address = #{address,jdbcType=VARCHAR},",
"auth_salt = #{authSalt,jdbcType=VARCHAR},",
"last_login_ip = #{lastLoginIp,jdbcType=VARCHAR},",
"last_login_time = #{lastLoginTime,jdbcType=TIMESTAMP},",
"is_delete = #{isDelete,jdbcType=INTEGER},",
"regist_time = #{registTime,jdbcType=TIMESTAMP}",
"where id = #{id,jdbcType=VARCHAR}"
})
int updateByPrimaryKey(User record);
4、@Delete 注解
@Delete 数据删除的注解
@Delete({
"delete from sys_user",
"where id = #{id,jdbcType=VARCHAR}"
})
int deleteByPrimaryKey(String id);
5、@Results 和 @Result 注解
@Results 和 @Result 主要作用是,当有一些特殊的场景需要处理,查询的返回结果与期望的数据格式不一致时,可以将将数据库中查询到的数值自动转化为具体的属性或类型,,修饰返回的结果集。比如查询的对象返回值属性名和字段名不一致,或者对象的属性中使用了枚举等。如果实体类属性和数据库属性名保持一致,就不需要这个属性来修饰。
@Select({
"select",
"id, company_id, username, password, nickname, age, sex, job, face_image, province, ",
"city, district, address, auth_salt, last_login_ip, last_login_time, is_delete, ",
"regist_time",
"from sys_user",
"where id = #{id,jdbcType=VARCHAR}"
})
@Results({
@Result(column="id", property="id", jdbcType=JdbcType.VARCHAR, id=true),
@Result(column="company_id", property="companyId", jdbcType=JdbcType.VARCHAR),
@Result(column="face_image", property="faceImage", jdbcType=JdbcType.VARCHAR),
@Result(column="auth_salt", property="authSalt", jdbcType=JdbcType.VARCHAR),
@Result(column="last_login_ip", property="lastLoginIp", jdbcType=JdbcType.VARCHAR),
@Result(column="last_login_time", property="lastLoginTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="is_delete", property="isDelete", jdbcType=JdbcType.INTEGER),
@Result(column="regist_time", property="registTime", jdbcType=JdbcType.TIMESTAMP)
})
User selectByPrimaryKey(String id);
上面的例子可以看到,数据库中的company_id 字段和实体类中定义的 companyId 属性的名称不一致,需要Result 转换。
以上就是项目中常用的增、删、改、查的操作, 其实这些在基本的方法不需要手动写,用前面讲过的mybatis generator 自动生成即可。讲这些主要是熟悉这些常用的注解。
传参方式
上面介绍了mybatis 常用的注解,如何实现增删改查的操作,相信很多人会有疑问了: mybatis 是如何将参数传递到 SQL 中的呢,都有哪几种传参方式呢? 下面就来一一介绍mybatis 注解版的传参方式。
1、直接传参
对于单个参数的方法,可直接使用 #{id} 的方式接收同名的变量参数。
@Delete("delete from sys_user where id = #{id,jdbcType=VARCHAR}")
int deleteByPrimaryKey(String id);
2、使用 @Param 注解
@Param注解的作用是给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中 。如果你的方法有多个参数,@Param 注解 会在方法的参数上就能为它们取自定义名字,参数则先以 "param" 作前缀,再加上它们的参数位置作为参数别名。例如, #{param1}、 #{param2},这个是默认值。如果注解是 @Param("person"),那么参数就会被命名为 #{person}。
@Select("SELECT * FROM sys_user WHERE username = #{username} and password = #{password}")
List<User> getListByUserSex(@Param("username") String userName, @Param("password") String password);
// 不自定义param 时,默认使用 param + 参数序号 或者 0,1,值就是参数的值。
@Select("SELECT * FROM sys_user WHERE username = #{param1} and password = #{param2}")
List<User> getListByUserSex(String userName, String password);
3、Map 传值
需要传送多个参数时,也可以考虑使用 Map的形式。
@Select("SELECT * FROM sys_user WHERE username=#{username} AND password = #{password}")
List<User> getListByNameAndSex(Map<String, Object> map);
调用时将参数依次加入到 Map 中即可。
Map param= new HashMap();
param.put("username","admin");
param.put("password","");
List<User> users = userMapper.getListByNameAndSex(param)
4、使用pojo对象
使用pojo对象传参是比较常用的传参方式。像上面的insert、update 等方法。都是直接传入user对象。
@Update({
"update sys_user",
"set company_id = #{companyId,jdbcType=VARCHAR},",
"username = #{username,jdbcType=VARCHAR},",
"password = #{password,jdbcType=VARCHAR},",
"nickname = #{nickname,jdbcType=VARCHAR},",
"age = #{age,jdbcType=INTEGER},",
"sex = #{sex,jdbcType=INTEGER},",
"job = #{job,jdbcType=INTEGER},",
"face_image = #{faceImage,jdbcType=VARCHAR},",
"province = #{province,jdbcType=VARCHAR},",
"city = #{city,jdbcType=VARCHAR},",
"district = #{district,jdbcType=VARCHAR},",
"address = #{address,jdbcType=VARCHAR},",
"auth_salt = #{authSalt,jdbcType=VARCHAR},",
"last_login_ip = #{lastLoginIp,jdbcType=VARCHAR},",
"last_login_time = #{lastLoginTime,jdbcType=TIMESTAMP},",
"is_delete = #{isDelete,jdbcType=INTEGER},",
"regist_time = #{registTime,jdbcType=TIMESTAMP}",
"where id = #{id,jdbcType=VARCHAR}"
})
int updateByPrimaryKey(User record);
以上,就是Mybatis 传参的四种方式。根据方法的参数选择合适的传值方式。
动态 SQL
实际项目中,除了使用一些常用的增删改查的方法之外,有些复杂的需求,可能还需要执行一些自定义的动态sql。mybatis 除了提供了@Insert、@Delete 这些常用的注解,还提供了多个注解如:@InsertProvider,@UpdateProvider,@DeleteProvider和@SelectProvider,用来建立动态sql 和让 mybatis 执行这些sql 的注解。下面就来实现按字段更新的功能。
1、首先在 UserSqlProvider 中创建 拼接sql的方法。
public String updateByPrimaryKeySelective(User record) {
BEGIN();
UPDATE("sys_user");
if (record.getCompanyId() != null) {
SET("company_id = #{companyId,jdbcType=VARCHAR}");
}
if (record.getUsername() != null) {
SET("username = #{username,jdbcType=VARCHAR}");
}
if (record.getPassword() != null) {
SET("password = #{password,jdbcType=VARCHAR}");
}
if (record.getNickname() != null) {
SET("nickname = #{nickname,jdbcType=VARCHAR}");
}
if (record.getAge() != null) {
SET("age = #{age,jdbcType=INTEGER}");
}
if (record.getSex() != null) {
SET("sex = #{sex,jdbcType=INTEGER}");
}
if (record.getJob() != null) {
SET("job = #{job,jdbcType=INTEGER}");
}
if (record.getFaceImage() != null) {
SET("face_image = #{faceImage,jdbcType=VARCHAR}");
}
if (record.getProvince() != null) {
SET("province = #{province,jdbcType=VARCHAR}");
}
if (record.getCity() != null) {
SET("city = #{city,jdbcType=VARCHAR}");
}
if (record.getDistrict() != null) {
SET("district = #{district,jdbcType=VARCHAR}");
}
if (record.getAddress() != null) {
SET("address = #{address,jdbcType=VARCHAR}");
}
if (record.getAuthSalt() != null) {
SET("auth_salt = #{authSalt,jdbcType=VARCHAR}");
}
if (record.getLastLoginIp() != null) {
SET("last_login_ip = #{lastLoginIp,jdbcType=VARCHAR}");
}
if (record.getLastLoginTime() != null) {
SET("last_login_time = #{lastLoginTime,jdbcType=TIMESTAMP}");
}
if (record.getIsDelete() != null) {
SET("is_delete = #{isDelete,jdbcType=INTEGER}");
}
if (record.getRegistTime() != null) {
SET("regist_time = #{registTime,jdbcType=TIMESTAMP}");
}
WHERE("id = #{id,jdbcType=VARCHAR}");
return SQL();
}
2、Mapper 中引入 updateByPrimaryKeySelective 方法
@UpdateProvider(type=UserSqlProvider.class, method="updateByPrimaryKeySelective")
int updateByPrimaryKeySelective(User record);
说明:
type:动态⽣成 SQL 的类
method:类中具体的方法名
以上,就是使用sqlprovider 动态创建sql,除了示例中的 @UpdateProvider ,,还有 @InsertProvider、 @SelectProvider 、@DeleteProvider 提供给插入、查询、删除的时使用。
最后
上面,介绍了使用mybatis 常用注解实现增、删、改、查。以及mybatis 常用的四种参数传递方式。
这个系列课程的完整源码,也会提供给大家。大家关注我的微信公众号(架构师精进),回复:springboot源码。获取这个系列课程的完整源码。
Spring Boot入门系列(十九)整合mybatis,使用注解实现动态Sql、参数传递等常用操作!的更多相关文章
- Spring Boot入门系列(九)如何实现异步执行任务
前面介绍了Spring Boot 如何整合定时任务,不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/1657780.htm ...
- Spring Boot入门系列(十七)整合Mybatis,创建自定义mapper 实现多表关联查询!
之前讲了Springboot整合Mybatis,介绍了如何自动生成pojo实体类.mapper类和对应的mapper.xml 文件,并实现最基本的增删改查功能.mybatis 插件自动生成的mappe ...
- Spring Boot入门系列(二十)快速打造Restful API 接口
spring boot入门系列文章已经写到第二十篇,前面我们讲了spring boot的基础入门的内容,也介绍了spring boot 整合mybatis,整合redis.整合Thymeleaf 模板 ...
- Spring Boot入门系列(十六)使用pagehelper实现分页功能
之前讲了Springboot整合Mybatis,然后介绍了如何自动生成pojo实体类.mapper类和对应的mapper.xml 文件,并实现最基本的增删改查功能.接下来要说一说Mybatis 的分页 ...
- Spring Boot 2.X(十九):集成 mybatis-plus 高效开发
前言 之前介绍了 SpringBoot 整合 Mybatis 实现数据库的增删改查操作,分别给出了 xml 和注解两种实现 mapper 接口的方式:虽然注解方式干掉了 xml 文件,但是使用起来并不 ...
- Spring Boot入门系列(十三)如何实现事务
前面介绍了Spring Boot 中的整合Mybatis并实现增删改查.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/1 ...
- Spring Boot入门系列(十八)整合mybatis,使用注解的方式实现增删改查
之前介绍了Spring Boot 整合mybatis 使用xml配置的方式实现增删改查,还介绍了自定义mapper 实现复杂多表关联查询.虽然目前 mybatis 使用xml 配置的方式 已经极大减轻 ...
- Spring Boot 入门系列(二十三)整合Mybatis,实现多数据源配置!
d之前介绍了Spring Boot 整合mybatis 使用注解方式配置的方式实现增删改查以及一些复杂自定义的sql 语句 .想必大家对spring boot 项目中,如何使用mybatis 有了一定 ...
- Spring Boot 入门(十):集成Redis哨兵模式,实现Mybatis二级缓存
本片文章续<Spring Boot 入门(九):集成Quartz定时任务>.本文主要基于redis实现了mybatis二级缓存.较redis缓存,mybaits自带缓存存在缺点(自行谷歌) ...
随机推荐
- android studio 部分问题及解决方案
1 启动多个虚拟机后开启指定端口的虚拟机 https://blog.csdn.net/chuyouyinghe/article/details/72958004 adb devic ...
- gerrit安装指南
Gerrit的基本介绍 Gerrit 是一个Git服务器,它基于 git 版本控制系统,使用网页界面来进行审阅工作.Gerrit 旨在提供一个轻量级框架,用于在代码入库之前对每个提交进行审阅,更改将上 ...
- 从包含10个无符号数的字节数组array中选出最小的一个数存于变量MIN中,并将该数以十进制形式显示出来。
问题 从包含10个无符号数的字节数组array中选出最小的一个数存于变量MIN中,并将该数以十进制形式显示出来. 代码 data segment arrey db 0,1,2,4,6,5,7,9,8, ...
- C#与网络相关的两个监听的事件
今天遇到一个问题,当网络连接有问题的时候设计软件向用户发送通知,查了资料发现了两个相关的事件分享一下. 一.System.Net.NetworkInformation命名空间下的NetworkChan ...
- 京东架构师:日均 5 亿查询量的ElasticSearch架构如何设计?
作者:张sir 来源:京东技术(id:jingdongjishu) 1. 背景 京东到家订单中心系统业务中,无论是外部商家的订单生产,或是内部上下游系统的依赖,订单查询的调用量都非常大,造成了订单数 ...
- 包管理Go module的使用
我用 Golang 的 Web 框架 Iris 写项目时,发现下载依赖老是失败原因是被墙了(可以参考上一篇 https://www.cnblogs.com/ser0632/p/11374790.htm ...
- log4net用法实例
内容转载自:https://www.cnblogs.com/youring2/archive/2011/04/27/2030424.html 1.引用log4net.dll 2.在AssemblyIn ...
- 关于Exceptionless日志收集框架如何关闭磁盘缓存
问题:在使用Exceptionless的时候,Exception在收集到日志时会默认在appdata里面缓存当条日志的缓存文件,时间久了之后,如果收集到的日志越多磁盘的空间就会不足. 我使用的环境是 ...
- CI4框架应用二 - 项目目录
我们之前搭建好了CI4的开发环境,下面我们来看一下CI4的目录结构. Administrator@PC- MINGW64 /c/wamp64/www/ci4 $ ls -l total drwxr-x ...
- JDK11.0.7下载及安装详细教程(win10)
0.背景知识 JRE: Java Runtime Environment JDK:Java Development Kit JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库. ...