Mybatis-Plus 5分钟快速上手,10分钟熟练使用

2024-03-04 07:44

本文主要是介绍Mybatis-Plus 5分钟快速上手,10分钟熟练使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

小伙伴们好,欢迎关注,一起学习,无限进步
以下为学习 mybatis-plus 过程中的笔记

mybatis-plus 官网地址:https://mp.baomidou.com/

文章目录

    • 特性
    • 快速开始
    • mybatis-plus 配置
    • 插入测试及雪花算法
      • 主键生成策略
        • 查询
        • 更新
        • 删除
        • 查询指定字段
        • 子查询
    • 自动填充
    • 乐观锁
    • 通用枚举
    • 代码自动生成器
      • 方式一(新版)
      • 方式二(旧版)
    • 分页插件
      • 测试分页
    • 多数据源
      • 简介
      • 特性
      • 约定
      • 使用方法
        • 添加相关依赖
        • 修改配置
        • 使用 **@DS** 切换数据源
        • 相关代码
        • 多数据源最全配置

特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

快速开始

1、创建数据库 mybatisplus

2、创建表、添加数据

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)
);
-- 添加数据
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、使用 SpringBoor 初始化项目,导入依赖

<!-- MySQL 连接驱动 -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mybatis-plus 依赖 -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version>
</dependency>
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>

注意:不要同时导入 mybatis 和 mybatis-plus

4、配置连接数据库

spring:data:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8username: rootpassword: 123456

5、依次创建实体、DAO层接口

实体

package com.ss.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private Long id; // 注意:mybatis-plus 默认识别的是id, 如果不是id的名称,需要加上@TableId注解private String name;private Integer age;private String email;
}

mapper 接口

package com.ss.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ss.entity.User;
import org.apache.ibatis.annotations.Mapper;public interface UserMapper extends BaseMapper<User> {
}

启动添加扫描所有 Mapper 文件夹

@MapperScan("com.ss.mapper")

7、使用 junit 测试

package com.ss;import com.ss.entity.User;
import com.ss.mapper.UserMapper;
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 {@Autowiredprivate UserMapper userMapper;@Testvoid contextLoads() {List<User> users = userMapper.selectList(null);users.forEach(System.out::println);}}

mybatis-plus 配置

#mybatis-plus 配置
mybatis-plus:mapper-locations: classpath:/mapper/*Mapper.xml#实体扫描,多个package用逗号或者分号分隔,类型对应的别名type-aliases-package: com.ss.mybatisplus.entity# 枚举类 扫描路径,如果配置了该属性,会将路径下的枚举类进行注入,让实体类字段能够简单快捷的使用枚举属性 默认值 null
#  type-enums-package: com.baomidou.springboot.entity.enums# 原生配置configuration:# 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射map-underscore-to-camel-case: true# 枚举tdefault-enum-type-handler: org.apache.ibatis.type.EnumOrdinalTypeHandler# 全局映射是否开启缓存cache-enabled: false# 查询时,关闭关联对象即时加载以提高性能lazy-loading-enabled: false# Mybatis 一级缓存,默认为 SESSION,同一个 session 相同查询语句不会再次查询数据库,STATEMENT 关闭一级缓存local-cache-scope: session# 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果multiple-result-sets-enabled: true# 允许使用列标签代替列名use-column-label: truejdbc-type-for-null: 'null'# 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段call-setters-on-nulls: true# 不允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖use-generated-keys: false# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用log-impl: org.apache.ibatis.logging.stdout.StdOutImpl# 给予被嵌套的resultMap以字段-属性的映射支持 NONE,FULL,PARTIALauto-mapping-behavior: partial# 全局配置global-config:# 是否显示 mybatis-plus LOGObanner: false# 数据库相关配置db-config:#主键类型 默认assign_id, AUTO:"数据库ID自增", INPUT:"用户输入ID",assign_id:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";id-type: auto# 字段验证策略之 insert,在 insert 的时候的字段验证策略, 默认值 NOT_NULLinsert-strategy: not_null# 字段验证策略之 update,在 update 的时候的字段验证策略, 默认值 NOT_NULLupdate-strategy: not_null# 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件, 默认值 NOT_NULLwhere-strategy: not_null#数据库大写下划线转换 默认值 falsecapital-mode: true# 表名是否使用驼峰转下划线命名,只对表名生效 默认为 truetable-underline: false# 表前缀
#      table-prefix: sys_# 配置逻辑删除规则 1代表删除 0代表未删除logic-delete-value: 1  # 默认是1logic-not-delete-value: 0 # 默认值0

常用配置

# MyBatis-plus配置
mybatis-plus:#实体扫描,多个package用逗号或者分号分隔typeAliasesPackage: com.ss.demo.entity# xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)mapper-locations: classpath*:mapper/**/*Mapper.xmlconfiguration:# 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射map-underscore-to-camel-case: true# 是否开启缓存cache-enabled: falsejdbc-type-for-null: 'null'# 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段call-setters-on-nulls: true# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用log-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:db-config:# 主键类型 默认assign_id auto:"数据库ID自增"id-type: auto# 配置逻辑删除规则 1代表删除 0代表未删除logic-delete-value: 1logic-not-delete-value: 0

插入测试及雪花算法

添加(以下内容实在 springboot 测试类中测试)

@Test
void  testInsert(){User user = new User();user.setName("我爱学习");user.setAge(11);user.setEmail("123@qq.com");// 此时没有设置id,会自动生成idint insert = userMapper.insert(user);System.out.println(insert);System.out.println(user);
}

主键生成策略

  • 默认 ASSIGN_ID 全局唯一id,@TableId(type = IdType.ASSIGN_ID)主键生成策略使用雪花算法(默认策略)
  • 主键自增 @TableId(type = IdType.AUTO),数据库中的 id 字段必须设置为自增
  • @TableId(type = IdType.NONE) 未设置主键
  • @TableId(type = IdType.INPUT) 手动输入,设置完后需要手动设置 id
  • @TableId(type = IdType.ASSIGN_ID) 雪花算法生成全局唯一id
  • @TableId(type = IdType.ASSIGN_UUID) UUID 生成策略

对应的源码为

public enum IdType {AUTO(0),NONE(1),INPUT(2),ASSIGN_ID(3),ASSIGN_UUID(4);private final int key;private IdType(int key) {this.key = key;}public int getKey() {return this.key;}
}
查询
// 使用 Condition,先判断条件是否满足 
@Test
void testCondition(){String name = "a";Integer ageBegin = null;Integer ageEnd = 30;QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like(StringUtils.isNotBlank(name),"name",name) // 先判断条件是否满足条件.ge(ageBegin!= null,"age",ageBegin).le(ageEnd!= null,"age",ageEnd);final List<User> list = userMapper.selectList(queryWrapper);list.forEach(System.out::println);
}// Lambda查询,通过实体属性获取映射字段名
@Test
void testLambdaQuery(){String name = "a";Integer ageBegin = null;Integer ageEnd = 30;LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.like(StringUtils.isNotBlank(name),User::getName,name).ge(ageBegin!= null,User::getAge,ageBegin).le(ageEnd!= null,User::getAge,ageEnd);final List<User> list = userMapper.selectList(queryWrapper);list.forEach(System.out::println);
}
更新
// 更新
@Test
void  testUpdate(){User user = new User();user.setId(6L);user.setName("我爱学习11111 ");// 此时没有设置id,会自动生成idint count = userMapper.updateById(user);System.out.println(count);
}// 根据指定条件修改
@Test
void testUpdate2() {// 将年两大于20并且用户中包含a 或者邮箱为 null 的用户信息修改QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 20).like("name", "a").or()  // 默认是用 and 连接.isNull("email");User user = new User();user.setName("张三");final int update = userMapper.update(user, queryWrapper);System.out.println("count:" + update);
}// 通过 UpdateWrapper 修改
@Test
void testUpdateWrapper() {// 将年两大于20并且用户中包含a 或者邮箱为 null 的用户信息修改UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.like("name", "a").and(i -> i.gt("age", "20").or().isNull("email")); // lambada 会优先执行updateWrapper.set("name", "老王").set("email", "123@qq.com");final int update = userMapper.update(null, updateWrapper);System.out.println("count:" + update);
}// 使用 LambdaUpdateWrapper 修改
@Test
void testLambdaUpdate() {// 将年两大于20并且用户中包含a 或者邮箱为 null 的用户信息修改LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();updateWrapper.like(User::getName, "a").and(i -> i.gt(User::getAge, "20").or().isNull(User::getEmail)); // lambada 会优先执行updateWrapper.set(User::getName, "老王").set(User::getEmail, "123@qq.com");final int update = userMapper.update(null, updateWrapper);System.out.println("count:" + update);
}
删除
@Test
void testDelete() {// 删除邮箱的地址为 null的用户信息QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.isNull("email");final int delete = userMapper.delete(queryWrapper);System.out.println("count:" + delete);
}
查询指定字段
@Test
void testFields(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.select("name","name","email");final List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);maps.forEach(System.out::println);
}
子查询
@Test
void testChildrenSelect(){// 查询id小于等于100的用户信息QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.inSql("id","select id from user where id <= 100");final List<User> list = userMapper.selectList(queryWrapper);list.forEach(System.out::println);
}

自动填充

1、修改表结构

ALTER TABLE `mybatisplus`.`user` 
ADD COLUMN `create_time` datetime NULL COMMENT '创建时间' AFTER `email`,
ADD COLUMN `update_time` datetime NULL COMMENT '修改时间' AFTER `create_time`;

2、实体添加对应的字段

// 添加是填充时间
@TableField(fill = FieldFill.INSERT)
private Date updateTime;// 添加和修改时都填充时间
@TableField(fill = FieldFill.INSERT)
private Date createTime;

3、自定义处理器处理时间,官网地址:https://mp.baomidou.com/guide/auto-fill-metainfo.html

package com.ss.handler;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;/*** mybatis-plus 自动填充设置*/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {// 插入的时候填充策略@Overridepublic void insertFill(MetaObject metaObject) {// 方法1metaObject.setValue("createDate", LocalDateTime.now());metaObject.setValue("createBy", LocalDateTime.now());// 方法2 使用 时间格式或者使用以下时间戳this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); this.strictInsertFill(metaObject, "updateTime", Date.class, new Date()); // 方法3this.setFieldValByName("createBy", "admin", metaObject);// 起始版本 3.3.0(推荐使用)// this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());// 或者
//        this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)// 或者
//        this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)}// 修改的时候填充策略@Overridepublic void updateFill(MetaObject metaObject) {// 起始版本 3.3.0(推荐)this.strictUpdateFill(metaObject, "updateTime",Date.class,new Date()); this.setFieldValByName("lastModifiedBy", "admin", metaObject);// 或者
//        this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)// 或者
//        this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)}
}

配置完成,测执行以上添加、更新即可

乐观锁

乐观锁:非常乐观,总是认为没有问题,无论干什么都不会上锁

悲观锁:非常悲观,总是认为会出问题,无论干什么搜索加锁

当要更新一条记录的时候,希望这条记录没有被别人更新

乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

测试 mybatis-plus 乐观锁

1、给数据库添加字段

ALTER TABLE `mybatisplus`.`user` 
ADD COLUMN `version` int(10) NOT NULL DEFAULT 1 COMMENT '乐观锁' AFTER `email`;

2、实体类添加对应的字段

// 乐观锁version注解
@Version
private Integer version;

说明:

  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity
  • 仅支持 updateById(id)update(entity, wrapper) 方法
  • update(entity, wrapper) 方法下, wrapper 不能复用!!!

3、添加 MybatisPlusConfig 配置类

package com.ss.config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;/*** mybatis-plus 配置类*/
@EnableTransactionManagement
@Configuration
public class MyBatisConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 乐观锁插件interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}
}

测试乐观锁

// 测试乐观锁成功 
@Test
public void testOptimisticLocker(){// 1、查询用户信息User user = userMapper.selectById(6L);// 2、修改用户信息user.setName("good study");user.setEmail("aa@qq.com");// 3、执行更新操作userMapper.updateById(user);
}// 测试乐观锁失败,模拟多线程下,注意版本号开始一定要存在
@Test
public void testOptimisticLocker2() {// 线程 1User user = userMapper.selectById(6L);user.setName("11111");user.setEmail("111@qq.com");// 模拟另外一个线程执行了插队操作User user2 = userMapper.selectById(6L);user2.setName("22222");user2.setEmail("22222@qq.com");userMapper.updateById(user2);// 如果没有乐观锁就会覆盖插队线程的值userMapper.updateById(user);
}

通用枚举

数据库表添加字段

ALTER TABLE `mybatisplus`.`user` 
ADD COLUMN `sex` int(2) NULL COMMENT '性别' AFTER `email`;

枚举类添加性别

import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;@Getter
public enum SexEnum {MALE(1,"男"),FEMALE(1,"女");@EnumValue  // 将注解所表示的属性的值存储在数据库中private Integer sex;private String sexName;SexEnum(Integer sex, String sexName) {this.sex = sex;this.sexName = sexName;}
}

实体添加对应的性别枚举

private SexEnum sex;

配置文件添加枚举包扫描

#mybatis-plus 配置
mybatis-plus:# 枚举类 扫描路径,如果配置了该属性,会将路径下的枚举类进行注入,让实体类字段能够简单快捷的使用枚举属性 默认值 nulltype-enums-package: com.ss.mybatisplus.enums

测试代码,添加数据

@Test
public void testEnum() {User user = new User();user.setName("admin");user.setAge(23);user.setSex(SexEnum.MALE);final int result = userMapper.insert(user);System.out.println("result:" + result);
}

代码自动生成器

方式一(新版)

1、引入依赖

注意:MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.1</version>
</dependency>
<!-- 使用 freemarker 模板引擎 -->
<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version>
</dependency>

2、相关代码

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;import java.util.Collections;public class GeneratorTest {public static void main(String[] args) {FastAutoGenerator.create("jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8","root","root").globalConfig(builder -> {builder.author("ss")  //设置作者
//                    .enableSwagger() //开启swagger.fileOverride() //覆盖已生成的文件.outputDir("D://mybatis_plus"); //指定输出目录}).packageConfig(builder -> {builder.parent("com.ss") // 设置父报名.moduleName("mybatisplus") //设置父包模块名
//                            .entity("entity")  // 设置包名
//                            .mapper("mapper")
//                            .service("service")
//                            .controller("controller")
//                            .serviceImpl("impl").pathInfo(Collections.singletonMap(OutputFile.mapper,"D://mybatis_plus")); // 设置Mapper.xml生成路径}).strategyConfig(builder -> {builder.addInclude("user")  // 设置需要生成的表名,可以是一个集合.addTablePrefix("t_","sys_"); // 设置过滤表前缀}).templateEngine(new FreemarkerTemplateEngine()) // 使用 Freemarker.execute();}
}

方式二(旧版)

1、引入依赖

注意:MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version>
</dependency><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.3</version>
</dependency>

2、编写代码生成类

官网地址:链接

mport com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
// 代码自动生成器
public class GeneratorCodeTest {public static void main(String[] args) {// 需要构建一个 代码自动生成器 对象AutoGenerator mpg = new AutoGenerator();// 配置策略// 1、全局配置GlobalConfig gc = new GlobalConfig();String projectPath = System.getProperty("user.dir"); // 项目所在路径gc.setOutputDir(projectPath+"/mybatisplus-demo/src/main/java"); //完整路径gc.setAuthor("ss");gc.setOpen(false);gc.setFileOverride(false); // 是否覆盖gc.setServiceName("%sService"); // 去Service的I前缀gc.setIdType(IdType.AUTO); // id生成策略gc.setDateType(DateType.ONLY_DATE);  // 时间策略gc.setSwagger2(true);  // 是否开启swaggermpg.setGlobalConfig(gc);//2、设置数据源DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://localhost:3306/gulimall_pms?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");dsc.setDriverName("com.mysql.cj.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("root");dsc.setDbType(DbType.MYSQL); // 数据库类型mpg.setDataSource(dsc);//3、包的配置PackageConfig pc = new PackageConfig();
//        pc.setModuleName("blog");  // 模块名 默认 ""pc.setParent("com.ss");  // 对应的包名pc.setEntity("entity");pc.setMapper("mapper");pc.setService("service");pc.setController("controller");mpg.setPackageInfo(pc);//4、策略配置StrategyConfig strategy = new StrategyConfig();strategy.setInclude("pms_attr"); // 设置要映射的表名 支持多个表名strategy.setNaming(NamingStrategy.underline_to_camel);strategy.setColumnNaming(NamingStrategy.underline_to_camel);strategy.setEntityLombokModel(true); // 自动lombok;strategy.setLogicDeleteFieldName("deleted");// 自动填充配置TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);TableFill gmtModified = new TableFill("gmt_modified",FieldFill.INSERT_UPDATE);ArrayList<TableFill> tableFills = new ArrayList<>();tableFills.add(gmtCreate);tableFills.add(gmtModified);strategy.setTableFillList(tableFills);// 乐观锁strategy.setVersionFieldName("version");strategy.setRestControllerStyle(true);strategy.setControllerMappingHyphenStyle(true); //mpg.setStrategy(strategy);mpg.execute(); //执行}
}

分页插件

@Configuration
@EnableTransactionManagement //开启事务
public class MyBatisPlusConfig {// 旧版@Beanpublic PaginationInnerInterceptor paginationInnerInterceptor(){PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();//设置请求的页面大于最大页后操作,true调回到首页,false继续请求,默认为falsepaginationInnerInterceptor.setOverflow(true);//设置最大单页限制数量,默认500条,-1不受限制paginationInnerInterceptor.setMaxLimit(1000L);//数据库类型paginationInnerInterceptor.setDbType(DbType.MYSQL);return paginationInnerInterceptor;}// 最新版@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}

测试分页

// MyBatisPlus 插件分页,首先配置分页相关信息
@Test
void testPage(){Page<User> page = new Page<>(1,3);userMapper.selectPage(page, null);System.out.println(page.getRecords()); //记录System.out.println(page.getPages()); // 几页System.out.println(page.getTotal()); // 总条数System.out.println(page.hasNext()); // 是否有下一页System.out.println(page.hasPrevious());  // 是否有上一页
}

自定义分页

1、Mapper 接口

/**
* 通过年龄查询用户信息并分页
* @param page Mybatis-Plus 提供的分页对象,必须位于第一个参数的位置
* @param age
* @return
*/
Page<User> selectPageVO(@Param("page") Page<User> page,@Param("age") Integer age);

2、UserMapper.xml 对应的sql

<?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.ss.mybatisplus.mapper.UserMapper"><select id="selectPageVO" resultType="User">select * from user where age >= #{age}</select>
</mapper>

3、测试查询

@Test
void testPageVO(){Page<User> page = new Page<>(1,3);userMapper.selectPageVO(page, 30);System.out.println(page.getRecords());System.out.println(page.getPages());System.out.println(page.getTotal());System.out.println(page.hasNext());System.out.println(page.hasPrevious());
}

多数据源

简介

介绍:dynamic-datasource-spring-boot-starter 是一个基于 springboot 的快速集成多数据源的启动器。

特性

  • 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
  • 支持数据库敏感配置信息 加密 ENC()。
  • 支持每个数据库独立初始化表结构schema和数据库database。
  • 支持无数据源启动,支持懒加载数据源(需要的时候再创建连接)。
  • 支持 自定义注解 ,需继承DS(3.2.0+)。
  • 提供并简化对Druid,HikariCp,BeeCp,Dbcp2的快速集成。
  • 提供对Mybatis-Plus,Quartz,ShardingJdbc,P6sy,Jndi等组件的集成方案。
  • 提供 自定义数据源来源 方案(如全从数据库加载)。
  • 提供项目启动后 动态增加移除数据源 方案。
  • 提供Mybatis环境下的 纯读写分离 方案。
  • 提供使用 spel动态参数 解析数据源方案。内置spel,session,header,支持自定义。
  • 支持 多层数据源嵌套切换 。(ServiceA >>> ServiceB >>> ServiceC)。
  • 提供 基于seata的分布式事务方案。
  • 提供 本地多数据源事务方案

约定

  1. 本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD。
  2. 配置文件所有以下划线 _ 分割的数据源 首部 即为组的名称,相同组名称的数据源会放在一个组下。
  3. 切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换。
  4. 默认的数据源名称为 master ,你可以通过 spring.datasource.dynamic.primary 修改。
  5. 方法上的注解优先于类上注解。
  6. DS支持继承抽象类上的DS,暂不支持继承接口上的DS。

使用方法

添加相关依赖
<!-- Mysql驱动包 -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency><!-- Mybatis-plus 依赖 -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version>
</dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version>
</dependency><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.1</version>
</dependency>
修改配置
spring:datasource:dynamic:# 设置默认的数据源或者数据源组,默认值即为masterprimary: master# 严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源strict: falsedatasource:master:driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置url: jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: rootslave_1:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/dtcms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: rootslave_2:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/renren?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: root
使用 @DS 切换数据源

@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解

注解结果
没有@DS默认数据源
@DS(“dsName”)dsName可以为组名也可以为具体某个库的名称
相关代码

实体

@Data
public class User {private Long id;private String name;private Integer age;private String email;private Integer sex;private Integer version;
}
@Data
@TableName("sys_role")
public class Role {private Long id;private String name;private String remark;
}

Mapper接口

@Mapper
@DS("master")
public interface UserMapper extends BaseMapper<User> {}
@Mapper
@DS("slave_1")
public interface RoleMapper extends BaseMapper<Role> {}

Service接口

public interface UserService extends IService<User> {}
public interface RoleService extends IService<Role> {}

ServiceImpl实现类

@DS("master")
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}
@Service
@DS("slave_1")
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {}

测试

@SpringBootTest
class DemoApplicationTests {@Autowiredprivate UserService userService;@Autowiredprivate RoleService roleService;@Testvoid contextLoads() {// 直接使用 service方法
//        System.out.println(userService.getById(1L));
//        System.out.println(roleService.getById(9L));// Mapper方法final List<Role> roleList = roleService.getBaseMapper().selectList(null);roleList.forEach(System.out::println);System.out.println("=======================");final List<User> userList = userService.getBaseMapper().selectList(null);userList.forEach(System.out::println);}
}
多数据源最全配置

使用 druid 连接池,选择添加必要的配置即可(不必都配置)

spring:datasource:dynamic:# 设置默认的数据源或者数据源组,默认值即为masterprimary: master# 严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源strict: falsedatasource:master:driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置url: jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: rootslave_1:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/dtcms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: rootslave_2:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/renren?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: root# 使用druid数据库连接池type: com.alibaba.druid.pool.DruidDataSource# druid 全局配置druid:# 初始连接数initial-size: 5# 最小连接池数量min-idle: 10# 最大连接池数量max-active: 20# 获取配置连接等待超时时间max-wait: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒time-between-connect-error-millis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒min-evictable-idle-time-millis: 300000# 配置一个连接在池中最大生存的时间,单位是毫秒max-evictable-idle-time-millis: 900000# 配置检测连接是否有效validation-query: SELECT * FROM DUAL# 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效test-while-idle: true# 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能test-on-borrow: false# 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能test-on-return: false# 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。keep-alive: true# 物理超时时间,默认:-1phy-timeout-millis: -1# 物理最大连接数,默认:-1(不建议配置)phy-max-use-count: -1# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙filters: stat,wall,slf4j,config# 是否启用web-stat-filter默认值falseweb-stat-filter:enabled: true# 是否启用StatViewServlet(监控页面)默认值为false(考虑到安全问题默认并未启动,如需启用建议设置密码或白名单以保障安全)stat-view-servlet:enabled: true# 设置白名单,不填则允许所有访问allow: /druid/*login-username:login-password:#mybatis-plus 配置
mybatis-plus:mapper-locations: classpath:/mapper/*Mapper.xml#实体扫描,多个package用逗号或者分号分隔type-aliases-package: com.example.demo.entity# 枚举类 扫描路径,如果配置了该属性,会将路径下的枚举类进行注入,让实体类字段能够简单快捷的使用枚举属性 默认值 nulltype-enums-package: com.example.demo.enums# 原生配置configuration:# 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射map-underscore-to-camel-case: true# 全局映射是否开启缓存cache-enabled: false# 查询时,关闭关联对象即时加载以提高性能lazy-loading-enabled: false# Mybatis 一级缓存,默认为 SESSION,同一个 session 相同查询语句不会再次查询数据库,STATEMENT 关闭一级缓存local-cache-scope: session# 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果multiple-result-sets-enabled: true# 允许使用列标签代替列名use-column-label: truejdbc-type-for-null: 'null'# 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段call-setters-on-nulls: true# 不允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖use-generated-keys: false# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用log-impl: org.apache.ibatis.logging.stdout.StdOutImpl# 给予被嵌套的resultMap以字段-属性的映射支持 NONE,FULL,PARTIALauto-mapping-behavior: partial# 全局配置global-config:# 是否显示 mybatis-plus LOGObanner: false# 数据库相关配置db-config:#主键类型 默认assign_id, AUTO:"数据库ID自增", INPUT:"用户输入ID",assign_id:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";id-type: auto# 字段验证策略之 insert,在 insert 的时候的字段验证策略, 默认值 NOT_NULLinsert-strategy: not_null# 字段验证策略之 update,在 update 的时候的字段验证策略, 默认值 NOT_NULLupdate-strategy: not_null# 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件, 默认值 NOT_NULLwhere-strategy: not_null#数据库大写下划线转换 默认值 falsecapital-mode: false# 表名是否使用驼峰转下划线命名,只对表名生效 默认为 truetable-underline: false# 表前缀#      table-prefix: sys_# 配置逻辑删除规则 1代表删除 0代表未删除logic-delete-value: 1  # 默认是1logic-not-delete-value: 0 # 默认值0

maven插件自动生成策略可参考

https://gitee.com/baomidou/mybatisplus-maven-plugin?_from=gitee_search

这篇关于Mybatis-Plus 5分钟快速上手,10分钟熟练使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/772493

相关文章

使用Redis快速实现共享Session登录的详细步骤

《使用Redis快速实现共享Session登录的详细步骤》在Web开发中,Session通常用于存储用户的会话信息,允许用户在多个页面之间保持登录状态,Redis是一个开源的高性能键值数据库,广泛用于... 目录前言实现原理:步骤:使用Redis实现共享Session登录1. 引入Redis依赖2. 配置R

使用Python的requests库调用API接口的详细步骤

《使用Python的requests库调用API接口的详细步骤》使用Python的requests库调用API接口是开发中最常用的方式之一,它简化了HTTP请求的处理流程,以下是详细步骤和实战示例,涵... 目录一、准备工作:安装 requests 库二、基本调用流程(以 RESTful API 为例)1.

使用Python开发一个Ditto剪贴板数据导出工具

《使用Python开发一个Ditto剪贴板数据导出工具》在日常工作中,我们经常需要处理大量的剪贴板数据,下面将介绍如何使用Python的wxPython库开发一个图形化工具,实现从Ditto数据库中读... 目录前言运行结果项目需求分析技术选型核心功能实现1. Ditto数据库结构分析2. 数据库自动定位3

Python yield与yield from的简单使用方式

《Pythonyield与yieldfrom的简单使用方式》生成器通过yield定义,可在处理I/O时暂停执行并返回部分结果,待其他任务完成后继续,yieldfrom用于将一个生成器的值传递给另一... 目录python yield与yield from的使用代码结构总结Python yield与yield

Go语言使用select监听多个channel的示例详解

《Go语言使用select监听多个channel的示例详解》本文将聚焦Go并发中的一个强力工具,select,这篇文章将通过实际案例学习如何优雅地监听多个Channel,实现多任务处理、超时控制和非阻... 目录一、前言:为什么要使用select二、实战目标三、案例代码:监听两个任务结果和超时四、运行示例五

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比