MyBatisPlus Service层的CRUD

article/2025/9/23 18:08:49
会当凌绝顶,一览众山小

| @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 -

http://chatgpt.dhexx.cn/article/IlFBmQY1.shtml

相关文章

Service层控制事务

1.Service业务逻辑层&#xff1a; 1.业务概述&#xff1a; 代表用户完成的一个业务功能&#xff0c;可以由一个或多个DAO的调用组成。(软件所提供的一个功能都叫业务) 2.Service开发流程 2.事务&#xff1a; 在JDBC中&#xff0c;在Service层实现事务需要以下几个步骤&#xf…

SpringBoot项目中的controller层、dao层、server层的区别以及对应的功能

&#xff08;1&#xff09;各层简介 Dao层&#xff08;mapper层&#xff09; service层&#xff08;业务层&#xff09; controller层&#xff08;控制层&#xff09; Dao层 即数据持久层&#xff0c;对数据做持久化操作。也被称为mapper层。声明为接口。 dao层的作用为访问数据…

service层的作用是什么?是否可以省略

一个基本的java项目分成Controller层,service层,mapper层等,controller是控制器层,mapper是数据访问层,与数据库相关,进行对数据库的增删改查等操作,service层负责整合mapper层供外部调用,但因为先阶段所涉及的业务量较小,小小的业务涉及这么多层总觉得有些麻烦,于是…

DAO层和Service层的究极理解--这波我在大气层

注重版权&#xff0c;转载请注明原作者和原文链接 作者&#xff1a;码农BookSea 原文链接&#xff1a;https://blog.csdn.net/bookssea/article/details/107488749 先看后赞&#xff0c;养成习惯。 点赞收藏&#xff0c;人生辉煌。 说实话&#xff0c;学了挺久的MVC架构了&…

将网页保存为图片--修改

这里以Chrome浏览器为例 &#xff08;谷歌浏览器&#xff09; 打开需要保存为图片的网页 然后按F12&#xff0c;接着按CtrlShiftP 在红框内输入full 点击下面的“Capture full size screenshot”就可以保存整个网页为图片了 ** 发现不能全部保存网页** 解决方法如下 1.打…

网页保存为PDF遇到的问题(网页打印)

在浏览CSDN上某些干货满满的文章时&#xff0c;我们经常会想将其下载至本地然后反复学习&#xff0c;这时便可以通过浏览器自带的打印功能进行网页保存&#xff0c;但是往往在保存时得不到想要的效果。 问题描述&#xff1a; 本来想以PDF格式将自己的博文保存至本地&#xff…

使用谷歌Chrome浏览器将网页保存为html格式

现版本谷歌Chrome浏览器再也没有"Sava Page as MHTML"一说&#xff0c;将网页保存为MHT、MHTML、HTML格式有俩种途径&#xff1a; 1、下载Save As MHT插件&#xff0c;压缩完成之后在文件中找到后缀名.crx用谷歌浏览打开&#xff0c;然后逐个添加MHT、MHTML 2、鼠标…

牛逼!40行Python代码一键把html网页保存为pdf,太方便了!

公众号 “菜鸟学Python”, 设为 “星标” 第451篇原创&#xff0c;和30w一起学Python&#xff01; 最近临近开学了&#xff0c;大家都在忙着准备各种学习的资料&#xff0c;准备在新的学期好好学习&#xff0c;充实自己。小编身边的同学也是如此&#xff0c;最近&#xff0c;小…

怎么把网页保存成pdf格式-最简单操作

网页怎么保存成pdf格式&#xff0c;会有很多人下载插件&#xff0c;其实不需要那么复杂。只需要简单的两步就可以了。 第一步&#xff1a;打开网页后&#xff0c;鼠标点击右键按打印 第二步&#xff1a;在目标打印机框中更改成另存为pdf模式&#xff0c;点击保存就可以了&…

网页保存为pdf神器(可自定义编辑)—Print Edit WE

1 如何保存一个网页为pdf文件 对于一个网页&#xff0c;如果想保存为一个pdf或者打印&#xff0c;可以直接使用CTRLP即可。但是这样对应的问题就是&#xff0c;网页时全部内容都会被保存进来&#xff0c;包括一些无关的广告或者评论图片等等。例如&#xff1a; 这样就不可避免…

如何查看网页保存的密码

查看网页保存密码 第一种方式,是在浏览器设置查看登陆网页保存的密码,但是不同浏览器操作不同,再次介绍一种通用使用所有网站小白也能操作的方式:修改代码 第一种: 第二种: 再次以简书为例,所有保存密码的都可以适用 首先,要点击填写的账号,会自动弹出提示你点击填充账号密…

Chrome 谷歌浏览器将整个网页保存为图片

两步解决Chrome谷歌浏览器如何将整个网页保存为图片&#xff0c;再也不用慢慢截取一张张图片拼接啦~ 先在需要保存为图片的页面按 F12 打开开发者工具再按 ctrlshiftp 输入full 搜索选择Capture full size screenshot

如何将网页保存成mhtml格式

如何将网页保存成mhtml格式 网页归档&#xff08;英语&#xff1a;MIME HTML或MIME Encapsulation of Aggregate HTML Documents&#xff0c;又称单一档案网页或网页封 存档案&#xff09;为以多用途互联网邮件扩展格式&#xff0c;将一个多附件网页&#xff08;如包含大量图片…

[Chrome] 超级好用的网页保存插件

需求背景&#xff1a; 1、有时候断网&#xff0c;不能浏览自己收藏的文章&#xff1b; 2、有时候网站服务器维护&#xff0c;自己写的文章竟然也不能浏览&#xff1b; 3、有时候明明收藏了别人的文章&#xff0c;还重点标记了&#xff0c;过几天&#xff0c;结果找不到了&#…

edge保存网页html,微软Edge浏览器不支持网页保存功能怎么办?

微软 Edge 浏览器自发布以来一直在不断完善与改进中&#xff0c;在添加了扩展插件功能后&#xff0c;Edge 浏览器的功能性得到了显著改进&#xff0c;但对于某些用户来说&#xff0c;Edge 仍旧欠缺一项非常重要的特性——将网页保存至本地设备的功能。 “保存网页到本地”是一项…

保存html为pdf,将网页保存为PDF的几种方法

方法一 虚拟打印机打印(1) 优点&#xff1a;字体正常、公式正常、文字可选 不足&#xff1a;链接失效优点&#xff1a;字体正常、公式正常、文字可选 工具&#xff1a;IE 浏览器 Foxit Reader PDF Printer 步骤&#xff1a; 1.在网页空白处单击右键&#xff0c;选择“打印”。…

浏览器网页保存长图

在需要保存的网页页面&#xff0c;按F12&#xff0c;弹出开发者工具&#xff0c;再按ctrlshiftp&#xff0c;在弹出框输入“full”&#xff0c;选择弹出的“capture full size screenshot”&#xff0c;就可以保存需要的网页长图了

如何将网页保存为pdf

有的时候我们需要备份某一个网页&#xff0c;但是直接收藏有的时候源链接会被删除&#xff0c;如果保存成网页&#xff0c;文件又很多&#xff0c;保存成PDF格式是一个不错的选择&#xff0c;下面就跟大家分享一个简单的方法。 首先&#xff0c;点击浏览器右上角的…三个点 我…

python将网页保存为pdf,python-网页保存为pdf

今天用到是python的一个第三方库: pdfkit pdfkit 是一个十分强大的第三方库,只需要把网页的url(需要登录或其他特殊方式才能访问的除外)传入,仅靠它自己就能将网页保存为pdf。当然,pdfkit 库也支持文件和源码的传入,同样能将获取到的保存为pdf。 使用工具:pdfkit 环境准备…