spring boot整合mybatis基于注解开发以及动态sql的使用
让我们回忆一下上篇博客中mybatis是怎样发挥它的作用的,主要是三类文件,第一mapper接口,第二xml文件,第三全局配置文件(application.properties),而今天我们就是来简化mybatis的工作的——利用注解替代xml配置文件。
先贴出mapper接口代码
@Mapper
public interface UserMapper { //获取用户名单
public List<User> getUser() throws Exception;
//根据id删除用户
public void deleteUser(int id)throws Exception;
//新增用户
public void addUser(User user)throws Exception;
//修改用户信息
public void updateUser(User user) throws Exception;
}
相较于上次的代码新增了一个修改用户信息的接口,然而怎么做才能替代xml呢???
针对以上的增删改查的操作,有四个注解@Select、@Delete、@Insert、@Update,在注解中加上之前在xml中写的sql就行了,所以完整的mapper接口文件如下
@Mapper
public interface UserMapper { //获取用户名单
@Select("select * from user")
public List<User> getUser() throws Exception;
//根据id删除用户
@Delete("delete from user where id = #{id}")
public void deleteUser(int id)throws Exception;
//新增用户
@Insert("insert into user(id,username,age)values(#{id},#{username},#{age})")
public void addUser(User user)throws Exception;
//修改用户信息
@Update("update user set username = #{name} where id = #{id}")
public void updateUser(User user) throws Exception;
}
剩下的service和controller中的代码很简单,和xml开发中的写法保持一致。需要值得注意的是不要忘记在各个接口和类中类名前的位置加上对应的注解,@Mapper、@Service、@Component等,不然spring是扫描不到的。这里有个小技巧,如果在启动类中加上注解@MapperScan(“com.XX.dao”),即可以省去@Mapper注解
说完了注解的开发我们来看一下这样的需求,如果我们要往数据库中更新一个对象,前台传过来的对象中有几个属性没有赋值,所以我们controller接收时就会将这几个属性置空,而我们需要更新不为空的属性,这时该怎么办??当然可以在service中将这个对象处理后再更新到数据库中,但是其实动态sql就可以直接解决这个问题。首先将问题分个类
if+set/where
例如现在前台将这样一个对象传过来
{
"id":1,
"age":12
}
我控制器的方法为
//更新用户
public String updateUser(User user)throws Exception{
userService.updateUser(user);
return "id为"+user.getId()+"的用户更新了";
}
如果我直接更新到后台显然会把这条记录之前的用户名给覆盖为空(在数据库允许该字段为空的情况下),所以看直接来看我的动态sql代码
<update id="updateUser" parameterType="com.fc.pojo.User">
update user set
<if test = "username != null">
user.username = #{username},
</if>
<if test = "age != 0">
user.age = #{age}
</if>
where id = #{id}
</update>
这样的sql拼接代码看起来很简单,但是有一个问题,如果age属性为0(前台如果不传age属性的话默认赋值为0)的话,最终sql语句会变成 update user set user.username =?,where id = ?
这样显然也是不对的,所以mybatis为我们提供了<set></set>标签将多余的逗号去掉,所以最终的动态sql变成
<update id="updateUser" parameterType="com.fc.pojo.User">
update user
<set>
<if test = "username != null">
user.username = #{username},
</if>
<if test = "age != 0">
user.age = #{age}
</if>
</set>
where id = #{id}
</update>
这样就解决了我们的问题了。同理在select语句中,也有这样的问题
<select id="getUser" parameterType="com.fc.pojo.User" resultType="com.fc.pojo.User">
select * from user where
<if test="username != null">
username=#{username}
</if> <if test="age!= null">
and age=#{age}
</if>
</select>
如果age为空的话sql就变成了select * from user where and age=?,所以要加上<where></where>标签,这样改进后的xml就是
<select id="getUser" parameterType="com.fc.pojo.User" resultType="com.fc.pojo.User">
select * from user
<where>
<if test="username != null">
username=#{username}
</if> <if test="age!= null">
and age=#{age}
</if>
</where>
</select>
foreach
我们在开发的时候经常会遇到这样的需求,删除多个对象,前台直接传一个对象id的集合,这个时候常规的做法是对集合处理,将id拿出来一个个删掉,其实也可以将集合放入一个包装类中,直接把包装类作为parameterType传入xml中,在xml中处理id集合。下面是包装类,我加上了数组的方式,不仅是id集合,还有id数组,都可以用这种方法来做
public class UserVo {
private List<Integer>idList;//id集合
private int[]idArray; //id数组
public List<Integer> getIdList() {
return idList;
}
public void setIdList(List<Integer> idList) {
this.idList = idList;
}
public int[] getIdArray() {
return idArray;
}
public void setIdArray(int[] idArray) {
this.idArray = idArray;
}
}
而xml文件中要使用foreach标签,在el表达式中和js中好像都有类似的用法,用来做循环操作,需要注意的是collection的值应该和包装类中的属性名保持一致。具体代码如下
<!-- 以id集合删除用户 -->
<delete id="deleteByIdList" parameterType="com.fc.pojo.UserVo">
delete from user
where id in
<foreach item="id" collection="idList" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<!-- 以id数组删除用户 -->
<delete id="deleteByIdArray" parameterType="com.fc.pojo.UserVo">
delete from user
where id in
<foreach item="id" collection="idArray" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
然后是Controller代码
//删除id集合
@RequestMapping(value="deleteByIdList",method=RequestMethod.DELETE)
public String deleteByIdList(@RequestBody UserVo userVo)throws Exception{
userService.deleteByIdList(userVo);
return "id列表里的用户都删掉了";
}
//删除id数组
@RequestMapping(value="deleteByIdArray",method=RequestMethod.DELETE)
public String deleteByIdArray(@RequestBody UserVo userVo)throws Exception{
userService.deleteByIdArray(userVo);
return "id数组里的用户都删掉了";
}
mapper接口和service的代码我就不贴了,套路跟之前都是一样的
最后是用来测试的json,第一个是测数组的,第二个测集合的
{
"idArray":[1,2,3]
}
{
"idList":[1,2,3]
}
sql片段
sql片段就是将一段重复率较高的sql抽取出来,供别的sql调用,这样可以有效地提高代码的复用率,话不多说,比如我们在新增一个用户时需要返回新增用户id,而我们之前的代码中已经有新增用户的sql,重复写一遍显得多此一举了,就可以把插入语句抽取出来供多次调用,代码如下,为了看到效果,我把之前的新增用户的语句也使用调用sql片段的方法来做
<sql id="base_insert_sql" >
insert into user(id,username,age)values(#{id},#{username},#{age})
</sql>
<!-- 新增用户 -->
<insert id="addUser" parameterType="com.fc.pojo.User">
<include refid="base_insert_sql" />
</insert>
<!-- 新增用户,返回用户id -->
<insert id="addUserWithId" parameterType="com.fc.pojo.User">
<selectKey keyProperty="id" resultType="int">
select LAST_INSERT_ID()
</selectKey>
<include refid="base_insert_sql" />
</insert>
好了,我在开发中常用到的动态sql就这些了,然后把以上xml文件转为注解的方法我就懒得去做了,有空再补上,最后安利一款测试软件Postman,挺好用的,公司也在用这个,以上的所有代码都是我用PostMan测试通过的,毕竟浏览器也发不了post和delete请求,所以嗯。。。就酱。
spring boot整合mybatis基于注解开发以及动态sql的使用的更多相关文章
- Spring Boot整合MyBatis(非注解版)
Spring Boot整合MyBatis(非注解版),开发时采用的时IDEA,JDK1.8 直接上图: 文件夹不存在,创建一个新的路径文件夹 创建完成目录结构如下: 本人第一步习惯先把需要的包结构创建 ...
- Spring Boot 整合 Mybatis Annotation 注解的完整 Web 案例
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 公司需要人.产品.业务和方向,方向又要人.产品.业务和方向,方向… 循环』 本文提纲一. ...
- Spring Boot整合Mybatis完成级联一对多CRUD操作
在关系型数据库中,随处可见表之间的连接,对级联的表进行增删改查也是程序员必备的基础技能.关于Spring Boot整合Mybatis在之前已经详细写过,不熟悉的可以回顾Spring Boot整合Myb ...
- Spring Boot 实战 —— MyBatis(注解版)使用方法
原文链接: Spring Boot 实战 -- MyBatis(注解版)使用方法 简介 MyBatis 官网 是这么介绍它自己的: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过 ...
- Spring Boot整合Mybatis并完成CRUD操作
MyBatis 是一款优秀的持久层框架,被各大互联网公司使用,本文使用Spring Boot整合Mybatis,并完成CRUD操作. 为什么要使用Mybatis?我们需要掌握Mybatis吗? 说的官 ...
- spring boot 整合 mybatis 以及原理
同上一篇文章一样,spring boot 整合 mybatis过程中没有看见SqlSessionFactory,sqlsession(sqlsessionTemplate),就连在spring框架整合 ...
- Spring Boot 整合mybatis时遇到的mapper接口不能注入的问题
现实情况是这样的,因为在练习spring boot整合mybatis,所以自己新建了个项目做测试,可是在idea里面mapper接口注入报错,后来百度查询了下,把idea的注入等级设置为了warnin ...
- Spring Boot系列(三):Spring Boot整合Mybatis源码解析
一.Mybatis回顾 1.MyBatis介绍 Mybatis是一个半ORM框架,它使用简单的 XML 或注解用于配置和原始映射,将接口和Java的POJOs(普通的Java 对象)映射成数据库中的记 ...
- Spring Boot整合Mybatis报错InstantiationException: tk.mybatis.mapper.provider.base.BaseSelectProvider
Spring Boot整合Mybatis时一直报错 后来发现原来主配置类上的MapperScan导错了包 由于我使用了通用Mapper,所以应该导入通用mapper这个包
随机推荐
- [零]java8 函数式编程入门官方文档中文版 java.util.stream 中文版 流处理的相关概念
前言 本文为java.util.stream 包文档的译文 极其个别部分可能为了更好理解,陈述略有改动,与原文几乎一致 原文可参考在线API文档 https://docs.oracle.com/jav ...
- Java GUI 单机版五子棋
前言 刚开始学java时接触到GUI,一时兴起写了个五子棋,五子棋的关键点在于判断输赢,其他的都没什么,现在翻出来整理并记录下来,不足之处还望各位路过的大佬多多指教. 代码实现 代码不多,四百多行,全 ...
- webpack4.0各个击破(9)—— karma篇
webpack作为前端最火的构建工具,是前端自动化工具链最重要的部分,使用门槛较高.本系列是笔者自己的学习记录,比较基础,希望通过问题 + 解决方式的模式,以前端构建中遇到的具体需求为出发点,学习we ...
- celery4+django2定时任务
网上有很多celery + django实现定时任务的教程,不过它们大多数是基于djcelery + celery3的: 或者是使用django_celery_beat配置较为繁琐的. 显然简洁而高效 ...
- 第33章 密码学(Cryptography),密钥(Keys)和HTTPS - Identity Server 4 中文文档(v1.0.0)
IdentityServer依赖于几个加密机制来完成它的工作. 33.1 令牌签名和验证 IdentityServer需要非对称密钥对来签署和验证JWT.此密钥对可以是证书/私钥组合或原始RSA密钥. ...
- MEF 基础简介 一
前言 小编菜鸟级别的程序员最近感慨颇多,经历了三五春秋深知程序路途遥远而我沧海一粟看不到的尽头到不了的终点何处是我停留的驿站.说了段废话下面进入正题吧! 什么是MEF? MEF:全称Managed E ...
- chrome设置网页编码
新版的 chrome 没有这个设置选项,可以借助插件 charset 插件实现,到 web store 搜索安装即可.
- 【Webpack 杂谈】帮助文档翻译:Webpack的模块
页面出自Webpack官方文档(撰写时,是v4.1.1) 其实Webpack本身有中文文档,不知道是谁去撰写的,但是自己翻译一遍感觉更好理解. https://webpack.js.org/conce ...
- 算法题丨Remove Duplicates from Sorted Array
描述 Given a sorted array, remove the duplicates in-place such that each element appear only once and ...
- 42.Odoo产品分析 (四) – 工具板块(10) – 问卷(2)
查看Odoo产品分析系列--目录 接上一篇Odoo产品分析 (四) – 工具板块(10) – 问卷(1) 4 页面 即问卷,点开一项查看: 可以看出,网页就是问卷本身的子目录,其中指明了该目录包括哪 ...