会当凌绝顶,一览众山小

| @Author:TTODS

MyBatisPlus框架系列文章目录:

  • Springboot整合MybatisPlus

  • MyBatisPlus Mapper层的CRUD

  • MyBatisPlus Service层的CRUD(当前)

  • MyBatisPlus提供的分页功能

  • MyBatisPlus之字段填充

  • MyBatisPlus之逻辑删除

  • MyBatisPlus之乐观锁

  • [MyBatisPlus之代码生成器(近期发布)]


前言

与Mapper层类似,MybatisPlus也提供了具有通用CRUD功能的Service层接口.本文将介绍如何使用MybatisPlus提供的基类与接口构建我们的Service层,以及如何使用Service层的通用CRUD.

创建UserService接口

在包com.example.service中创建一个UserService接口,并使其继承mybatis-plus提供的IService<T>接口(T表示对应实体类类型)。

package com.example.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.example.pojo.User;public interface UserService extends IService<User> {}

创建UserServiceImpl类

在包com.example.service.impl中创建一个UserServiceImpl类,并使其继承mybatis-plus提供的ServiceImpl<M extends BaseMapper<T>, T>类(T表示对应实体类类型),并实现上一步中创建的UserService接口。然后加上@Service注解。

package com.example.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mapper.UserMapper;
import com.example.pojo.User;
import com.example.service.UserService;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}

创建好之后项目结构如下:

至此,虽然我们没有在UserService中内写任何代码,但它已经具备了mybatis-plus提供的基本的CRUD的功能。

Service层的CRUD

save方法

boolean save(T entity); // 插入一条记录
boolean saveBatch(Collection<T> entityList);// 插入(批量),默认分批大小为1000
boolean saveBatch(Collection<T> entityList, int batchSize);// 插入(批量)
public class ServiceCurdTests {@AutowiredUserService userService;@Testpublic void testSave(){// 创建实体类对象User user = new User();user.setName("Garrison");user.setAge(45);user.setEmail("garrsion@gmail.com");user.setGender(1);//  调用save方法userService.save(user);}
}

生成的sql语句及输出:

==>  Preparing: INSERT INTO user ( name, age, gender, email ) VALUES ( ?, ?, ?, ? )
==> Parameters: Garrison(String), 45(Integer), 1(Integer), garrsion@gmail.com(String)
<==    Updates: 1

查看数据库,修改成功。

saveOrUpdate方法

boolean saveOrUpdate(T entity); // TableId 注解存在更新记录,否插入一条记录
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdateBatch(Collection<T> entityList);// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);// 批量修改插入

saveOrUpdate测试1:

    @Testpublic void testSaveOrUpdate(){User user = new User();user.setId(7);user.setAge(1);userService.saveOrUpdate(user);}

生成的Sql代码:

==>  Preparing: SELECT id,name,age,gender,email FROM user WHERE id=?
==> Parameters: 7(Integer)
<==      Total: 1
==>  Preparing: UPDATE user SET age=? WHERE id=?
==> Parameters: 1(Integer), 7(Integer)
<==    Updates: 1

saveOrUpdate测试2:

    @Testpublic void testSaveOrUpdate1(){User user = new User();user.setId(8);user.setAge(1);userService.saveOrUpdate(user);}

生成的sql代码:

==>  Preparing: SELECT id,name,age,gender,email FROM user WHERE id=?
==> Parameters: 8(Integer)
<==      Total: 0
==>  Preparing: INSERT INTO user ( age ) VALUES ( ? )
==> Parameters: 1(Integer)
<==    Updates: 1

通过上面两个测试可以看出:updateOrSave方法会先运行一个Select语句,通过主键字段判断该条记录是否存在,若存在则运行Update语句,否则运行Insert语句,且实体类中为null的属性,不会更新。

remove方法

boolean remove(Wrapper<T> queryWrapper);// 根据 entity 条件,删除记录
boolean removeById(Serializable id); // 根据 ID 删除
boolean removeByMap(Map<String, Object> columnMap);// 根据 columnMap 条件,删除记录
boolean removeByIds(Collection<? extends Serializable> idList);// 删除(根据ID 批量删除)

update方法

boolean update(Wrapper<T> updateWrapper);// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(T updateEntity, Wrapper<T> whereWrapper);// 根据 whereWrapper 条件,更新记录
boolean updateById(T entity);// 根据 ID 选择修改
boolean updateBatchById(Collection<T> entityList);// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);// 根据ID 批量更新
    @Testpublic void update(){User user = new User();user.setName("Hailie");user.setAge(32);user.setGender(0);user.setEmail("haile@gmail.com");// 第一个参数实体类对象中的值将会生成对应的set子句userService.update(user,new UpdateWrapper<User>().eq("id",8));}

生成的sql:

==>  Preparing: UPDATE user SET name=?, age=?, gender=?, email=? WHERE (id = ?)
==> Parameters: Hailie(String), 32(Integer), 0(Integer), haile@gmail.com(String), 8(Integer)
<==    Updates: 1

查看数据库,修改成功。

一个奇奇怪怪的问题

假设我们使用boolean update(T updateEntity, Wrapper<T> whereWrapper)方法时,在第二个参数中使用UpdateWrappper且设置set与第一个实体类对象中参数冲突会怎么样呢?

本例只是本人学习过程中的突发奇想[doge]…高危代码…请勿模仿…[doge]

    @Testpublic void update01(){User user = new User();//在此设置年龄为30user.setAge(30);// 在第二个参数中设置年龄为29userService.update(user,new UpdateWrapper<User>().eq("id",8).set("age",29));}

生成的sql代码:

==>  Preparing: UPDATE user SET age=?, age=? WHERE (id = ?)
==> Parameters: 30(Integer), 29(Integer), 8(Integer)
<==    Updates: 1

还是可以成功运行,不过生成的sql语句中age被设置了两次,由于age=29在后面,所以最后数据库中的结果是29.

Get方法

根据条件查询一条记录

T getById(Serializable id);// 根据 ID 查询
T getOne(Wrapper<T> queryWrapper);// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper, boolean throwEx);// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);// 根据 Wrapper,查询一条记录

List方法

根据条件查询多条记录

List<T> list();// 查询所有
List<T> list(Wrapper<T> queryWrapper);// 查询列表
Collection<T> listByIds(Collection<? extends Serializable> idList);// 查询(根据ID 批量查询)
Collection<T> listByMap(Map<String, Object> columnMap);// 查询(根据 columnMap 条件)
List<Map<String, Object>> listMaps();// 查询所有列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);// 查询列表
List<Object> listObjs();// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);// 查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);// 根据 Wrapper 条件,查询全部记录

Page方法

请阅读~~<<mybatis-plus分页功能>>~~

Count方法

int count();// 查询总记录数
int count(Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询总记录数
@Test
public void testCount(){int total = userService.count();int male = userService.count(new QueryWrapper<User>().eq("gender",1));int female = userService.count(new QueryWrapper<User>().eq("gender", 0));System.out.println(String.format("用户总数: %d\n其中:\n\t男性:\t%d\n\t女性:\t%d",total,male,female));
}

生成的sql语句及输出

==>  Preparing: SELECT COUNT( 1 ) FROM user WHERE (gender = ?)
==> Parameters: 0(Integer)
<==      Total: 1
用户总数: 8
其中:男性:  5女性:    3

链式查询与链式更新

@Test
public void testChainQuery(){QueryChainWrapper<User> query = new QueryChainWrapper<>(userMapper);// 查询所有男性用户的id、name和ageList<User> users = query.select("id", "name", "age").eq("gender",0).list();for (User user : users) {System.out.println(user);}
}

生成的sql语句及输出:

@Test
public void testChainUpdate(){UpdateChainWrapper<User> query = new UpdateChainWrapper<>(userMapper);// 使所有女性用户年龄增加1query.setSql("age = age+1").eq("gender",1).update();
}

生成的sql语句:

==>  Preparing: UPDATE user SET age = age+1 WHERE (gender = ?)
==> Parameters: 1(Integer)
<==    Updates: 5

上一篇:MyBatisPlus Mapper层的CRUD
下一篇:MyBatisPlus提供的分页功能

- THE END -

MyBatisPlus Service层的CRUD相关推荐

  1. MyBatisPlus之Service层配置

    以下内容参考尚硅谷的https://www.bilibili.com/video/BV1y7411y7am视频 实体类为EduTeacher 1.service层接口 public interface ...

  2. MybatisPlus核心功能——实现CRUD增删改查操作 (包含条件构造器)

    条件构造器 一般都是用service层的方法,因为比mapper层的全.十分重要:Wrapper 记住查看输出的SQL进行分析 相当于创建一个构造器对象,然后讲需要查询or更新的条件写在里面,最后打包 ...

  3. SpringBoot项目拥抱Mybatis-Plus持久层框架实践

    本文目录 前言 自从 Mybatis-Plus推出以来,越来越多的公司在自己的项目中选择Mybatis-Plus框架替换了持久层框架Mybatis.因为Mybatis-Plus用起来既有Mybatis ...

  4. java action dao_java中Action层、Service层和Dao层的功能区分

    一.Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DA ...

  5. [转]JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分

    首先这是现在最基本的分层方式,结合了SSH架构.modle层就是对应的数据库表的实体类.Dao层是使用了Hibernate连接数据库.操作数据库(增删改查).Service层:引用对应的Dao数据库操 ...

  6. service 层 拼接的html 代码如何直接返回_软件系统的分层,有效降低层与层之间的依赖...

    在分解复杂的软件系统时,架构师和程序员用得最多的技术之一就是分层.个人学习开发的时候,软件系统大多数是三层架构,也就是大家非常熟悉的表现层.领域层(业务层).数据源层.随着互联网的发展,智能手机普及手 ...

  7. service层的作业+mybatis中的重要组件

    一.JavaWeb中service层的作用 MVC = Jsp + Servlet + JavaBean 其中jsp View,servlet Controller,javaBean 是一个可复用的j ...

  8. SpringBoot框架分层(View层、Controller层、Service层、Mapper层、pojo层)

    SpringBoot框架一般分为View层.Controller层.Service层.Mapper层.pojo层. View层:视图层,根据接到的数据展示页面给用户 Controller层:响应用户需 ...

  9. Dao层service层controller层mannager层和biz层详解

    本篇文章内容 1.阿里开发手册关于应用分层的部分 2.对于阿里应用分层的理解 1.阿里开发手册关于应用分层的介绍 1.开放接口层: 可直接封装 Service 方法暴露成 RPC 接口:通过 Web ...

最新文章

  1. 系统异常设计规范与原则
  2. 全国计算机等级考试第3套,全国计算机等级考试四级计算机网络第3套试题
  3. php下curl与file_get_contents性能对比
  4. #ifdef __cplusplus
  5. 解析jsonarra_使用JSONReader或JSONObject / JSONArray解析JSON数据
  6. 拉格朗日差值法----算法学习
  7. 【客户下单】后台提供webservice服务接收数据
  8. 2.Android的学习(Android的环境搭建)
  9. Web Service简洁版调用公开手机api
  10. JavaScript 中的 require / exports、import / export、浅谈JavaScript、ES5、ES6
  11. oracle视图用法,Oracle视图用法示例
  12. 电脑c盘怎么清理_电脑C盘内存不足?三分钟教你彻底清理C盘空间,瞬间多出10个G...
  13. mac安装ffmpeg
  14. Effective C# 原则12:选择变量初始化而不是赋值语句
  15. 阿里云云计算 31在线实验--弹性伸缩(AS)初体验
  16. Linux学习笔记:wc查看文件字节数、字数、行数
  17. 蓝牙模块配置串口通讯
  18. 世界超长经典名车荟萃
  19. Mac访问NTFS文件系统的移动硬盘
  20. 北方工业大学计算机复试分数线,北方工业大学2017年复试分数线

热门文章

  1. 面向新手的CNN入门指南(一)
  2. 23-pytest-清空allure历史报告
  3. accessToken refreshToken简单使用源码demo,双token刷新及有效时间设置
  4. ip的mysql字段_MySQL 对 IP 字段的排序问题
  5. Linux下的二进制文件比较工具
  6. Money Pro for Mac(理财应用程序)
  7. UrlRewrite:重写url,实现伪静态、缩短URL、高安全性
  8. Android护眼模式(argb)
  9. (数据结构)[python](11)----链表与栈
  10. python调用百度翻译-python3调用百度翻译API实时翻译的实例代码