这篇主要是总结一下MybatisPlus一些常用的场景,目前主要有以下几点:

  • 完整的CURD操作示例
  • 逻辑删除功能示例
  • 自动填充功能示例
  • 分页插件功能示例

有关一些其它重要的功能比如 条件生成器主键策略通用枚举多数据源乐观锁多租户等功能可以看官方文档,官方文档已经写的很清楚了,而且每个功能点都有对应的项目示例。

示例准备

1、用户表

CREATE TABLE `user` (
`id` int unsigned AUTO_INCREMENT COMMENT '主键',
`username` varchar(128) COMMENT '用户名',
`phone` varchar(32) COMMENT '手机号',
`sex` char(1) COMMENT '性别',
`create_time` datetime COMMENT '创建时间',
`update_time` datetime COMMENT '更新时间',
`deleted` tinyint DEFAULT '0' COMMENT '1、删除 0、未删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1

2、创建对应实体

@Data
@Accessors(chain = true)
@TableName("user")
public class UserDO implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO)
private Integer id; /**
* 用户名
*/
@TableField("username")
private String username; /**
* 手机号
*/
@TableField("phone")
private String phone; /**
* 性别
*/
@TableField("sex")
private String sex; /**
* 创建时间
*/
@TableField("create_time")
private LocalDateTime createTime; /**
* 更新时间
*/
@TableField("update_time")
private LocalDateTime updateTime; /**
* 1、删除 0、未删除
*/
@TableField("deleted")
private Integer deleted;
}

3、创建Mapper

@Mapper
public interface UserMapper extends BaseMapper<UserDO> { }

其它有关代码这里就不粘贴了,具体看项目源码就可以了。

一、完整的CURD操作

public class UserServiceTest extends Base {

   @Autowired
private UserMapper mapper; @Test
public void insert() {
UserDO user = new UserDO();
user.setUsername("小小");
user.setPhone("18812345678");
user.setSex("女");
Assertions.assertThat(mapper.insert(user)).isGreaterThan(0);
// 成功直接拿回写的 ID
Assertions.assertThat(user.getId()).isNotNull();
} @Test
public void delete() {
mapper.deleteById(6);
mapper.delete(new LambdaQueryWrapper<UserDO>().eq(UserDO::getUsername, "张三"));
} @Test
public void update() {
//方式一: 根据id更新
mapper.updateById(new UserDO().setId(1).setPhone("13312345678"));
//方式二: 左边是需要更新的值 右边是where条件
mapper.update(
new UserDO().setDeleted(1), new LambdaQueryWrapper<UserDO>().eq(UserDO::getPhone, "18812345678")
);
//方式三:不创建User对象
mapper.update(null,new LambdaUpdateWrapper<UserDO>()
.set(UserDO::getPhone,"13111111111").set(UserDO::getCreateTime, LocalDateTime.now()).eq(UserDO::getUsername,"小小"));
} @Test
public void select() {
//1、根据主键获取
UserDO userDO = mapper.selectById(1);
//2、根据手机号获取 单个
UserDO userDO1 = mapper.selectOne(new LambdaQueryWrapper<UserDO>().eq(UserDO::getPhone, "13312345678"));
//3、获取集合
List<UserDO> userDOS = mapper.selectList(new LambdaQueryWrapper<UserDO>().eq(UserDO::getPhone, "13312345678"));
List<UserDO> userDOS1 = mapper.selectList(null);
} @Test
public void orderBy() {
//1、单个排序
List<UserDO> users = mapper.selectList(Wrappers.<UserDO>query().orderByAsc("create_time"));
//2、多字段排序
List<UserDO> users2 = mapper.selectList(Wrappers.<UserDO>query().orderByAsc(Lists.newArrayList("create_time","phone")));
//3、先按手机号升序排列,phone相同再按create_time降序排列
List<UserDO> users3 = mapper.selectList(Wrappers.<UserDO>query().orderByAsc("phone").orderByDesc("create_time"));
//4、Lambda实现方式,和3实现的效果是一样的。
List<UserDO> users4 = mapper.selectList(new LambdaQueryWrapper<UserDO>().orderByAsc(UserDO::getPhone).orderByDesc(UserDO::getCreateTime));
} @Test
public void groupBy() {
QueryWrapper<UserDO> wrapper = new QueryWrapper<>();
wrapper.select("phone, count(*) as total")
.groupBy("phone");
//注意要用 listMaps ,返回的是 Map<String,Object>
List<Map<String, Object>> maplist = mapper.selectMaps(wrapper);
} @Test
public void testSelectMaxId() {
QueryWrapper<UserDO> wrapper = new QueryWrapper<>();
wrapper.select("max(id) as id");
UserDO user = mapper.selectOne(wrapper);
}
}

二、逻辑删除功能

1、使用场景

这个场景是这样的,因为我们在设计表结构的时候都会有一个逻辑删除字段,比如上表中就有一个deleted字段,1=删除 0=未删除。

那我们在查询或者更新操作时,sql都会带上这个字段。

例如:

-- 更新
update user set sex='女' where id = 1 and deleted=0
-- 查询
select id,sex,username from user where deleted=0

既然都要带上,那是不是可以做成全局的,不用我们每个sql都手动添加deleted=0,这个条件。

2、使用方法

1、配置

例如: application.yml

mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 全局逻辑删除的实体字段名()
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

2、实体类字段上加上@TableLogic注解

    @TableLogic
private Integer deleted;

注意:since 3.3.0,配置后可以忽略不配置这步骤

3、示例

public class UserServiceDeleteTest extends Base {

   @Autowired
private UserMapper mapper; @Test
public void update() {
//方式一: 根据id更新
mapper.updateById(new UserDO().setId(1).setPhone("13312345678"));
//实际执行sql: UPDATE user SET phone=? WHERE id=? AND deleted=0
} @Test
public void select() {
//1、根据主键获取
UserDO userDO = mapper.selectById(1);
//实际执行sql: SELECT id,username,phone,sex,create_time,update_time,deleted FROM user WHERE id=? AND deleted=0
}
}

上面两条sql虽然没有加入deleted=0这个条件,但因为加了全局配置,所以会自动加上deleted=0条件。

三、自动填充功能

1、使用背景

我们在设计表的时候,会有创建人ID,创建人名称,创建时间,更新人ID,更新人名称,更新时间

我们在新增或者更新数据的时候,都会修改这些数据。所以我们也可以做成全局的。

2、使用方式

1、实体添加注解

   /**
* 创建时间
*/
@TableField(value = "create_time",fill = FieldFill.INSERT)
private LocalDateTime createTime; /**
* 更新时间
*/
@TableField(value = "update_time",fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;

FieldFill一共有4种属性,默认是DEFAULT

public enum FieldFill {
DEFAULT,
INSERT,
UPDATE,
INSERT_UPDATE;
}

2、自定义实现类 MyMetaObjectHandler

@Component
public class MyMetaObjectHandler implements MetaObjectHandler { @Override
public void insertFill(MetaObject metaObject) {
//设置属性值
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
} @Override
public void updateFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}

3、测试

  @Test
public void insert() {
UserDO user = new UserDO();
user.setUsername("小小");
user.setPhone("18812345678");
user.setSex("女");
Assertions.assertThat(mapper.insert(user)).isGreaterThan(0);
// 成功直接拿回写的 ID
Assertions.assertThat(user.getId()).isNotNull();
}

用上面这个测试用例,发现虽然这里没有插入创建时间和更新时间,但打印sql发现插入该属性。

==>  Preparing: INSERT INTO user ( username, phone, sex, create_time, update_time ) VALUES ( ?, ?, ?, ?, ? )
==> Parameters: 小小(String), 18812345678(String), 女(String), 2022-09-27T16:40:00.682(LocalDateTime), 2022-09-27T16:40:00.687(LocalDateTime)
<== Updates: 1

4、注意事项

  • 填充原理是直接给entity的属性设置值!!!
  • 注解则是指定该属性在对应情况下必有值,如果无值则入库会是null
  • MetaObjectHandler提供的默认方法的策略均为:如果属性有值则不覆盖,如果填充值为null则不填充
  • 字段必须声明TableField注解,属性fill选择对应策略,该声明告知Mybatis-Plus需要预留注入SQL字段
  • 填充处理器MyMetaObjectHandler在 Spring Boot 中需要声明@Component@Bean注入
  • update(T t,Wrapper updateWrapper)时t不能为空,否则自动填充失效

四、分页功能示例

1、配置类

@Configuration
public class MybatisPlusPageConfig {
/**
* 新的分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

2、示例

public class UserServicePageTest extends Base {

   @Autowired
private UserMapper mapper; @Test
public void page() {
Page<UserDO> page = new Page<>(1, 3);
Page<UserDO> result = mapper.selectPage(page, new LambdaQueryWrapper<UserDO>().eq(UserDO::getDeleted, 0));
}
}

这里有点需要注意: MybatisPlus 与 pagehelper 存在依赖 jsqlparser 冲突,不建议混用

项目地址: https://github.com/yudiandemingzi/spring-boot-study

MyBatisPlus常用功能总结!(附项目示例)的更多相关文章

  1. Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码)

    Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码)    转 https://blog.csdn.net/lhl1124281072/article/details/800 ...

  2. Echarts图表常用功能配置,Demo示例

    先看下效果图: 就如上图所示,都是些常用的基本配置. Legend分页,X轴设置,Y轴设置,底部缩放条设置, 数值显示样式设置,工具箱设置,自定义工具按钮, 绑定点击事件等等.这些配置代码中都做了简单 ...

  3. mybatis常用功能总结

    mybatis-plus常用功能总结-以User表为例 1.数据库 id name age email create_time update_time version deleted 1 mary 2 ...

  4. iOS项目开发常用功能静态库

    YHDeveloperTools iOS项目开发常用功能静态库 查看源码 功能方法: 1.字符检查 [NSString checkStringWithType:Email andTargetStrin ...

  5. Spring Boot从入门到实战:整合Web项目常用功能

    在Web应用开发过程中,一般都涵盖一些常用功能的实现,如数据库访问.异常处理.消息队列.缓存服务.OSS服务,以及接口日志配置,接口文档生成等.如果每个项目都来一套,则既费力又难以维护.可以通过Spr ...

  6. 项目中常用功能,如:流媒体、健康数据(步数等)等-b

    整理iOS开发中使用的各种流媒体和常用的高级功能.由于时间关系,目前只写了一部分功能,全部都采用的是系统方法,没用第三方,截图如下: screen1.png screen2.png 个人比较懒,不爱多 ...

  7. Spring Boot搭建Web项目常用功能

    搭建WEB项目过程中,哪些点需要注意: 1.技术选型: 前端:freemarker.vue 后端:spring boot.spring mvc 2.如何包装返回统一结构结果数据? 首先要弄清楚为什么要 ...

  8. 开源三维地球GIS引擎Cesium常用功能的开发

    Cesium是一个非常优秀的三维地球GIS引擎(开源且免费).能够加载各种符合标准的地图图层,瓦片图.矢量图等都支持.支持3DMax等建模软件生成的obj文件,支持通用的GIS计算:支持DEM高程图. ...

  9. Nginx常用功能

    3.Nginx常用功能 3.1 反向代理服务器 3.1.1.demo2 a.我在tomcat下部署了一个javaweb项目,tomcat安装的服务器IP为:192.168.37.136,部署的项目在t ...

  10. C#构造方法(函数) C#方法重载 C#字段和属性 MUI实现上拉加载和下拉刷新 SVN常用功能介绍(二) SVN常用功能介绍(一) ASP.NET常用内置对象之——Server sql server——子查询 C#接口 字符串的本质 AJAX原生JavaScript写法

    C#构造方法(函数)   一.概括 1.通常创建一个对象的方法如图: 通过  Student tom = new Student(); 创建tom对象,这种创建实例的形式被称为构造方法. 简述:用来初 ...

随机推荐

  1. P3730 曼哈顿交易 题解

    题目链接:曼哈顿交易 比较容易想的题,观察下首先不带修改,考虑维护的东西:次数作为权值,这玩意很显然很难在线维护,考虑下离线算法.看到这种和次数有关的权值,典型的单点加入和删除是非常好找到变化的,那么 ...

  2. 到什么程度才叫精通 Linux?

    大家好,我是陶朱公Boy,一个认真生活,总想超越自己的程序员. 前言 知乎上有一个提问:到什么程度才叫精通 Linux?                              ↓↓↓ 今天,我们就 ...

  3. JS Leetcode 213. 打家劫舍 II 题解分析,在动态规划基础上感受分治算法的魅力

    壹 ❀ 引 本题来自LeetCode 213. 打家劫舍 II,难度中等,属于前面我们做过的198. 打家劫舍的升级版,难度同样为中等,题目描述如下: 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内 ...

  4. NC50505 二叉苹果树

    题目链接 题目 题目描述 有一棵二叉苹果树,如果数字有分叉,一定是分两叉,即没有只有一个儿子的节点.这棵树共N个节点,标号1至N,树根编号一定为1. 我们用一根树枝两端连接的节点编号描述一根树枝的位置 ...

  5. NC16641 [NOIP2007]守望者的逃离

    题目链接 题目 题目描述 恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变.守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上.为了杀死守望者,尤迪安开始对这个荒岛施咒 ...

  6. fmt、变量、常量

    fmt包 fmt包主要用于打印数据,常用的有Printf.Print.Printf // 文件所属包 package main // 导入fmt包,主要用于打印数据 import "fmt& ...

  7. Java设计模式-建造者模式Builder

    介绍 建造者模式(Builder Pattern) 又叫生成器模式,是一种对象构建模式.它可以 将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方 法可以构造出不同表现(属性)的对象 ...

  8. 骨牌铺方格 SDUT

    状态转移方程:dp[i] = dp[i - 1] + dp[i - 2]. 当前行,可能是由上一行转移过来的,那么当前行就只能横着铺,所以方案数是dp[i - 1]. 当前行,可能是由i-2行转移过来 ...

  9. 以二进制文件安装K8S之部署Node服务

    概述 在Node上需要部署Docker.kubelet.kube-proxy,在成功加入Kubernetes集群后,还需要部署CNI网络插件.DNS插件等管理组件. 本节以将192.168.3.138 ...

  10. error接口

    // 实际上它是interface类型,这个类型有一个返回错误信息的单一方法: type error interface{ Error() string } 创建一个error最简单的方法就是调用er ...