Mybatis Plus ActiveRecord 模式

Mybatis Plus ActiveRecord 模式 使用

DEMO源碼地址 https://gitee.com/JackSong2019/demo-mybatis3.git

前言

ActiveRecord 模式 簡介
  • ActiveRecord 是一種設計模式,它是一種在軟件開發中用于管理關系數據庫的模式,他簡化了數據庫操作的流程,使得開發人員可以更專注于業務邏輯而非數據庫細節。它提供了一種面向對象的方法來處理數據庫,使得數據庫操作變得更加直觀、易于維護和擴展。
    • 關于 ActiveRecord 模式的一些重要概念和特點
      1、對象關系映射 (ORM):ActiveRecord 是一種對象關系映射 (ORM) 模式的實現。它將數據庫中的表格(或集合)映射到應用程序中的對象。
    每個數據庫表格對應于一個 ActiveRecord 模型類,而表格中的每一行數據則對應于該模型類的一個實例對象。2、模型類(Model Class):在 ActiveRecord 中,模型類是應用程序中操作數據庫的主要組件。每個模型類代表一個數據庫表格,
    并且可以用于查詢、插入、更新和刪除表格中的數據。模型類通常繼承自框架提供的 ActiveRecord 基類,
    這個基類提供了許多用于數據庫操作的方法和功能。3、數據表與字段映射:ActiveRecord 模式通過約定俗成的方式將數據表中的字段映射到模型類的屬性。
    例如,一個數據庫表格中的 users 表可能會映射到一個 User 模型類,表中的每個字段(如 id、name、email 等)
    則對應于模型類中的屬性。4、CRUD 操作:ActiveRecord 模式使得執行 CRUD 操作變得簡單和直觀。通過模型類,我們可以輕松地執行
    創建(Create)、讀取(Read)、更新(Update)和刪除(Delete)這些基本的數據庫操作,
    而無需編寫復雜的 SQL 查詢語句。5、關聯和查詢:ActiveRecord 支持定義和使用關聯關系,比如一對一、一對多、多對多等關系。
    這使得在處理復雜的數據模型時更加便捷。同時,ActiveRecord 提供了強大的查詢接口,
    允許開發人員使用鏈式調用的方式構建復雜的數據庫查詢,而無需直接編寫 SQL。6、數據驗證和回調:ActiveRecord 提供了內置的數據驗證功能,可以確保數據的完整性和一致性。
    開發人員可以在模型類中定義驗證規則,以確保數據符合預期的格式和約束。此外,
    ActiveRecord 還支持回調機制,允許在數據保存、更新等操作前后執行特定的代碼。
    

一、前置條件 JDK版本 Springboot版本 MybatisPlus版本

  • JDK 17 以上
  • SpringBoot 3.+ 以上
  • MybatisPlus 3.+ 以上
  • 說明: 實體類只需繼承 Model 類即可進行強大的 CRUD 操作 ; 需要項目中已注入對應實體的BaseMapper

二、示例數據腳本 將腳本數據腳本導入到數據庫中

-- user 表Schema 腳本
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`
(id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',age INT NULL DEFAULT NULL COMMENT '年齡',email VARCHAR(50) NULL DEFAULT NULL COMMENT '郵箱',PRIMARY KEY (id)
);--  Data 腳本
DELETE FROM `user`;
INSERT INTO `user` (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

三、初始化工程

  • 1、 創建一個空的 Spring Boot 工程
  提示 :a、可以使用 Spring Initializer (opens new window)快速初始化一個 Spring Boot 工程b、也可以創建一個maven空工程,然后按需要引入依賴

#添加依賴

  • 2、 引入 Spring Boot Starter 父工程
      <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><!-- 因為使用的mybatis plus 3.+ 所以需要指定springboot3.+以上的版本 --><version>3.1.5</version><relativePath/></parent>
    
  • 3、 引入 spring-boot-starter、spring-boot-starter-test、mybatis-plus-boot-starter、mysql 依賴:
  <dependencies><!-- SpringBoot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><!-- mybatis plus3 --><dependency><groupId>com.baomidou</groupId><!--3.5.4開始,支持SpringBoot3使用此版本--><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.4</version></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version><scope>runtime</scope></dependency></dependencies>
  • 4、 配置application.yml 文件 主要是數據庫連接信息
spring:datasource:url: jdbc:mysql://localhost:3306/test_db?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=trueusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
  • 5、 添加啟動類,在 Spring Boot 啟動類中添加 @MapperScan 注解,掃描 Mapper 文件夾
package org.example;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@MapperScan("org.example.mapper")
public class DemoMybatis3Application {public static void main(String[] args) {SpringApplication.run(DemoMybatis3Application.class, args);}
}
  • 6、編寫 User 實體類 及 UserMapper 接口
@Data
@TableName("`user`")
public class User extends Model<User>{private Long id;private String name;private Integer age;private String email;
}
public interface UserMapper  extends BaseMapper<User> {}
  • 7、 CRUD操作測試
 /*** 測試查詢所有*/@Testpublic void testSelectAll() {System.out.println(("----- selectAll method test ------"));User user = new User();List<User> userList = user.selectAll();userList.forEach(System.out::println);}/*** 測試新增*/@Testpublic void add() {System.out.println(("----- add method test ------"));User user = new User();user.setName("趙六");user.setAge(30);user.setEmail("zhaoliu@163.com");user.insert();System.out.println(user.toString());}/*** 測試單條查詢*/@Testpublic void getOne() {System.out.println(("----- getOne method test ------"));User user = new User();
//        user.setId(9L);
//        user = user.selectById();user = user.selectById(9L);System.out.println(user.toString());}/*** 測試修改*/@Testpublic void update() {System.out.println(("----- update method test ------"));User user = new User();user.setId(9L);user.setName("趙六六");user.setAge(33);user.setEmail("zhaoliu@163.com");user.updateById();System.out.println(user.toString());}/*** 測試刪除*/@Testpublic void del() {System.out.println(("----- del method test ------"));User user = new User();
//        user.setId(9L);
//        user.deleteById();boolean b = user.deleteById(9L);System.out.println(b);}
  • 8、 SimpleQuery 工具類
說明:
對selectList查詢后的結果用Stream流進行了一些封裝,使其可以返回一些指定結果,簡潔了api的調用
需要項目中已注入對應實體的BaseMapper

測試代碼示例

 @Test
public void listOperate() {
System.out.println(("----- SimpleQuery listOperate method test ------"));
List<String> userNames = new java.util.ArrayList<>();
List<String> emails = new java.util.ArrayList<>();
// 該查詢 追加了 獲取id集,打印,獲取name集,獲取email集的操作
List<Long> ids = SimpleQuery.list(lambdaQuery(),User::getId, System.out::println, user -> userNames.add(user.getName()),user -> emails.add(user.getEmail()));
// 打印ids
ids.forEach(System.out::println);
// 打印userNames
userNames.forEach(System.out::println);
// 打印emails
emails.forEach(System.out::println);
}/**
* 測試查詢 keyMap 返回為Map<屬性,實體>
*/
@Test
public void keyMap() {
System.out.println(("----- SimpleQuery keyMap method test ------"));
// 查詢表內記錄,封裝返回為Map<屬性,實體>
//        Map<Long,User> userMap = SimpleQuery.keyMap(Wrappers.lambdaQuery(),
//                User::getId);
// 查詢表內記錄,封裝返回為Map<屬性,實體>,考慮了并行流的情況
Map<Long,User> userMap = SimpleQuery.keyMap(lambdaQuery(),User::getId,true);
userMap.forEach((k,v)->{System.out.println(k+"-->"+v);
});
}/**
* 測試查詢 map  返回為Map<屬性,屬性>
*/
@Test
public void map() {
System.out.println(("----- SimpleQuery map method test ------"));
//  查詢表內記錄,封裝返回為Map<屬性,屬性>
//        Map<Long,String> userMap = SimpleQuery.map(Wrappers.lambdaQuery(),
//                User::getId,User::getName);
// 查詢表內記錄,封裝返回為Map<屬性,屬性>,考慮了并行流的情況
Map<Long,String> userMap = SimpleQuery.map(lambdaQuery(),User::getId,User::getEmail,true);
userMap.forEach((k,v)->{System.out.println(k+"-->"+v);
});
}/**
* 測試查詢 group  返回為Map<屬性,List<實體>>
*/
@Test
public void group() {
System.out.println(("----- SimpleQuery group method test ------"));
//  查詢表內記錄,封裝返回為Map<屬性,List<實體>>
//        Map<Integer,List<User>> userMap = SimpleQuery.group(Wrappers.lambdaQuery(),
//                User::getAge);
// 查詢表內記錄,封裝返回為Map<屬性,List<實體>>,考慮了并行流的情況
Map<Integer,List<User>> userMap = SimpleQuery.group(lambdaQuery(),User::getAge,true);
userMap.forEach((k,v)->{System.out.println(k+"-->"+v);
});
}/**
* 測試查詢 group  返回為Map<屬性,分組后對集合進行的下游收集器>
*/
@Test
public void groupM() {
System.out.println(("----- SimpleQuery groupM method test ------"));
//  查詢表內記錄,封裝返回為Map<屬性,List<實體>>
//        Map<Integer, Set<User>> group = SimpleQuery.group(Wrappers.lambdaQuery(),
//                User::getAge, Collectors.toSet());//        Map<Integer, Map<Long, String>> group = SimpleQuery.group(Wrappers.lambdaQuery(),
//                User::getAge, Collectors.toMap(User::getId, User::getName, (a, b) -> a));//        // 查詢表內記錄,封裝返回為Map<屬性,List<實體>>,考慮了并行流的情況
//        Map<Integer, Set<User>> group = SimpleQuery.group(Wrappers.lambdaQuery(),
//                User::getAge, Collectors.toSet(),true);
Map<Integer, Map<Long, String>> group = SimpleQuery.group(lambdaQuery(),User::getAge, Collectors.toMap(User::getId, User::getName, (a, b) -> a));
group.forEach((k,v)->{System.out.println(k+"-->"+v);
});
}/**
* 測試查詢 list 返回為List<屬性>
*/
@Test
public void list() {
System.out.println(("----- SimpleQuery list method test ------"));
// 查詢表內記錄,封裝返回為List<屬性>
//        List<String> names = SimpleQuery.list(Wrappers.lambdaQuery(), User::getName);
// 查詢表內記錄,封裝返回為List<屬性>,考慮了并行流的情況
List<String> names = SimpleQuery.list(lambdaQuery(), User::getName,true);
// 打印 names
names.forEach(System.out::println);
}@Test
void testList() {
// 我要這張表里的ids
List<Long> entityIds = SimpleQuery.list(lambdaQuery(), User::getId);
assertThat(entityIds).containsExactly(1L, 2L);// 可疊加后續操作
List<String> names = SimpleQuery.list(lambdaQuery(), User::getName,e -> Optional.ofNullable(e.getName()).map(String::toUpperCase).ifPresent(e::setName));
assertThat(names).containsExactly("RUBEN", null);
}
  • 9、Db類
說明:使用靜態調用的方式,執行CRUD方法,避免Spring環境下Service循環注入、簡潔代碼,提升效率
需要項目中已注入對應實體的BaseMapper
對于參數為Wrapper的,需要在Wrapper中傳入Entity或者EntityClass供尋找對應的Mapper
不建議在循環中調用,如果是批量保存,建議將數據構造好后使用 Db.saveBatch(數據) 保存

代碼示例

 @Testvoid dbTest() {// 根據id查詢List<User> list = Db.listByIds(Arrays.asList(1L, 2L), User.class);list.stream().forEach(System.out::println);// 根據條件構造器查詢List<User> list1 = Db.list(Wrappers.lambdaQuery(User.class));list1.stream().forEach(System.out::println);// 批量根據id更新
//        boolean isSuccess = Db.updateBatchById(list);}

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

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

相關文章

docker八大架構之應用服務集群架構

應用服務集群架構 在之前&#xff0c;一個應用層要負責所有的用戶操作&#xff0c;但是有時用戶增加后就會導致供不應求的現象&#xff08;單個應用不足以支持海量的并發請求&#xff0c;高并發的時候站點響應變慢&#xff09;&#xff0c;這時就需要增加應用層服務器&#xf…

【STM32 |GPIO】GPIO結構、GPIO輸出

目錄 GPIO簡介 GPIO的基本結構 GPIO位結構&#xff08;每一位的具體電路結構&#xff09; 輸入 上拉和下拉電阻 斯密特觸發器 ?編輯 輸出 GPIO模式 ?編輯 浮空輸入、上拉輸入、下拉輸入 模擬輸入 開漏輸出和推挽輸出 復用開漏輸出和復用推挽輸出 LED和蜂鳴器…

簡述線程同步和線程通信及如何實現線程間的同步

一、線程同步和線程通信是多線程編程中的兩個重要概念。 線程同步&#xff1a; 線程同步是指當有一個線程在對內存進行操作時&#xff08;如讀取、寫入等&#xff09;&#xff0c;其他線程都不可以對該內存地址進行操作&#xff0c;直到該線程完成操作&#xff0c;其他線程才…

FFmpeg開發筆記(二十七)APP無法訪問ZLMediaKit的HLS直播地址

上一篇文章介紹了如何通過ZLMediaKit實現視頻推拉流&#xff0c;并使用VLC播放器驗證視頻直播地址。即使不用VLC播放器&#xff0c;直接在Qt工程的C代碼中調用FFmpeg的API&#xff0c;也能訪問ZLMediaKit的直播地址&#xff0c;并正常渲染視頻畫面。關于如何在Qt工程中引入FFmp…

【資源分享】完勝谷歌翻譯的Deepl翻譯

::: block-1 “時問桫欏”是一個致力于為本科生到研究生教育階段提供幫助的不太正式的公眾號。我們旨在在大家感到困惑、痛苦或面臨困難時伸出援手。通過總結廣大研究生的經驗&#xff0c;幫助大家盡早適應研究生生活&#xff0c;盡快了解科研的本質。祝一切順利&#xff01;—…

【數據結構與算法】力扣 111. 二叉樹的最小深度

題目描述 給定一個二叉樹&#xff0c;找出其最小深度。 最小深度是從根節點到最近葉子節點的最短路徑上的節點數量。 說明&#xff1a; 葉子節點是指沒有子節點的節點。 示例 1&#xff1a; 輸入&#xff1a; root [3,9,20,null,null,15,7] 輸出&#xff1a; 2示例 2&#…

長事務的理解和預防

我們常常聽說數據庫發生了“長事務”而導致很嚴重的后果。那么何為長事務&#xff1f;長事務是如何產生的&#xff1f;長事務對數據庫有什么影響&#xff1f;如何防止長事務的產生&#xff1f;以下對這幾方面進行闡述和說明&#xff0c;以加深對SinoDB長事務的理解。 1&#x…

Python-VBA函數之旅-super函數

目錄 一、super函數的常見應用場景 二、super函數使用注意事項 三、如何用好super函數&#xff1f; 1、super函數&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推薦閱讀&#xff1a; 個人主頁&#xff1a; https://myelsa1024.blog.csdn.net/ 一、su…

AI代理和AgentOps生態系統的剖析

1、AI代理的構成&#xff1a;AI代理能夠根據用戶的一般性指令自行做出決策和采取行動。 主要包含四個部分&#xff1a; &#xff08;1&#xff09;大模型&#xff08;LLM&#xff09; &#xff08;2&#xff09;工具&#xff1a;如網絡搜索、代碼執行等 &#xff08;3&#x…

探索未來:IT行業的革新脈動與明日圖景

你眼中的IT行業現狀與未來趨勢 隨著技術的不斷進步&#xff0c;IT行業已成為推動全球經濟和社會發展的關鍵力量。從云計算、大數據、人工智能到物聯網、5G通信和區塊鏈&#xff0c;這些技術正在重塑我們的生活和工作方式。你眼中IT行業的現狀及未來發展趨勢是怎么樣的&#xf…

開散列哈希桶

通過上面這幅圖&#xff0c;讀者應該能較為直觀地理解何為開散列&#xff0c;以及閉散列與開散列的區別在哪里 —— 數據的存儲形式不同&#xff0c;至于其他的&#xff0c;如確定每個元素的哈希地址等一概相同。 與閉散列相比&#xff0c;開散列能夠更好地處理發生沖突的元素 …

Taro + React + Tailwind 開發微信小程序問題匯總(持續更新中...)

搞小程序也有兩周了&#xff0c;踩了很多坑&#xff0c;有些問題很難搜索到&#xff0c;在這里記錄一下問題和自己的解決方案&#xff0c;希望能幫助到需要的小伙伴&#xff5e; 1. 真機調試報錯&#xff1a;Error: module ‘babel/runtime/helpers/Arrayincludes.js’ is not …

Transformers 加速的一些常用技巧

Transformers 是一個強大的架構&#xff0c;但模型因其采用的自注意力機制&#xff0c;雖然能夠有效地處理序列數據并捕獲長距離依賴關系&#xff0c;但同時也容易導致在訓練過程中出現OOM&#xff08;Out of Memory&#xff0c;內存不足&#xff09;或者達到GPU的運行時限制。…

AI大模型探索之路-訓練篇22: ChatGLM3微調實戰-從原理到應用的LoRA技術全解

系列篇章&#x1f4a5; AI大模型探索之路-訓練篇1&#xff1a;大語言模型微調基礎認知 AI大模型探索之路-訓練篇2&#xff1a;大語言模型預訓練基礎認知 AI大模型探索之路-訓練篇3&#xff1a;大語言模型全景解讀 AI大模型探索之路-訓練篇4&#xff1a;大語言模型訓練數據集概…

MPLAB X IDE編譯attiny1616工程報錯卻無報錯信息

MPLAB X IDE(XC-8編譯器)編譯報錯&#xff0c;無具體錯誤內容&#xff0c;僅顯示需要xc-8 pro的警告。 內存占用率顯示為81%&#xff0c;未超標。 原因&#xff1a;軟件使用了microchip的bootloader功能。應用程序起始地址&#xff08;也是bootloader結束地址&#xff09;設置錯…

社交巨頭:探索Facebook的震撼力量

Facebook作為社交媒體領域的巨頭&#xff0c;不僅在數字化社會中占據著重要地位&#xff0c;更是影響了人們的生活、工作和社交方式。本文將深入探索Facebook的震撼力量&#xff0c;從多個角度解讀其在當今社會中的重要性和影響。 1. 全球用戶覆蓋的壯觀規模 Facebook作為全球…

軟件定義汽車七大典型應用場景

隨著軟件定義汽車典型應用場景的落地&#xff0c;用戶將明顯體驗到汽車從交通工具向智能移動終端的轉變。幾十年前主要用高性能的底盤操穩與動力系統定義一臺好車&#xff0c;幾年前主要用智能化系統與智能交互滿足終端用戶的用車體驗&#xff0c;未來將調度全車傳感器與數據驅…

c 數組遍歷

#include <stdio.h> #include <stdlib.h> int main() { printf(“指針數組練習&#xff01;&#xff01;&#xff01;\n”); /* 數組名就是數組的首地址 數組存在一段連續的內存空間中 */ double score[] {60, 70, 80, 90, 100}; double *ptr_score; i…

docker安裝時報錯:Error: Nothing to do

安裝docker時報以下錯誤 解決方法&#xff1a; 1.下載關于docker的相關依賴環境 yum -y install yum-utils device-mapper-persistent-data lvm22.設置下載Docker的鏡像源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo3…