mybatisPlus
mybatisplus
基础: mybatis spring springmvc
为什么要学习mybatisplus ?
可以解决大量时间 所有的CRUD 代码它都可以自动化完成
简介
简化 jdbc 操作
简化 mybatis
快速入门
网站:快速开始 | MyBatis-Plus (baomidou.com)
使用第三方依赖
- 导入对应的依赖
- 研究依赖如何配置
- 代码如何编写
- 提高扩展技术能力
步骤
- 创建数据库 mybatis_plus
- 现有一张 User 表,其表结构如下:
idnameageemail1Jone18test1@baomidou.com2Jack20test2@baomidou.com3Tom28test3@baomidou.com4Sandy21test4@baomidou.com5Billie24test5@baomidou.com
其对应的数据库 Schema 脚本如下:- DROP TABLE IF EXISTS user;
- 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 脚本如下:- 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');
复制代码
- 编写项目 ,初始化项目
-
- <dependency>
- <groupId>com.mysql</groupId>
- <artifactId>mysql-connector-j</artifactId>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-boot-starter</artifactId>
- <version>3.0.5</version>
- </dependency>
复制代码 说明
使用mybatisplus 可以节省我们大量的代码,尽量不要同时导入 mybatis 和 mybatis-plus!
版本差异
- 链接数据库
- spring.couchbase.username=root
- spring.datasource.password=123456
- spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf8
- # mysql8 serverTimezone=GMT%2B8
- spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
复制代码 pojo-dao(链接mybatis,配置mapper.xml文件)-service-controller
- mapper 接口
- package com.lmq.mapper;
- import com.baomidou.mybatisplus.core.mapper.BaseMapper;
- import com.lmq.pojo.User;
- import org.springframework.stereotype.Repository;
- /**
- * @author 羡鱼
- * @version 1.0
- * @date 2023/7/20 20:23
- */
- @Repository // 持久层
- public interface UserMapper extends BaseMapper<User> {
- // 所有CRUD操作都已经编写完成了
- // 你不需要配置一大堆文件了
- }
复制代码 注意: 我们需要在主启动类上去扫描我们的mapper包下的所有接口 @MapperScan("com.lmq.mapper")
测试类- package com.lmq;
- import com.lmq.mapper.UserMapper;
- import com.lmq.pojo.User;
- import org.junit.jupiter.api.Test;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
- import java.util.List;
- @SpringBootTest
- class MybatisPlusApplicationTests {
- @Autowired
- private UserMapper userMapper;
- @Test
- void contextLoads() {
- // 参数是一个Wrapper,条件构造器,这里我们先不用null
- // 查询全部用户
- List<User> users = userMapper.selectList(null);
- users.forEach(System.out::println);
- }
- }
复制代码 1、sql是谁帮我写的? MyBatis-plus 写好了
2、方法哪里来的? MyBatis-plus 都写好了
配置日志
我们所以的sql现在是不可见的,我们希望知道是怎么执行的- #配置日志
- mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
复制代码
CRUD扩展
insert
- @Test
- public void testInsert(){
- User user = new User();
- user.setName("lmq");
- user.setAge(21);
- user.setEmail("1435456124@qq.com");
- int result = userMapper.insert(user); // 帮我们自动生成id
- System.out.println(result); //受影响的行数
- System.out.println(user); // 发现id会自动回填
- }
复制代码
数据库插入的id的默认值为:全局的唯一id
主键生成策略
默认ID_WORKER 全局唯一ID
雪花算法:
snowflake 是 Twitter 开源的分布式id生成算法,结果是个long型的id.核心思想是:使6用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在毫秒可以产生4096个ID),最后hiatus有一个符号位,永远是0,可以保证全球唯一
主键自增
我们需要配置主键自增
- 实体类字段上@TableId(type= Idtype.AUTO)
- 数据库字段也要是自增
其他源码解释
- public enum IdType {
- AUTO(0), // 数据库自增
- NONE(1), // 未设置主键
- INPUT(2), // 手动输入
- ID_WORKER(3), // 默认 雪花算法 id
- UUID(4), //
- ID_WORKER_STR(5); //字符串截取
- private int key;
- private IdType(int key) {
- this.key = key;
- }
- public int getKey() {
- return this.key;
- }
- }
复制代码 更新操作
自动填充
方式一 :数据库级别 (工作中不允许你修改数据库)
- 表中加入字段 create_time update_time 默认值为CURRENT_TIMESTAMP

方式二:代码级别
- 删除数据库的默认值
- 实体类字段属性上需要增加注解
- // 字段添加填充内容
- @TableField(fill = FieldFill.INSERT)
- private Date createTime;
- @TableField(fill = FieldFill.INSERT_UPDATE)
- private Date updateTime;
复制代码 - 编写处理器来处理这个注解
- package com.lmq.handler;
- import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.ibatis.reflection.MetaObject;
- import org.springframework.stereotype.Component;
- import java.util.Date;
- /**
- * @author 羡鱼
- * @version 1.0
- * @date 2023/7/21 17:49
- */
- @Slf4j
- @Component // 不要忘记把处理器加入到我们的ioc容器中
- public class MyMetaObjectHandler implements MetaObjectHandler {
- // 插入时候的填充策略
- @Override
- public void insertFill(MetaObject metaObject) {
- log.info("start insert fill 插入填充");
- // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
- this.setFieldValByName("createTime",new Date(),metaObject);
- this.setFieldValByName("updateTime",new Date(),metaObject);
- }
- // 插入时候的填充策略
- @Override
- public void updateFill(MetaObject metaObject) {
- this.setFieldValByName("updateTime",new Date(),metaObject);
- }
- }
复制代码 锁
乐观锁 : 顾名思义 十分乐观 它认为不会出问题,无论干什么都不去上锁
悲观锁: 顾名思义十分悲观 他认为都会出问题 无论什么都去上锁
乐观锁实现方式
- 取出记录时,获取当前的version
- 更新时,带上这个version
- 执行时 set version = newVersion where version = oldVersion
- 如果version不对,更新失败
- 乐观锁 1 先查询
-
- -- A
- update User set name = "lmq",version = version+1
- where id = 2 and version = 1
- -- B 线程抢线完成 这个时候 version = 2 会导致 A修改失败!
- update User set name = "lmq",version = version+1
- where id = 2 and version = 1
复制代码测试一下MP中的乐观锁插件
- 给数据库添加version字段
- 我们实体类加对应的字段
- // 乐观锁的version注解
- @Version
- private Integer version;
复制代码 - 注册组件
- // Spring Boot 方式
- @Configuration
- @MapperScan("按需修改")
- public class MybatisPlusConfig {
- /**
- * 旧版
- */
- @Bean
- public OptimisticLockerInterceptor optimisticLockerInterceptor() {
- return new OptimisticLockerInterceptor();
- }
- /**
- * 新版
- */
- @Bean
- public MybatisPlusInterceptor mybatisPlusInterceptor() {
- MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
- mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
- return mybatisPlusInterceptor;
- }
- }
复制代码 - 测试
- @Test
- public void test2OptimisticLocker(){
- // 线程1
- User user = userMapper.selectById(1l);
- user.setName("lmq");
- user.setEmail("1435456124@qq.com");
- // 模拟线程插队操作
- User user2 = userMapper.selectById(1l);
- user2.setName("lmq222");
- user2.setEmail("LLL1435456124@qq.com");
- userMapper.updateById(user2);
- //自旋锁来多次尝试提交
- userMapper.updateById(user); // 如果没有乐观锁就会插队
- }
复制代码 查询操作
- // 查询测试
- @Test
- public void testSelectById() { //单个
- User user = userMapper.selectById(1L);
- System.out.println(user);
- }
- @Test
- public void testSelectByBatchId() { // 批量查询
- List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
- users.forEach(System.out::println);
- }
- @Test
- public void testSelectByBatchIds() { //条件查询
- HashMap<String, Object> map = new HashMap<>();
- map.put("name", "lmq");
- List<User> users = userMapper.selectByMap(map);
- users.forEach(System.out::println);
- }
复制代码 分页查询
网站使用十分多
- 原始的limit进行分页
- pageHelper 第三方的插件
- MP内置了分页插件
如何使用
- 导入插件
- @Bean
- public PaginationInterceptor paginationInterceptor() {
- return new PaginationInterceptor();
- }
复制代码 - 直接使用Page对象
- //测试分页查询
- @Test
- public void testPage(){
- // 参数一 当前页 参数二 页面大小 所有的分页变简单了
- Page<User> page = new Page<>(2,5);
- userMapper.selectPage(page,null);
- page.getRecords().forEach(System.out::println);
- System.out.println(page.getTotal());
- }
复制代码 删除操作
- //测试删除
- @Test
- public void testDeleteById() { // 单个id
- userMapper.deleteById(1682330740093681666L);
- }
- @Test
- public void testDeleteBatchIds() { // 多个id
- userMapper.deleteBatchIds(Arrays.asList(1L, 2L));
- }
- @Test
- public void testDeleteByMap() { // 通过map删除
- HashMap<String, Object> map = new HashMap<>();
- map.put("name", "lmq");
- userMapper.deleteByMap(map);
- }
- }
复制代码 逻辑删除
物理删除 : 从数据库中直接移除
逻辑删除: 在数据库中没有删除,而是通过一个变量来让他失效! deleted =0=>deleted =1
管理员可以看见删除记录! 防止数据丢失,类似回收站
- 在数据库中加入deleted 字段
- pojo 实体类中增加属性
- // 逻辑删除
- @TableLogic
- private Integer deleted;
复制代码 - 配置bean
- @Bean
- public ISqlInjector sqlInjector() {
- return new LogicSqlInjector();
- }
复制代码 - 配置properties
- # 配置逻辑删除
- mybatis-plus.global-config.db-config.logic-delete-value=1
- mybatis-plus.global-config.db-config.logic-not-delete-value=0
复制代码 性能分析插件
开发中经常遇到慢sql 测试! druid..
MP也提供性能分析插件 超过时间就停止运行
- 导入插件
- @Bean
- @Profile({"dev", "test"}) //保证效率 设置环境
- public PerformanceInterceptor performanceInterceptor() {
- PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
- performanceInterceptor.setMaxTime(100); //sql执行的最大时间 如果超过就不仔细了
- performanceInterceptor.setFormat(true);
- return performanceInterceptor;
- }
复制代码- #设置开发环境
- spring.profiles.active=dev
复制代码 - 测试使用
- Time:78 ms - ID:com.lmq.mapper.UserMapper.insert
- Execute SQL:
- INSERT
- INTO
- user
- ( id, name, age, email, create_time, update_time )
- VALUES
- ( 1682397170604474369, 'lmq', 21, '1435456124@qq.com', '2023-07-21 22:28:37.558', '2023-07-21 22:28:37.559' )
复制代码 条件构造器
十分重要Wrapper
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |