1、简介

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

  • 润物无声
    只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。
  • 效率至上
    只需简单配置,即可快速进行 CRUD 操作,从而节省大量时间。
  • 丰富功能
    热加载、代码生成、分页、性能分析等功能一应俱全。

2、创建并初始化数据库

2.1 创建数据库

  • mybatis_plus

2.2 创建 User 表

其对应的数据库 Schema 脚本如下:

CREATE TABLE USER
(id BIGINT(20)NOT NULL COMMENT '主键ID',NAME VARCHAR(30)NULL DEFAULT NULL COMMENT '姓名',age INT(11)NULL DEFAULT NULL COMMENT '年龄',email VARCHAR(50)NULL DEFAULT NULL COMMENT '邮箱',PRIMARY KEY (id)
);

其对应的数据库 Data 脚本如下:

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、引入依赖

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency><!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--lombok用来简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

4、编写代码

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

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

注意:

  • 1、这里的 url 使用了 ?serverTimezone=GMT%2B8 后缀,因为8.0版本的jdbc驱动需要添加这个后缀,否则运行测试用例报告如下错误:
    java.sql.SQLException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or represents more
  • 2、这里的 driver-class-name 使用了 com.mysql.cj.jdbc.Driver ,在 jdbc 8 中 建议使用这个驱动,否则运行测试用例的时候会有 WARN 信息

4.1 启动类

在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹

@SpringBootApplication
@MapperScan("com.atguigu.demomptest.mapper")
public class DemomptestApplication {public static void main(String[] args) {SpringApplication.run(DemomptestApplication.class, args);}}

4.2 添加实体

创建包 entity 编写实体类 User.java(此处使用了 Lombok 简化代码)

@Data
public class User {private Long id;private String name;private Integer age;private String email;
}

4.3 添加mapper

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

@Repository
public interface UserMapper extends BaseMapper<User> {}

此处的BaseMapper父类是由mybatis-plus实现的的基础数据库操作类,User是需要操作的类型

4.4 查看sql输出日志

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

4.5 注意

本教程直接使用mapper操作数据库实现,如需使用service,还需构建以下类

public interface UserService extends IService<User>  {}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements HospitalSetService {}

5、主键策略

5.1 添加操作

//添加
@Test
public void testAdd() {User user = new User();user.setName("lucy");user.setAge(20);user.setEmail("1243@qq.com");int insert = userMapper.insert(user);System.out.println(insert);
}

注意:数据库插入id值默认为:全局唯一id

5.2 MP的主键策略

5.3 ASSIGN_ID

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.4 AUTO 自增策略

需要在创建数据表的时候设置主键自增
实体字段中配置 @TableId(type = IdType.AUTO)
要想影响所有实体的配置,可以设置全局主键配置

#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto

5.5 其他策略

6、自动填充和乐观锁

6.1 更新操作

注意:update时生成的sql自动是动态sql:UPDATE user SET age=? WHERE id=?

//修改
@Test
public void testUpdate() {User user = new User();user.setId(1340868235401764865L);user.setName("lucymary");int count = userMapper.updateById(user);System.out.println(count);
}

6.2 自动填充

需求描述:

项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。
我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作

  • 数据库修改
    在User表中添加datetime类型的新的字段 create_time、update_time
  • 实体类修改
    实体上增加字段并添加自动填充注解
@TableField(fill = FieldFill.INSERT)
private Date createTime;  //create_time@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime; //update_time
  • 实现元对象处理器接口
    注意:不要忘记添加 @Component 注解
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {//mp执行添加操作,这个方法执行@Overridepublic void insertFill(MetaObject metaObject) {this.setFieldValByName("createTime",new Date(),metaObject);this.setFieldValByName("updateTime",new Date(),metaObject);}//mp执行修改操作,这个方法执行@Overridepublic void updateFill(MetaObject metaObject) {this.setFieldValByName("updateTime",new Date(),metaObject);}
}

6.3 乐观锁

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

乐观锁实现方式:

取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
接下来介绍如何在Mybatis-Plus项目中,使用乐观锁:

6.3.1 乐观锁实现流程

  • 修改实体类
    添加 @Version 注解
@Version
private Integer version;
  • 创建配置文件
    创建包config,创建文件MybatisPlusConfig.java
    此时可以删除主类中的 @MapperScan 扫描注解
@Configuration
@MapperScan("com.atguigu.demomptest.mapper")
public class MpConfig {/*** 乐观锁插件*/@Beanpublic OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();}
}
  • 注册乐观锁插件
    在 MybatisPlusConfig 中注册 Bean
/**
* 乐观锁插件
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();
}

7、查询

7.1 查询

7.1.1通过多个id批量查询

完成了动态sql的foreach的功能

//多个id批量查询
@Test
public void testSelect1() {List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));System.out.println(users);
}

7.1.2简单的条件查询

  • 通过map封装查询条件
    注意:map中的key对应数据库中的列名。如:数据库user_id,实体类是userId,这时map的key需要填写user_id
//简单条件查询
@Test
public void testSelect2() {Map<String, Object> columnMap = new HashMap<>();columnMap.put("name","Jack");columnMap.put("age",20);List<User> users = userMapper.selectByMap(columnMap);System.out.println(users);
}

7.2 分页

7.2.1 分页插件

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

7.2.1.1 添加分页插件
配置类中添加@Bean配置
/*** 分页插件*/
@Bean
public PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();
}
7.2.1.2 测试selectPage分页

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

//分页查询
@Test
public void testSelectPage() {Page<User> page = new Page(1,3);Page<User> userPage = userMapper.selectPage(page, null);//返回对象得到分页所有数据long pages = userPage.getPages(); //总页数long current = userPage.getCurrent(); //当前页List<User> records = userPage.getRecords(); //查询数据集合long total = userPage.getTotal(); //总记录数boolean hasNext = userPage.hasNext();  //下一页boolean hasPrevious = userPage.hasPrevious(); //上一页System.out.println(pages);System.out.println(current);System.out.println(records);System.out.println(total);System.out.println(hasNext);System.out.println(hasPrevious);
}

7.2.2测试selectMapsPage分页

  • 当指定了特定的查询列时,希望分页结果列表只返回被查询的列,而不是很多null值
    测试selectMapsPage分页:结果集是Map
@Test
public void testSelectMapsPage() {//Page不需要泛型
Page<Map<String, Object>> page = newPage<>(1, 5);
Page<Map<String, Object>> pageParam = userMapper.selectMapsPage(page, null);
List<Map<String, Object>> records = pageParam.getRecords();
records.forEach(System.out::println);
System.out.println(pageParam.getCurrent());
System.out.println(pageParam.getPages());
System.out.println(pageParam.getSize());
System.out.println(pageParam.getTotal());
System.out.println(pageParam.hasNext());
System.out.println(pageParam.hasPrevious());
}

8、删除与逻辑删除

8.1 删除

8.1.1 根据id删除记录

@Test
public void testDeleteById(){int result = userMapper.deleteById(5L);
system.out.println(result);
}

8.1.2 批量删除

@Test
public void testDeleteBatchIds() {int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10));
system.out.println(result);
}

简单条件删除


@Test
public void testDeleteByMap() {HashMap<String, Object> map = new HashMap<>();
map.put("name", "Helen");
map.put("age", 18);int result = userMapper.deleteByMap(map);
system.out.println(result);
}

8.2 逻辑删除

8.2.1物理删除和逻辑删除

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

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

  • 逻辑删除的使用场景:
    可以进行数据恢复
    有关联数据,不便删除

8.2.2 逻辑删除实现流程

8.2.2.1数据库修改

添加 deleted字段
ALTERTABLE user ADD COLUMN deleted boolean DEFAULT false

8.2.2.2 实体类修改
  • 添加deleted 字段,并加上 @TableLogic 注解
@TableLogic
private Integer deleted;
8.2.2.3 配置(可选)
  • application.properties 加入以下配置,此为默认值,如果你的默认值和mp默认的一样,该配置可无

mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

8.2.2.4 测试
  • 测试后发现,数据并没有被删除,deleted字段的值由0变成了1
  • 测试后分析打印的sql语句,是一条update
  • 注意:被删除前,数据的deleted 字段的值必须是 0,才能被选取出来执行逻辑删除的操作
@Test
public void testLogicDelete() {int result = userMapper.deleteById(1L);
system.out.println(result);
}
8.2.2.5 测试逻辑删除后的查询

MyBatis Plus中查询操作也会自动添加逻辑删除字段的判断

@Test
public void testLogicDeleteSelect() {List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}

9、条件构造器和常用接口

9.1 wapper介绍

Wrapper : 条件构造抽象类,最顶端父类

  • AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
  • QueryWrapper : 查询条件封装
  • UpdateWrapper : Update 条件封装
  • AbstractLambdaWrapper : 使用Lambda 语法
  • LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
  • LambdaUpdateWrapper : Lambda 更新封装Wrapper
@SpringBootTest
publicclassQueryWrapperTests {@Autowired
privateUserMapperuserMapper;
}

9.2 查询方式

查询方式 说明
setSqlSelect 设置 SELECT 查询字段
where WHERE 语句,拼接 + WHERE 条件
and AND 语句,拼接 + AND 字段=值
andNew AND 语句,拼接 + AND (字段=值)
or OR 语句,拼接 + OR 字段=值
orNew OR 语句,拼接 + OR (字段=值)
eq 等于=
allEq 基于 map 内容等于=
ne 不等于<>
gt 大于>
ge 大于等于>=
lt 小于<
le 小于等于<=
like 模糊查询 LIKE
notLike 模糊查询 NOT LIKE
in IN 查询
notIn NOT IN 查询
isNull NULL 值查询
isNotNull IS NOT NULL
groupBy 分组 GROUP BY
having HAVING 关键词
orderBy 排序 ORDER BY
orderAsc ASC 排序 ORDER BY
orderDesc DESC 排序 ORDER BY
exists EXISTS 条件语句
notExists NOT EXISTS 条件语句
between BETWEEN 条件语句
notBetween NOT BETWEEN 条件语句
addFilter 自由拼接 SQL
last 拼接在最后,例如:last(“LIMIT 1”)

9.3 测试用例

9.3.1 ge、gt、le、lt、isNull、isNotNull

@Test
public void testQuery() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.isNull("name").ge("age", 12).isNotNull("email");int result = userMapper.delete(queryWrapper);
System.out.println("delete return count = " + result);
}

9.3.2 eq、ne

注意:seletOne()返回的是一条实体记录,当出现多条时会报错

@Test
public void testSelectOne() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.eq("name", "Tom");
Useruser = userMapper.selectOne(queryWrapper);//只能返回一条记录,多余一条则抛出异常
System.out.println(user);
}

9.3.3 between、notBetween

包含大小边界

@Test
public void testSelectCount() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.between("age", 20, 30);Integer count = userMapper.selectCount(queryWrapper); //返回数据数量
System.out.println(count);
}

9.3.4 like、notLike、likeLeft、likeRight

selectMaps()返回Map集合列表,通常配合select()使用

@Test
public void testSelectMaps() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.select("name", "age").like("name", "e").likeRight("email", "5");
List<Map<String, Object>>maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表
maps.forEach(System.out::println);
}

9.3.5 orderBy、orderByDesc、orderByAsc

@Test
public void testSelectListOrderBy() {QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.orderByDesc("age", "id");
List<User>users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}

MyBatis-Plus快速入门相关推荐

  1. MyBatis之快速入门

    MyBatis之快速入门 2017/9/30 首先我要明确告诉大家的是MyBatis是一个java持久层框架,以前我们都是用jdbc来将我们的java程序与数据库相连接,而MyBatis是对jdbc的 ...

  2. java day53【 Mybatis框架概述 、 Mybatis 框架快速入门、自定义 Mybatis 框架 】

    第1章 框架概述 1.1 什么是框架 1.1.1 什么是框架 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种 定义认为,框架是可被应用开发者定 ...

  3. MyBatis框架快速入门

    MyBatis框架快速入门 入门案例 创建一个关于Mybatis项目 首先创建一个空项目,然后新建一个moudle,选择quickstart,接下来把模块放到空项目之下.即可 实现mybatis查询数 ...

  4. MyBatis 01 快速入门

    MyBatis 01 快速入门 文章目录 MyBatis 01 快速入门 一.学习目标 二.为什么需要框架技术 三.框架技术介绍 四.主流框架介绍 五.持久化与ORM 六.MyBatis简介 七.搭建 ...

  5. Mybatis(day1)快速入门

    框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法:另一种定义认为,框架是可被应用开发者定制的应用骨架.前者是从应用方面而后者是从目的方面给出的定义. 简 ...

  6. mybatis的快速入门

    说明: 在这个部分,会写个简单的入门案例. 然后,会重新写一个,更加严格的程序案例. 一:案例一 1.最终的目录结构 2.新建一个普通的Java项目,并新建lib 在项目名上右键,不是src. 3.导 ...

  7. 第一:Java+MyBatis(快速入门)

    MyBatis 简介 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为 ...

  8. springboot 整合mybatis_SpringBoot整合MyBatis框架快速入门

    MyBatis概述: mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动.创建连接.创建statemenet等繁 ...

  9. MyBatis:快速入门代码实例(maven代码版)

    文章目录 1. MyBatis实例 1.1 添加Mybatis依赖 1.2 创建MyBatis配置文件 1.3.创建po类 1.4.创建映射文件 #{}: 表示sql参数,一个占位符. 1.5.测试 ...

  10. MyBatis从入门到精通(一)—MyBatis基础知识和快速入门

    Mybatis简介 原始jdbc操作(查询数据) Connection connection = null;PreparedStatement preparedStatement = null;Res ...

最新文章

  1. 信号 09 | 信号概念
  2. java jdbc 增删改封装_JAVA JDBC 常规增删改查简单封装
  3. 无代码时代来临,程序员如何保住饭碗?赶紧看一看!
  4. 抽象数据类型和Python类的基础
  5. 字节跳动高工面试:mysql查询重复数据sql
  6. 用request.getParameterMap()获得jsp页面元素的集合出现[Ljava.lang.String;@的问题解决
  7. 给机器人罗宾写一封英语回信_小学英语人教(13版三起点)六年级上册Unit1
  8. Delphi 跨语言环境 乱码问题
  9. 本人考研的时间流程图
  10. 外地父母常住北京-医疗问题-新农合北京就医实时结算
  11. 蚂蚁区块链第9课 SSL/TLS工作原理及在蚂蚁BAAS中的应用
  12. 邮箱登录入口,163邮箱个人登录入口,163邮箱注册登录
  13. iis7无法写入配置文件,更换进入方式解决
  14. prctl()和pthread_setname_np()函数-设置线程名称
  15. 噪声种类及Matlab添加噪声
  16. 全球通史读书笔记上(第六章——古代文明的新起)
  17. Error 12154 received logging on to the standby
  18. 令人头秃的cudaTensorCoreGemm详解
  19. Firefox浏览器浏览自己做的网站需要输入用户名和密码解决
  20. Robosense速腾激光雷达如何使用多雷达

热门文章

  1. 濒临死亡的校园BBS
  2. 计算机图形图像的领域应用论文,计算机图形与图像处理论文2000字
  3. 【四舍六入五单双法】
  4. 模式识别学习笔记-lecture2-统计判别1
  5. 世上无难事,只要舍花钱
  6. 默小伟网站开发帮助文档UI模板
  7. 操作系统教程课后习题答案完整版
  8. matlab gui更新结构体,Matlab GUI教程0x5 -handles结构体用法简介
  9. 《鬼泣-巅峰之战》产品分析:如何将ACT游戏改编成ARPG手游 ​
  10. Postgresql之Vacuum和Vacuum full的区别