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这个包
随机推荐
- kubernetes进阶之七:Service
1.概述 Service也是Kubernetes里的最核心的资源对象之一,Kubernetes里的每个Service其实就是我们经常提起的微服务架构中的一个“微服务”,之前我们所说的Pod.RC等资源 ...
- Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现
自Spring Cloud Alibaba发布第一个Release以来,就备受国内开发者的高度关注.虽然Spring Cloud Alibaba还没能纳入Spring Cloud的主版本管理中,但是凭 ...
- Java开发笔记(五十七)因抽象方法而产生的抽象类
前面介绍了类的常见用法,令人感叹面向对象的强大,几乎日常生活中的所有事物,都可以抽象成Java的基类及其子类.然而抽象操作也有副作用,就是某个抽象而来的行为可能是不确定的,比如半夜鸡叫,如果是公鸡则必 ...
- Spring框架基础(上)
spring是开源对轻量级框架 spring核心主要两部分 aop 面向切面编程,扩展功能不是修改源代码实现 aop采用横向抽取机制,取代了传统纵向继承体系重复代码(性能监视.事务管理.安全检查.缓存 ...
- 基于WanAndroid开放API实现的文章阅读APP
简介 基于WanAndroid开放API开发的技术文章阅读App.主要功能包括:首页.体系.项目.公众号.搜索.登录.收藏.夜间模式等. 用到的第三方框架 RxJava RxAndroid Retro ...
- Django数据库--事务及事务回滚
数据库的读写操作中,事务在保证数据的安全性和一致性方面起着关键的作用,而回滚正是这里面的核心操作.Django的ORM在事务方面也提供了不少的API.有事务出错的整体回滚操作,也有基于保存点的部分回滚 ...
- HTTP与HTTPS介绍
文章大纲 一.HTTP和HTTPS的基本概念二.HTTP缺点三.HTTPS介绍四.免费HTTPS证书推荐 一.HTTP和HTTPS的基本概念 HTTP:是互联网上应用最为广泛的一种网络协议,是一个 ...
- JVM内存管理 《深入分析java web 技术内幕》第八章
8.1 物理内存与虚拟内存 物理内存RAM(随机存储器),寄存单元为寄存器,用于存储计算单元执行指令的中间结果. 连接处理器和RAM或者处理器和寄存器的是地址总线,这个地址的宽度影响了物理地址的索引范 ...
- git上传新项目到coding
1:coding.net注册账号,并创建项目.可以将readme.txt打上勾 2:cd到本机的项目文件夹下 在git中代表workspace 3:mac用户用ls -all ,linux用户用ll ...
- linux备份还原命令
使用范围:1.可以作为系统还原点,还原到备份时的状态 2.系统完全损坏后无法启动,通过引导盘恢复 一.备份还原系统命令 方法一: 备份:tar cvpzf backup.tgz --exclude=/ ...