Mybatis-plus介绍及使用

PRIMARY KEY (id)

);

插入数据

DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES

(1, ‘Jone’, 18, ‘test1@baomidou.com’),

(2, ‘Jack’, 20, ‘test2@baomidou.com’),

(3, ‘Tom’, 28, ‘test3@baomidou.com’),

(4, ‘Sandy’, 21, ‘test4@baomidou.com’),

(5, ‘Billie’, 24, ‘test5@baomidou.com’);

3.2、创建springboot工程


在这里插入图片描述

3.3、引入入门项目所需的依赖


com.baomidou

mybatis-plus-boot-starter

3.3.1

mysql

mysql-connector-java

org.projectlombok

lombok

true

3.4、配置数据库信息


在 application.properties 配置文件中添加 MySQL 数据库的相关配置

  • spring boot 2.0(内置jdbc5驱动)

#mysql数据库连接

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false

spring.datasource.username=root

spring.datasource.password=root

  • spring boot 2.1及以上(内置jdbc8驱动)

注意:driver和url的变化

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8

spring.datasource.username=root

spring.datasource.password=root

在这里插入图片描述

3.5、编写代码


3.5.1、实体类:

在这里插入图片描述

@Data

public class User {

private Long id;

private String name;

private Integer age;

private String email;

}

在这里插入图片描述

3.5.2、添加mapper

创建包 mapper 编写UserMapper 接口: UserMapper.java

在这里插入图片描述

@Repository

public interface UserMapper extends BaseMapper {

}

3.5.3、启动类添加注解@MapperScan

作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类

添加位置:是在Springboot启动类上面添加.

@SpringBootApplication

@MapperScan(“com.study.demomptest.mapper”)

public class DemomptestApplication {

public static void main(String[] args) {

SpringApplication.run(DemomptestApplication.class, args);

}

}

3.6、测试


3.6.1、查询user表中所有数据

@SpringBootTest

class DemomptestApplicationTests {

@Autowired

private UserMapper userMapper;

@Test

void findAll() {

List users = userMapper.selectList(null);

System.out.println(users);

}

}

在这里插入图片描述

3.6.2、新增

在这里插入图片描述

@SpringBootTest

class DemomptestApplicationTests {

@Autowired

private UserMapper userMapper;

//新增

@Test

void insert(){

User user = new User();

user.setName(“Lucy”);

user.setAge(20);

user.setEmail(“12345@qq.com”);

int insert = userMapper.insert(user);

System.out.println(insert);

}

}

3.6.3、修改数据

在这里插入图片描述

4、要想在控制台看到sql输出日志,需要在application.properties配置文件中添加以下代码

=====================================================================================================================

#mybatis日志

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

5、主键生成策略

=======================================================================

  • auto-increment

  • uuid:每次随机生成唯一值,排序不方便

  • redis

  • mybatis-plus (使用了snowplake算法)

5.1、常见的主键生成策略介绍


https://www.cnblogs.com/haoxinyue/p/5208136.html

5.2、 Mybatis-plus默认主键生成策略


mybatis-plus默认只用自己自带的主键生成策略,MyBatis-Plus默认的主键策略是:ASSIGN_ID (使用了雪花算法)

@TableId(type = IdType.ASSIGN_ID)

private String id;

  • 雪花算法:分布式ID生成器

雪花算法是由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性。

  • 核心思想:

长度共64bit(一个long型)。

首先是一个符号位,1bit标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0。

41bit时间截(毫秒级),存储的是时间截的差值(当前时间截 - 开始时间截),结果约等于69.73年。

10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID,可以部署在1024个节点)。

12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID)。

在这里插入图片描述

  • 雪花算法优点:

整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞,并且效率较高。

5.3、 自定义主键生成策略


可以自己设置要使用的主键生成策略,使用如下注解@TableId

  • @TableId(type = IdType.ID_WORKER)

mybatis-plus自带的策略,生成19位值,当属性类型类数字类型时使用该策略,比如Long

  • @TableId(type = IdType.ID_WORKER_STR)

mybatis-plus自带的策略,生成19位值,当属性类型类字符串类型时使用该策略,比如String

在这里插入图片描述

  • @TableId(type = IdType.UUID)

随机生成唯一值

  • @TableId(type = IdType.AUTO)

数据库ID自增

  • @TableId(type = IdType.INPUT)

用户输入ID, 该类型可以通过自己注册自动填充插件进行填充

  • @TableId(type = IdType.NONE)

没有策略

在需要设置主键的实体类属性上使用该注解,可以设置主键策略,主要有以下几种策略。

在这里插入图片描述

5.4、全局主键配置


要想影响所有实体的配置,可以设置全局主键配置

#全局设置主键生成策略

mybatis-plus.global-config.db-config.id-type=auto

6、mbatis-plus自动填充

================================================================================

需求描述:

项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。

我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作

6.1、数据库修改


在User表中添加datetime类型的新的字段 create_time、update_time

6.2、实体类修改


在实体类里需要自动填充的属性上面添加注解

如在下面User实体类的createTime和updateTime属性上添加注解

在这里插入图片描述

6.3、实现元对象处理器接口


创建类,实现MetaObjectHandler接口,实现接口里的方法

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;

import org.apache.ibatis.reflection.MetaObject;

import java.util.Date;

/**

  • @Description :

  • @Author :lenovo

  • @Date :2021/2/20 21:34

*/

@Component

public class MyMetaObjectHandler implements MetaObjectHandler {

//用mybatis-plus实现添加操作时,在这个方法会执行

@Override

public void insertFill(MetaObject metaObject) {

this.setFieldValByName(“createTime”,new Date(),metaObject);

this.setFieldValByName(“updateTime”,new Date(),metaObject);

}

//用mybatis-plus实现修改操作时,在这个方法会执行

@Override

public void updateFill(MetaObject metaObject) {

this.setFieldValByName(“updateTime”,new Date(),metaObject);

}

}

7、丢失更新

=====================================================================

什么是丢失更新:

多个人同时需改一条记录,最后提交的会把之前提交的数据覆盖更新。

在这里插入图片描述

7.1、丢失更新解决方案


7.1.1 、悲观锁(表级锁):串行操作。

举例1:如上图修改数据,Lucy修改money数据时,别人都不能进行操作,只有lucy操作完成后,其他人才能操作。

举例2:又比如当一个人上网浏览新闻时,别人不能浏览,只有当这个人浏览完成后,别人才能浏览,如果这个人浏览一百年,其他所有人就要等一百年,这就是悲观锁。

7.1.2、 乐观锁

  • 主要适用场景:当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新

  • 使用版本号进行并发的控制。比如多个人修改数据时,只有一个人才能修改成功,其他人不能同时修改。

在这里插入图片描述乐观锁的实现原理:

在这里插入图片描述乐观锁的具体实现:

mybatis-plus实现乐观锁官方步骤:https://mp.baomidou.com/guide/interceptor-optimistic-locker.html#optimisticlockerinnerinterceptor

  • 1、表中添加字段,作为乐观锁版本号。

在这里插入图片描述

  • 2、对应实体类添加版本号属性。

在这里插入图片描述

@TableField(fill = FieldFill.INSERT): 插入数据时自动填充数据

在这里插入图片描述

@version注解所在的包:

在这里插入图片描述

  • 3、插件配置

spring工程:在spring.xml配置文件中

spring-boot项目:新建一个存放配置类的包,在该包下新建个配置类:编写乐观锁插件

package com.nonglin.mpdemo.config;

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

@MapperScan(“com.nonglin.mpdemo”)

public class Mpconfig {

//乐观锁插件

@Bean

public OptimisticLockerInterceptor optimisticLockerInterceptor() {

return new OptimisticLockerInterceptor();

}

}

  • 4、在测试类中测试乐观锁:

//测试乐观锁

@Test

public void testOptimisticLocker(){

User user = userMapper.selectById(1363307390618947585L);

user.setAge(1);

int row = userMapper.updateById(user);

System.out.println(“修改”+row+“条数据”);

}

8、mybatis-plus简单查询

=================================================================================

8.1、过多个id批量查询selectBatchIds


Zero date value prohibited解决方法

//多个id批量查询

@Test

public void findByBatchIds(){

List users = userMapper.selectBatchIds(Arrays.asList(1L,2L,3L));

for(User user:users){

System.out.println(user);

}

}

控制台输出:

在这里插入图片描述

JDBC Connection [HikariProxyConnection@1171672359 wrapping com.mysql.cj.jdbc.ConnectionImpl@34fe326d] will not be managed by Spring

==> Preparing: SELECT id,name,age,email,create_time,update_time,version FROM user WHERE id IN ( ? , ? , ? )

==> Parameters: 1(Long), 2(Long), 3(Long)

<== Columns: id, name, age, email, create_time, update_time, version

<== Row: 1, Jone, 18, test1@baomidou.com, null, null, null

<== Row: 2, Jack, 120, test2@baomidou.com, null, null, null

<== Row: 3, Tom, 28, test3@baomidou.com, null, null, null

<== Total: 3

打印输出:

Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@65eabaab]

User(id=1, name=Jone, age=18, email=test1@baomidou.com, createTime=null, updateTime=null, version=null)

User(id=2, name=Jack, age=120, email=test2@baomidou.com, createTime=null, updateTime=null, version=null)

User(id=3, name=Tom, age=28, email=test3@baomidou.com, createTime=null, updateTime=null, version=null)

8.2、简单的条件查询selectByMap


//简单条件查询

@Test

public void testSelectByMap(){

HashMap<String,Object> map = new HashMap<>();

map.put(“name”,“Lucy”);

map.put(“age”,18);

List users = userMapper.selectByMap(map);

users.forEach(System.out::println);

}

控制台输出:

在这里插入图片描述

JDBC Connection [HikariProxyConnection@774095232 wrapping com.mysql.cj.jdbc.ConnectionImpl@499683c4] will not be managed by Spring

==> Preparing: SELECT id,name,age,email,create_time,update_time,version FROM user WHERE name = ? AND age = ?

==> Parameters: Lucy(String), 18(Integer)

<== Columns: id, name, age, email, create_time, update_time, version

<== Row: 1363104207493660674, Lucy, 18, Lucy@qq.com, null, null, null

<== Total: 1

Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2b917fb0]

User(id=1363104207493660674, name=Lucy, age=18, email=Lucy@qq.com, createTime=null, updateTime=null, version=null)

9、mybatis-plus分页

===============================================================================

MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能

(1)创建配置类

在配置类中添加插件

//分页插件

@Bean

public PaginationInterceptor paginationInterceptor() {

return new PaginationInterceptor();

}

(2)测试selectPage分页

测试:最终通过page对象获取相关数据

@Test

void textPage(){

Page page = new Page(1,3);

Page userPage = userMapper.selectPage(page, null);

//返回的对象得到分页的所有数据

long current = userPage.getCurrent();//当前显示的页码

long size = userPage.getSize();//每页显示记录数

List records = userPage.getRecords();//当前页数据的集合

long pages = userPage.getPages();//表中数据的总页数

long total = userPage.getTotal();//数据库表中的总记录数

boolean hasPrevious = userPage.hasPrevious();//是否有上一页

boolean hasNext = userPage.hasNext();//是否有下一页

//通过page对象获取分页数据

System.out.println(“当前页:”+current);//当前页

System.out.println(“每页显示记录数:”+size);//每页显示记录数

System.out.println(“当前页数据的集合:”+records);//当前页数据的list集合

System.out.println(“数据库表中数据总页数:”+pages);//总页数

System.out.println(“数据库表中的总记录数:”+total);//总记录数

System.out.println(“是否有上一页:”+hasPrevious);//是否有上一页

System.out.println(“是否有下一页:”+hasNext);//是否有下一页

}

控制台输出:

在这里插入图片描述

9、mybatis-plus删除

===============================================================================

9.1、物理删除


真实删除,将对应数据从数据库中删除,之后查询不到此条被删除数据。

//根据id删除

@Test

public void deleteById(){

int result = userMapper.deleteById(1363126056508198913L);

System.out.println(result);

}

//批量删除

@Test

public void testDeleteBatchIds(){

int result = userMapper.deleteBatchIds(Arrays.asList(1L,2L,3L));

System.out.println(result);

}

//根据条件删除

@Test

void testDelete(){

HashMap map = new HashMap();

map.put(“name”,“LucyTest”);

map.put(“age”,23);

int i = userMapper.deleteByMap(map);

System.out.println(“成功删除了”+i+“条数据”);

}

9.2、逻辑删除


假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录。

逻辑删除的使用场景:

  • 可以进行数据恢复

  • 有关联数据,不便删除

9.2.1、表添加逻辑删除字段,对应实体类添加属性,属性添加注解。

在这里插入图片描述在这里插入图片描述

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里获取!


假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录。

逻辑删除的使用场景:

  • 可以进行数据恢复

  • 有关联数据,不便删除

9.2.1、表添加逻辑删除字段,对应实体类添加属性,属性添加注解。

在这里插入图片描述在这里插入图片描述

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-ZgiQG3CQ-1712946874502)]

[外链图片转存中…(img-Qp21jz8U-1712946874502)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

[外链图片转存中…(img-t2LJXTzY-1712946874502)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里获取!

[外链图片转存中…(img-Z5rlSqJ4-1712946874503)]

[外链图片转存中…(img-BzL8rgnw-1712946874503)]

  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值