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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/719151.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/719151.shtml
英文地址,請注明出處:http://en.pswp.cn/news/719151.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Text2SQL 和 智能問答 的提示詞寫法

Text2SQL 生成 Query SQL System Message You are a {dialect} expert. Given an input question, creat a syntactically correct {dialect} query to run. Unless the user specifies in the question a specific number of examples to obtain, query for at most {top_k} r…

Linux 創建.NET 服務

文章目錄 創建服務啟用服務啟動 & 重啟服務查看服務狀態問題排查 創建服務 將服務文件上傳到 /home/mes/api-mes-dev, 其他服務修改對應的目錄在 /usr/lib/systemd/system/ 創建 mesapi-dev.service, 其他服務修改對應文件名 [Unit] Descriptionmesapi-dev service[Servi…

探索Linux世界:初次接觸和基本指令(文件操作)

文章目錄 1.基本介紹和準備2.基本指令和Linux的基本操作3.幾個重要基本指令3.1 ls - 列出文件和目錄3.1.1文件的知識3.1.2 .和..文件 3.2pwd - 顯示當前工作目錄3.2.1路徑知識 3.3 cd - 切換目錄3.4 touch - 創建文件或更新時間戳3.5mkdir - 創建新目錄3.6rm - 刪除文件或目錄3…

leetcode熱題100學習計劃-鏈表-反轉鏈表

思路 使用頭插法逆轉鏈表 注&#xff1a;鏈表一般為操作方便&#xff0c;頭結點不存值&#xff0c;是一個虛擬節點 代碼 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val)…

深入了解 Android 中的 FrameLayout 布局

FrameLayout 是 Android 中常用的布局之一&#xff0c;它允許子視圖堆疊在一起&#xff0c;可以在不同位置放置子視圖。在這篇博客中&#xff0c;我們將詳細介紹 FrameLayout 的屬性及其作用。 <FrameLayout xmlns:android"http://schemas.android.com/apk/res/androi…

【數據結構和算法初階(C語言)】帶環鏈表問題詳解(快慢指針的燒腦應用)

目錄 1.鋪墊-----帶環鏈表基本了解 2. 題目&#xff1a;環形鏈表 3.環形鏈表|| ?編輯 3.1題解1 3.2 題解2 4.總結 1.鋪墊-----帶環鏈表基本了解 環形鏈表題目啟迪&#xff1a; 環形鏈表特點&#xff1a;遍歷鏈表會出現一模一樣的地址 2. 題目&#xff1a;環形鏈表 給…

數字化轉型導師鵬:政府數字化轉型政務服務類案例研究

政府數字化轉型政務服務類案例研究 課程背景&#xff1a; 很多地方政府存在以下問題&#xff1a; 不清楚標桿省政府數字化轉型的政務服務類成功案例 不清楚地級市政府數字化轉型的政務服務類成功案例 不清楚縣區級政府數字化轉型的政務服務類成功案例 課程特色&#x…

基于C語言實現內存型數據庫(kv存儲)

基于C語言實現內存型數據庫(kv存儲) 文章目錄 基于C語言實現內存型數據庫(kv存儲)1. 項目背景1.1 Redis介紹1.2 項目預期及基本架構 2. 服務端原理及代碼框架2.1 網絡數據回環的實現2.2 array的實現2.3 rbtree的實現2.4 btree的實現2.5 hash的實現2.6 dhash的實現2.7 skiplist的…

XV4001KC數字輸出 車載用(piezoman)

EPSON的XV4001KC角速度傳感器是為滿足汽車行業對高精度和高可靠性需求而設計的。它不僅提供了高級的運動監測特性&#xff0c;高精度的角速度測量和溫度監測功能&#xff0c;而且其緊湊的設計6.04.83.3mm尺寸對于空間受限的車載環境來說&#xff0c;是一大優勢&#xff0c;使得…

二十篇esp345

from machine import I2C,Pin from ssd1306 import SSD1306_I2C i2c I2C(sdaPin(“Y8”), sclPin(“Y6”)) oled SSD1306_I2C(128, 64, i2c, addr0x3c) oled.text(“Hello World!”, 0, 0) oled.text(“MicroPython”, 0, 20) oled.text(“By 01Studio”, 0, 50) oled.show()…

vue 中在子頁面中使用watch監聽父頁面數據而導致接口多次調用

vue 中在子頁面中使用watch監聽父頁面數據而導致接口多次調用 解決方式 debounce function debounce(func, delay) {let timerId;return function(...args) {clearTimeout(timerId);timerId setTimeout(() > {func.apply(this, args);}, delay);}; }watch中 watch:{監聽值…

AIGC 知識:機器學習中的“微調“和“遷移學習“有什么區別?

以下是關于**微調 (fine-tuning)和遷移學習 (Transfer learning)**的區別&#xff0c;涉及到機器學習和深度學習的上下文&#xff1a; 遷移學習&#xff1a; 概述&#xff1a;遷移學習涉及使用預訓練模型作為新任務或領域的起點。目標&#xff1a;利用預訓練模型在大型數據集上…

政務瀏覽器——打通信創閉環最后一公里

當前&#xff0c;信創建設工作主要集中在芯片、操作系統、數據庫以及pc整機&#xff0c;這些領域基本可用&#xff0c;或者達到了市場主流水平。但是&#xff0c;政務辦事場景下的信創落地仍然困難重重&#xff0c;很多地方不得不裝雙系統或買兩臺設備來來平衡日常業務和信創考…

Qt:基于QQuickFramebufferObject顯示QImage到QML中

GItHub地址 簡介 本倉庫實現了一個在QML框架中&#xff0c;顯示QImage數據的QML控件&#xff0c;取名為JQImageItem 本控件針對的場合是需要顯示并且頻繁修改QImage的場景&#xff0c;例如視頻顯示。 提供了2個實現版本&#xff0c;一個是基于QQuickFramebufferObject&…

STM32CubeIDE基礎學習-軟件安裝,環境搭建

STM32CubeIDE基礎學習-軟件介紹及環境搭建步驟 文章目錄 STM32CubeIDE基礎學習-軟件介紹及環境搭建步驟前言第1章 STM32CubeIDE 介紹1.1 軟件描述1.2 軟件支持的功能及特點 第2章 STM32CubeIDE 軟件安裝2.1 STM32CubeIDE 軟件獲取方法2.2 STM32CubeIDE 軟件安裝步驟2.2.1 錯誤安…

C++模板完整版

顧得泉&#xff1a;個人主頁 個人專欄&#xff1a;《Linux操作系統》 《C從入門到精通》 《LeedCode刷題》 鍵盤敲爛&#xff0c;年薪百萬&#xff01; 一、泛型編程 如何實現一個通用的交換函數呢&#xff1f; void Swap(int& left, int& right) {int temp left…

抖店入駐費用是多少?新手入駐都有哪些要求?2024費用明細!

我是電商珠珠 我做電商做了將近五年&#xff0c;做抖店做了三年多&#xff0c;期間還帶著學員一起做店。 今天&#xff0c;就來給大家詳細的講一下在抖音開店&#xff0c;需要多少費用&#xff0c;最低需要投入多少。 1、營業執照200元左右 就拿個體店舉例&#xff0c;在入…

hook函數——useReducer

目錄 1.useReducer定義2.useReducer用法3.useState和useReducer區別 1.useReducer定義 const [state, dispatch] useReducer(reducer, initialArg, init?) reducer&#xff1a;用于更新 state 的純函數。參數為 state 和 action&#xff0c;返回值是更新后的 state。state …

這波操作看麻了!十億行數據,從71s到1.7s的優化之路。

節期間關注到了一個關于 Java 方面的比賽&#xff0c;很有意思。由于是開源的&#xff0c;我把項目拉下來試圖學&#xff08;白&#xff09;習&#xff08;嫖&#xff09;別人的做題思路&#xff0c;在這期間一度讓我產生了一個自我懷疑&#xff1a; 他們寫的 Java 和我會的 Ja…

解鎖軟件管理新篇章,Allegro許可證使用規定全解

在數字化經濟的時代&#xff0c;軟件已經成為企業運營的關鍵要素。然而&#xff0c;軟件的使用往往伴隨著一系列的合規性問題&#xff0c;導致企業面臨潛在的風險和成本。Allegro許可證作為業界領先的軟件解決方案提供商&#xff0c;為企業提供全面的許可證使用規定&#xff0c…