让我们回忆一下上篇博客中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的使用的更多相关文章

  1. Spring Boot整合MyBatis(非注解版)

    Spring Boot整合MyBatis(非注解版),开发时采用的时IDEA,JDK1.8 直接上图: 文件夹不存在,创建一个新的路径文件夹 创建完成目录结构如下: 本人第一步习惯先把需要的包结构创建 ...

  2. Spring Boot 整合 Mybatis Annotation 注解的完整 Web 案例

    摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 公司需要人.产品.业务和方向,方向又要人.产品.业务和方向,方向… 循环』 本文提纲一. ...

  3. Spring Boot整合Mybatis完成级联一对多CRUD操作

    在关系型数据库中,随处可见表之间的连接,对级联的表进行增删改查也是程序员必备的基础技能.关于Spring Boot整合Mybatis在之前已经详细写过,不熟悉的可以回顾Spring Boot整合Myb ...

  4. Spring Boot 实战 —— MyBatis(注解版)使用方法

    原文链接: Spring Boot 实战 -- MyBatis(注解版)使用方法 简介 MyBatis 官网 是这么介绍它自己的: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过 ...

  5. Spring Boot整合Mybatis并完成CRUD操作

    MyBatis 是一款优秀的持久层框架,被各大互联网公司使用,本文使用Spring Boot整合Mybatis,并完成CRUD操作. 为什么要使用Mybatis?我们需要掌握Mybatis吗? 说的官 ...

  6. spring boot 整合 mybatis 以及原理

    同上一篇文章一样,spring boot 整合 mybatis过程中没有看见SqlSessionFactory,sqlsession(sqlsessionTemplate),就连在spring框架整合 ...

  7. Spring Boot 整合mybatis时遇到的mapper接口不能注入的问题

    现实情况是这样的,因为在练习spring boot整合mybatis,所以自己新建了个项目做测试,可是在idea里面mapper接口注入报错,后来百度查询了下,把idea的注入等级设置为了warnin ...

  8. Spring Boot系列(三):Spring Boot整合Mybatis源码解析

    一.Mybatis回顾 1.MyBatis介绍 Mybatis是一个半ORM框架,它使用简单的 XML 或注解用于配置和原始映射,将接口和Java的POJOs(普通的Java 对象)映射成数据库中的记 ...

  9. Spring Boot整合Mybatis报错InstantiationException: tk.mybatis.mapper.provider.base.BaseSelectProvider

    Spring Boot整合Mybatis时一直报错 后来发现原来主配置类上的MapperScan导错了包 由于我使用了通用Mapper,所以应该导入通用mapper这个包

随机推荐

  1. leetcode — unique-binary-search-trees-ii

    ``` import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util ...

  2. ASP.NET Core教程【二】从保存数据看Razor Page的特有属性与服务端验证

    前文索引:ASP.NET Core教程[一]关于Razor Page的知识 在layout.cshtml文件中,我们可以看到如下代码: <a asp-page="/Index" ...

  3. AppBoxFuture(二): Say goodbye to sql!

      信息管理类应用系统离不开关系数据存储,目前大家基本都使用的是传统的数据库如MySql.Postgres等.作者从事信息化建设十多年,个人认为传统的数据库存在以下的问题: 扩展问题:   系统数据的 ...

  4. Jenkins结合.net平台之ftp客户端

    上一节我们讲解了如何配置ftp服务端,本节我们讲解如何使用winscp搭建ftp客户端,为什么使用winscp而不是filezilla客户端版,前面我们简单说过,这里不再赘述. 下载winscp以后我 ...

  5. 第24章 退出 - Identity Server 4 中文文档(v1.0.0)

    注销IdentityServer就像删除身份验证cookie一样简单,但是为了完成联合注销,我们必须考虑将用户从客户端应用程序(甚至可能是上游身份提供者)中签名. 24.1 删除认证 要删除身份验证c ...

  6. [Go] golang的接口合约

    接口类型1.接口类型具体描述了一系列方法的集合,实现这些方法的具体类型是这个接口类型的实例2.一个类型如果拥有一个接口需要的所有方法,那么这个类型就实现了这个接口 package main impor ...

  7. asp.net DES加密解密

    数据加密标准DES加密算法是一种对称加密算法,DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小.这是一个迭代的分组密码,使用称为 Feistel 的技术,其中 ...

  8. Laravel5多图上传和Laravel5单图上传的功能实现

    Laravel5文件上传默认只能上传一张图片,但是有的时候我们需要一次性上传多图就不行了,我在网上看了很多关于laravel5图片上传的文章,很多都只是介绍laravel5单图上传,多图片上传介绍少之 ...

  9. arcgis for js开发之路径分析

    arcgis for js开发之路径分析 //方法封装 function routeplan(x1, x2, y1, y2, barrierPathArray, isDraw, callback) { ...

  10. 仿9GAG制作过程(三)

    有话要说: 这次准备讲述后台服务器的搭建以及前台访问到数据的过程. 成果: 准备: 安装了eclipse 安装了Tomcat7 安装了数据库管理工具:Navicat 搭建服务器: 用eclipse直接 ...