当前位置: 首页 > news >正文

【MyBatis-Plus】快速精通Mybatis-plus框架—快速入门

大家在日常开发中应该能发现,单表的CRUD功能代码重复度很高,也没有什么难度。而这部分代码量往往比较大,开发起来比较费时。

因此,目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是MybatisPlus.

官方网站如下:

当然,MybatisPlus不仅仅可以简化单表操作,而且还对Mybatis的功能有很多的增强。可以让我们的开发更加的简单,高效。

通过今天的学习,我们要达成下面的目标:

  • 能利用MybatisPlus实现基本的CRUD

  • 会使用条件构建造构建查询和更新语句

  • 会使用MybatisPlus中的常用注解

  • 会使用MybatisPlus处理枚举、JSON类型字段

  • 会使用MybatisPlus实现分页

为了方便测试,我们先创建一个新的项目,并准备一些基础数据。

1.环境准备

复制课前资料提供好的一个项目到你的工作空间(不要包含空格和特殊字符):

然后用你的IDEA工具打开,项目结构如下:

注意配置一下项目的JDK版本为JDK11。首先点击项目结构设置:

在弹窗中配置JDK:

接下来,要导入两张表,在课前资料中已经提供了SQL文件:

对应的数据库表结构如下:

最后,在application.yaml中修改jdbc参数为你自己的数据库参数:

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: MySQL123
logging:level:com.itheima: debugpattern:dateformat: HH:mm:ss

2.快速开始

比如我们要实现User表的CRUD,只需要下面几步:

  • 引入MybatisPlus依赖

  • 定义Mapper

2.1引入依赖

MybatisPlus提供了starter,实现了自动Mybatis以及MybatisPlus的自动装配功能,坐标如下:

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency>

由于这个starter包含对mybatis的自动装配,因此完全可以替换掉Mybatis的starter。 最终,项目的依赖如下:

<dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>

2.2定义Mapper

为了简化单表CRUD,MybatisPlus提供了一个基础的BaseMapper接口,其中已经实现了单表的CRUD:

因此我们自定义的Mapper只要实现了这个BaseMapper,就无需自己实现单表CRUD了。 修改mp-demo中的com.itheima.mp.mapper包下的UserMapper接口,让其继承BaseMapper

代码如下:

package com.itheima.mp.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;public interface UserMapper extends BaseMapper<User> {
}

2.3测试

新建一个测试类,编写几个单元测试,测试基本的CRUD功能:

package com.itheima.mp.mapper;import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDateTime;
import java.util.List;@SpringBootTest
class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testvoid testInsert() {User user = new User();user.setId(5L);user.setUsername("Lucy");user.setPassword("123");user.setPhone("18688990011");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userMapper.insert(user);}@Testvoid testSelectById() {User user = userMapper.selectById(5L);System.out.println("user = " + user);}@Testvoid testSelectByIds() {List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L, 5L));users.forEach(System.out::println);}@Testvoid testUpdateById() {User user = new User();user.setId(5L);user.setBalance(20000);userMapper.updateById(user);}@Testvoid testDelete() {userMapper.deleteById(5L);}
}

可以看到,在运行过程中打印出的SQL日志,非常标准:

11:05:01  INFO 15524 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
11:05:02  INFO 15524 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
11:05:02 DEBUG 15524 --- [           main] c.i.mp.mapper.UserMapper.selectById      : ==>  Preparing: SELECT id,username,password,phone,info,status,balance,create_time,update_time FROM user WHERE id=?
11:05:02 DEBUG 15524 --- [           main] c.i.mp.mapper.UserMapper.selectById      : ==> Parameters: 5(Long)
11:05:02 DEBUG 15524 --- [           main] c.i.mp.mapper.UserMapper.selectById      : <==      Total: 1
user = User(id=5, username=Lucy, password=123, phone=18688990011, info={"age": 21}, status=1, balance=20000, createTime=Fri Jun 30 11:02:30 CST 2023, updateTime=Fri Jun 30 11:02:30 CST 2023)

3.常见注解

在刚刚的入门案例中,我们仅仅引入了依赖,继承了BaseMapper就能使用MybatisPlus,非常简单。但是问题来了: MybatisPlus如何知道我们要查询的是哪张表?表中有哪些字段呢?

大家回忆一下,UserMapper在继承BaseMapper的时候指定了一个泛型:

泛型中的User就是与数据库对应的PO.

MybatisPlus就是根据PO实体的信息来推断出表的信息,从而生成SQL的。默认情况下:

  • MybatisPlus会把PO实体的类名驼峰转下划线作为表名

  • MybatisPlus会把PO实体的所有变量名驼峰转下划线作为表的字段名,并根据变量类型推断字段类型

  • MybatisPlus会把名为id的字段作为主键

但很多情况下,默认的实现与实际场景不符,因此MybatisPlus提供了一些注解便于我们声明表信息。

3.1@TableName

说明:

  • 描述:表名注解,标识实体类对应的表

  • 使用位置:实体类

示例:

@TableName("user")
public class User {private Long id;private String name;
}

TableName注解除了指定表名以外,还可以指定很多其它属性:

属性

类型

必须指定

默认值

描述

value

String

""

表名

schema

String

""

schema

keepGlobalPrefix

boolean

false

是否保持使用全局的 tablePrefix 的值(当全局 tablePrefix 生效时)

resultMap

String

""

xml 中 resultMap 的 id(用于满足特定类型的实体类对象绑定)

autoResultMap

boolean

false

是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建与注入)

excludeProperty

String[]

{}

需要排除的属性名 @since 3.3.1

3.2@TableId

说明:

  • 描述:主键注解,标识实体类中的主键字段

  • 使用位置:实体类的主键字段

示例:

@TableName("user")
public class User {@TableIdprivate Long id;private String name;
}

TableId注解支持两个属性:

属性

类型

必须指定

默认值

描述

value

String

""

表名

type

Enum

IdType.NONE

指定主键类型

IdType支持的类型有:

描述

AUTO

数据库 ID 自增

NONE

无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)

INPUT

insert 前自行 set 主键值

ASSIGN_ID

分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)

ASSIGN_UUID

分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法)

ID_WORKER

分布式全局唯一 ID 长整型类型(please use ASSIGN_ID)

UUID

32 位 UUID 字符串(please use ASSIGN_UUID)

ID_WORKER_STR

分布式全局唯一 ID 字符串类型(please use ASSIGN_ID)

这里比较常见的有三种:

  • AUTO:利用数据库的id自增长

  • INPUT:手动生成id

  • ASSIGN_ID:雪花算法生成Long类型的全局唯一id,这是默认的ID策略

3.3@TableField

说明:

描述:普通字段注解

示例:

@TableName("user")
public class User {@TableIdprivate Long id;private String name;private Integer age;@TableField("isMarried")private Boolean isMarried;@TableField("concat")private String concat;
}

一般情况下我们并不需要给字段添加@TableField注解,一些特殊情况除外:

  • 成员变量名与数据库字段名不一致

  • 成员变量是以isXXX命名,按照JavaBean的规范,MybatisPlus识别字段时会把is去除,这就导致与数据库不符。

  • 成员变量名与数据库一致,但是与数据库的关键字冲突。使用@TableField注解给字段名添加````转义

支持的其它属性如下:

属性

类型

必填

默认值

描述

value

String

""

数据库字段名

exist

boolean

true

是否为数据库表字段

condition

String

""

字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s},参考(opens new window)

update

String

""

字段 update set 部分注入,例如:当在version字段上注解update="%s+1" 表示更新时会 set version=version+1 (该属性优先级高于 el 属性)

insertStrategy

Enum

FieldStrategy.DEFAULT

举例:NOT_NULL insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)

updateStrategy

Enum

FieldStrategy.DEFAULT

举例:IGNORED update table_a set column=#{columnProperty}

whereStrategy

Enum

FieldStrategy.DEFAULT

举例:NOT_EMPTY where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>

fill

Enum

FieldFill.DEFAULT

字段自动填充策略

select

boolean

true

是否进行 select 查询

keepGlobalFormat

boolean

false

是否保持使用全局的 format 进行处理

jdbcType

JdbcType

JdbcType.UNDEFINED

JDBC 类型 (该默认值不代表会按照该值生效)

typeHandler

TypeHander

类型处理器 (该默认值不代表会按照该值生效)

numericScale

String

""

指定小数点后保留的位数

4.常见配置

MybatisPlus也支持基于yaml文件的自定义配置,详见官方文档:

大多数的配置都有默认值,因此我们都无需配置。但还有一些是没有默认值的,例如:

  • 实体类的别名扫描包

  • 全局id类型

mybatis-plus:type-aliases-package: com.itheima.mp.domain.poglobal-config:db-config:id-type: auto # 全局id类型为自增长

需要注意的是,MyBatisPlus也支持手写SQL的,而mapper文件的读取地址可以自己配置:

mybatis-plus:mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,当前这个是默认值。

可以看到默认值是classpath*:/mapper/**/*.xml,也就是说我们只要把mapper.xml文件放置这个目录下就一定会被加载。

例如,我们新建一个UserMapper.xml文件:

 然后在其中定义一个方法:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mp.mapper.UserMapper"><select id="queryById" resultType="User">SELECT * FROM user WHERE id = #{id}</select>
</mapper>

然后在测试类UserMapperTest中测试该方法:

@Test
void testQuery() {User user = userMapper.queryById(1L);System.out.println("user = " + user);
}

相关文章:

【MyBatis-Plus】快速精通Mybatis-plus框架—快速入门

大家在日常开发中应该能发现&#xff0c;单表的CRUD功能代码重复度很高&#xff0c;也没有什么难度。而这部分代码量往往比较大&#xff0c;开发起来比较费时。 因此&#xff0c;目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是…...

docker 安装kafka

运行容器 zookeeper: [rootk8s-master ~]# docker run -d --restartalways --log-driver json-file --log-opt max-size100m --log-opt max-file2 --name zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime zookeeper c603f292813cfd6e2b16fff88a9767cc86fc9bba34d82…...

容器内获得apiserver地址

1.容器的Env的KUBENETES_SERVICE_HOST字段 roottomcat01-69fc8f859b-w9btn:/tmp# env | grep KUBERNETES_SERVICE_HOST10.96.0.1 KUBERNETES_SERVICE_HOST10.96.0.12.通过域名查询 nslookup getent hosts roottomcat01-69fc8f859b-w9btn:/tmp# getent hosts kubernetes.def…...

linux服务端c++开发工具介绍(vscode版)

本文适合于有一定c开发经验&#xff0c;但是还不明确如何到linux服务端开发程序的同学。 一、vscode 几年前用的是ssh到云服务上&#xff0c;再用vim在云上开发的形式 ssh dongbeijing.dbj11.158.142.176 vim hello.c 现今&#xff0c;由于vscode比较好用&#xff0c;这几年…...

Linux常用命令大全

Linux常用命令大全 一、文件&目录管理1. 文件和目录操作命令2. 查看文件及内容处理命令3. 文件压缩及解压缩命令4. 搜索文件命令5. 其他 二、Linux 软件包管理三、用户管理1. 用户管理2. 查看系统用户登陆信息的命令 四、进程管理五、网络通信1. 基础网络操作命令2. 深入网…...

Python中取2023, 9, 1——2023, 10, 31的全部时间

使用datetime.date()函数定义了开始和结束日期。然后&#xff0c;我们使用datetime.timedelta()类创建了一个时间范围&#xff0c;其中n表示从开始日期到结束日期之间的天数。最后&#xff0c;我们使用一个for循环迭代时间范围内的日期&#xff0c;并打印每个日期。示例代码演示…...

创建django文件

1、在指定目录里打开终端&#xff0c;输入D:\Softwares\Anaconda3\envs\pytorch\Scripts\django-admin .exe startproject 名称 &#xff0c;即可在对应目录里创建django文件。...

全排列[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个不含重复数字的数组nums&#xff0c;返回其所有可能的全排列。你可以按任意顺序返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示例…...

mybatise-plus的id过长问题

一、问题情景 笔者在做mp插入数据库(id已设置为自增)操作时&#xff0c;发现新增数据的id过长&#xff0c;结果导致前端JS拿到的数据出现了精度丢失问题&#xff0c;原因是后端id的类型是Long。在网上查了一下&#xff0c;只要在该属性上加上如下注解就可以 TableId(value &q…...

图示矩阵分解

特征值与特征向量 设 A A A 是 n 阶矩阵&#xff0c;如果存在数 λ \lambda λ 和 n 维非零列向量 x x x&#xff0c;满足关系式&#xff1a; A x λ x ( 1 ) Ax \lambda x\quad\quad(1) Axλx(1) 则数 λ \lambda λ 称为矩阵 A A A 的特征值&#xff0c;非零向量 x…...

六、互联网技术——数据存储

文章目录 一、存储系统层次结构二、按照重要性分类三、磁盘阵列RAID三、RAID基础四、磁盘阵列分级五、数据备份与恢复六、容灾与灾难恢复 一、存储系统层次结构 常见的三层存储体系结构如下图所示&#xff0c;分为高速缓冲存储器、主存储器和外存储器。 二、按照重要性分类 …...

六、vpp 流表+负载均衡

草稿&#xff01;&#xff01;&#xff01; vpp node其实就是三个部分 1、plugin init 2、set command 3、function 实现功能&#xff0c;比如这里的流表 今天我们再用VPP实现一个流表的功能 一、流表 1.1流表----plugin init VLIB_REGISTER_NODE 注册流表节点 // 注册流…...

word已排序好的参考文献,插入新的参考文献,序号更新

原排序好的文献序号。 现在在3号后面插入一个新文献。4&#xff0c;5号应该成为5&#xff0c;6 这时在3号后面&#xff0c;回车&#xff0c;就会自动的增长。如下图&#xff1a; 但是如果手滑&#xff0c;把[4]删除了如何排序&#xff1f;&#xff1f; 如下图&#xff1a; …...

二叉树的顺序存储——堆——初识堆排序

前面我们学过可以把完全二叉树存入到顺序表中&#xff0c;然后利用完全二叉树的情缘关系&#xff0c;就可以通过数组下标来联系。 但是并不是把二叉树存入到数组中就是堆了&#xff0c;要看原原来的二叉树是否满足&#xff1a;所有的父都小于等于子&#xff0c;或者所有的父都…...

CYEZ 模拟赛 9

A a ⊥ b ⇒ a − b ⊥ a b (1) a \perp b \Rightarrow a-b \perp ab \tag {1} a⊥b⇒a−b⊥ab(1) 证明&#xff1a; gcd ⁡ ( a , b ) gcd ⁡ ( b , a − b ) \gcd(a,b) \gcd(b, a-b) gcd(a,b)gcd(b,a−b)&#xff0c;故 a − b ⊥ b a - b \perp b a−b⊥b&#xff0c;同…...

typescript: Builder Pattern

/*** file: CarBuilderts.ts* TypeScript 实体类 Model* Builder Pattern* 生成器是一种创建型设计模式&#xff0c; 使你能够分步骤创建复杂对象。* https://stackoverflow.com/questions/12827266/get-and-set-in-typescript* https://github.com/Microsoft/TypeScript/wiki/…...

WPS/word 表格跨行如何续表、和表的名称

1&#xff1a;具体操作&#xff1a; 将光标定位在跨页部分的第一行任意位置&#xff0c;按下快捷键ctrlshiftenter&#xff0c;就可以在跨页的表格上方插入空行&#xff08;在空行可以写&#xff0c;表1-3 xxxx&#xff08;续&#xff09;&#xff09; 在空行中输入…...

Python的NumPy库(一)基础用法

NumPy库并不是Python的标准库&#xff0c;但其在机器学习、大数据等很多领域有非常广泛的应用&#xff0c;NumPy本身就有比较多的内容&#xff0c;全部的学习可能涉及许多的内容&#xff0c;但我们在这里仅学习常见的使用&#xff0c;这些内容对于我们日常使用NumPy是足够的。 …...

uniapp app 导出excel 表格

直接复制运行 <template><view><button click"tableToExcel">导出一个表来看</button><view>{{ successTip }}</view></view> </template><script>export default {data() {return {successTip: }},metho…...

【RabbitMQ】常用消息模型详解

文章目录 AMQP协议的回顾RabbitMQ支持的消息模型第一种模型(直连)开发生产者开发消费者生产者、消费者开发优化API参数细节 第二种模型(work quene)开发生产者开发消费者消息自动确认机制 第三种模型(fanout)开发生产者开发消费者 第四种模型(Routing)开发生产者开发消费者 第五…...

mPLUG在金融领域的应用:票据智能识别系统

mPLUG在金融领域的应用&#xff1a;票据智能识别系统 1. 项目背景与需求 金融行业每天都要处理海量的票据单据&#xff0c;从银行的支票、汇票&#xff0c;到保险公司的保单、理赔单&#xff0c;再到企业的发票、报销单。传统的人工处理方式不仅效率低下&#xff0c;还容易出…...

GTE文本向量模型部署全攻略:从零到一搭建企业级文本处理服务

GTE文本向量模型部署全攻略&#xff1a;从零到一搭建企业级文本处理服务 1. 项目介绍与核心价值 如果你正在寻找一个能一站式解决中文文本分析难题的工具&#xff0c;那么GTE文本向量模型可能就是你的答案。想象一下&#xff0c;一个模型就能帮你识别文档里的关键人物、地点&…...

OpenClaw+Qwen3-32B-Chat:3种模型调用方式对比与选型建议

OpenClawQwen3-32B-Chat&#xff1a;3种模型调用方式对比与选型建议 1. 为什么需要对比模型调用方式&#xff1f; 第一次在本地部署Qwen3-32B-Chat模型时&#xff0c;我遇到了一个典型的技术选择困境&#xff1a;究竟应该直接调用本地模型&#xff0c;还是通过API访问远程服务…...

AI Agent 时代的“将领艺术“:一个人如何指挥一支开发军队

摘要&#xff1a;本文探讨在 AI Agent 时代&#xff0c;开发者如何从"单兵作战"转变为"一人成军"&#xff0c;核心在于任务拆分能力、Agent 调度能力和系统集成能力。通过战争将领的类比&#xff0c;提供一套可复用的 Agent 项目管理框架。 关键词&#x…...

辅助用电系统安装:工业项目电力配套的关键环节问题全解析

在工业厂房、园区配套、商业综合体、仓储物流中心以及各类生产型项目中&#xff0c;很多人一提到电气工程&#xff0c;第一反应往往是高压配电、变压器、动力柜或者主供电系统。但真正决定项目是否“好用、稳用、久用”的&#xff0c;往往不是主系统本身&#xff0c;而是隐藏在…...

开发环境神器:OpenClaw+GLM-4.7-Flash自动补全错误日志解决方案

开发环境神器&#xff1a;OpenClawGLM-4.7-Flash自动补全错误日志解决方案 1. 为什么需要日志自动诊断系统 作为一个长期与开发环境打交道的程序员&#xff0c;我每天要面对数百行日志输出。最头疼的场景莫过于&#xff1a;当你在IDE中调试时&#xff0c;突然蹦出一段晦涩的错…...

.NET eShop 开源项目教程

.NET eShop 开源项目教程 【免费下载链接】eShop A reference .NET application implementing an eCommerce site 项目地址: https://gitcode.com/GitHub_Trending/es/eShop 1. 项目介绍 .NET eShop 是一个基于 Microsoft 的 .NET 技术栈开发的开源电子商务平台。该项目…...

LLaMA-Adapter微调终极指南:1小时掌握120万参数的高效优化技巧

LLaMA-Adapter微调终极指南&#xff1a;1小时掌握120万参数的高效优化技巧 【免费下载链接】LLaMA-Adapter Fine-tuning LLaMA to follow Instructions within 1 Hour and 1.2M Parameters 项目地址: https://gitcode.com/gh_mirrors/ll/LLaMA-Adapter LLaMA-Adapter是一…...

eSearch终极指南:5分钟掌握OCR屏幕工具的强大功能

eSearch终极指南&#xff1a;5分钟掌握OCR屏幕工具的强大功能 【免费下载链接】eSearch 截屏 离线OCR 搜索翻译 以图搜图 贴图 录屏 滚动截屏 Screenshot OCR search translate search for picture paste the picture on the screen screen recorder 项目地址: https://gitco…...

微信小程序点餐毕业设计开题报告怎么写:从实战需求到技术架构的完整拆解

最近在辅导学弟学妹做毕业设计&#xff0c;发现很多同学在写“微信小程序点餐系统”的开题报告时&#xff0c;都挺头疼的。大家普遍感觉&#xff0c;报告写出来要么是功能列表的堆砌&#xff0c;要么就是技术方案写得特别虚&#xff0c;什么“采用先进技术”、“保证高可用”&a…...