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

相关文章

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加

SpringBoot基于MyBatis-Plus实现Lambda Query查询的示例代码

《SpringBoot基于MyBatis-Plus实现LambdaQuery查询的示例代码》MyBatis-Plus是MyBatis的增强工具,简化了数据库操作,并提高了开发效率,它提供了多种查询方... 目录引言基础环境配置依赖配置(Maven)application.yml 配置表结构设计demo_st

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

使用Python绘制蛇年春节祝福艺术图

《使用Python绘制蛇年春节祝福艺术图》:本文主要介绍如何使用Python的Matplotlib库绘制一幅富有创意的“蛇年有福”艺术图,这幅图结合了数字,蛇形,花朵等装饰,需要的可以参考下... 目录1. 绘图的基本概念2. 准备工作3. 实现代码解析3.1 设置绘图画布3.2 绘制数字“2025”3.3

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

Jsoncpp的安装与使用方式

《Jsoncpp的安装与使用方式》JsonCpp是一个用于解析和生成JSON数据的C++库,它支持解析JSON文件或字符串到C++对象,以及将C++对象序列化回JSON格式,安装JsonCpp可以通过... 目录安装jsoncppJsoncpp的使用Value类构造函数检测保存的数据类型提取数据对json数

python使用watchdog实现文件资源监控

《python使用watchdog实现文件资源监控》watchdog支持跨平台文件资源监控,可以检测指定文件夹下文件及文件夹变动,下面我们来看看Python如何使用watchdog实现文件资源监控吧... python文件监控库watchdogs简介随着Python在各种应用领域中的广泛使用,其生态环境也

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链

springboot整合 xxl-job及使用步骤

《springboot整合xxl-job及使用步骤》XXL-JOB是一个分布式任务调度平台,用于解决分布式系统中的任务调度和管理问题,文章详细介绍了XXL-JOB的架构,包括调度中心、执行器和Web... 目录一、xxl-job是什么二、使用步骤1. 下载并运行管理端代码2. 访问管理页面,确认是否启动成功

使用Nginx来共享文件的详细教程

《使用Nginx来共享文件的详细教程》有时我们想共享电脑上的某些文件,一个比较方便的做法是,开一个HTTP服务,指向文件所在的目录,这次我们用nginx来实现这个需求,本文将通过代码示例一步步教你使用... 在本教程中,我们将向您展示如何使用开源 Web 服务器 Nginx 设置文件共享服务器步骤 0 —