MyBatis-Plus實作資料庫crud操作
1.mp是什么
MyBatis-Plus (opens new window)(簡稱 MP)是一個 MyBatis (opens new window)的增強工具,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生,
2.創建并初始化資料庫
快速開始 | MyBatis-Plus (baomidou.com)
-
創建資料庫,創建資料庫表
-
創建工程 springboot
可以使用 Spring Initializer (opens new window)快速初始化一個 Spring Boot 工程
-
引入依賴
<!-- mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> -
配置資料庫資訊
spring: datasource: username: root password: 123456 url: "jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8" driver-class-name: com.mysql.cj.jdbc.Driver -
撰寫物體類
User
package com.mj.demomptest.entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class User { private Long id; private String name; private Integer age; private String email; } -
mapper介面
UserMapper
package com.mj.demomptest.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.mj.demomptest.entity.User; public interface UserMapper extends BaseMapper<User> { } -
包掃描
package com.mj.demomptest; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.mj.demomptest.mapper") /* mapper 是一個interface介面動態生成實作類物件 動態生成物件默認找不到 @MapperScan 才能找到動態生成的物件 */ public class DemomptestApplication { public static void main(String[] args) { SpringApplication.run(DemomptestApplication.class, args); } } -
測驗
package com.mj.demomptest; import com.mj.demomptest.entity.User; import com.mj.demomptest.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 DemomptestApplicationTests { @Autowired private UserMapper userMapper; @Test public void findAll() { System.out.println(userMapper.selectList(null)); } } -
查看sql輸出日志
#mybatis日志 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl控制臺輸出

3.mp實作添加 修改
添加
@Test
public void testAdd(){
User user = new User();
user.setName("Lucy");
user.setAge(20);
user.setEmail("[email protected]");
//回傳影響行數
int insert = userMapper.insert(user);
System.out.println(insert);
}

修改
//修改
@Test
public void testUpdate(){
User user = new User();
user.setId(1585808430935887874L);
user.setName("Mary");
int count = userMapper.updateById(user);
System.out.println(count);
}
4.組件策略
1、插入操作
//添加
@Test
public void testAdd() {
User user = new User();
user.setName("lucy");
user.setAge(20);
user.setEmail("[email protected]");
int insert = userMapper.insert(user);
System.out.println(insert);
}
注意:資料庫插入id值默認為:全域唯一id
1585808430935887874
2、MP的主鍵策略
2.1 ASSIGN_ID
MyBatis-Plus默認的主鍵策略是:ASSIGN_ID (使用了雪花演算法)
@TableId(type = IdType.ASSIGN_ID)``private String id;
雪花演算法:分布式ID生成器
雪花演算法是由Twitter公布的分布式主鍵生成演算法,它能夠保證不同表的主鍵的不重復性,以及相同表的主鍵的有序性,
核心思想:
長度共64bit(一個long型),
首先是一個符號位,1bit標識,由于long基本型別在Java中是帶符號的,最高位是符號位,正數是0,負數是1,所以id一般是正數,最高位是0,
41bit時間截(毫秒級),存盤的是時間截的差值(當前時間截 - 開始時間截),結果約等于69.73年,
10bit作為機器的ID(5個bit是資料中心,5個bit的機器ID,可以部署在1024個節點),
12bit作為毫秒內的流水號(意味著每個節點在每毫秒可以產生 4096 個 ID),

優點:整體上按照時間自增排序,并且整個分布式系統內不會產生ID碰撞,并且效率較高,
2.2 AUTO 自增策略
需要在創建資料表的時候設定主鍵自增
物體欄位中配置 @TableId(type = IdType.AUTO)
@TableId(type = IdType.AUTO)
private Long id;
要想影響所有物體的配置,可以設定全域主鍵配置
#全域設定主鍵生成策略
mybatis-plus.global-config.db-config.id-type=auto
5.mp自動填充 樂觀鎖
使用相同的方式填充
自動填充
-
準備作業
-
在表中添加兩個欄位
添加datatime型別的新的欄位,create_time,update_time
-
在表對應物體類添加對應的屬性
-
-
物體類修改
自動填充屬性添加注解
@TableField(fill = FieldFill.INSERT) //添加的時候設定值 private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) //添加的時候設定值,修改的時候不設定值 private Date updateTime; -
創建物體類實作介面,實作介面兩個方法
一個方法添加執行,一個方法修改執行
設定添加什么值
注意:不要忘記添加 @Component 注解
package com.mj.demomptest.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.util.Date; @Component public class MyMetaObjectHandler implements MetaObjectHandler { //mp執行添加操作時 @Override public void insertFill(MetaObject metaObject) { //屬性名稱,設定的值(當前時間),metaObject物件 ;當前時間 set createTime中去 this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); } //mp執行修改時 @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updateTime",new Date(),metaObject); } }
樂觀鎖
多執行緒操作中或并發操作中,多人更改同一條資料,最后提交的事務,把之前的事務覆寫,丟失更新問題
- 取出記錄時,獲取當前的版本號 version
- 更新時,帶上當前version
- 執行更新時, set version = newVersion where version = oldVersion 比較當前修改資料版本和資料庫版本是否一樣
- 如果 version 不對 ,就更新失敗
實作
-
修改物體類
在表添加欄位作為版本號,在表對應物體類添加版本號屬性
@Version private Integer version; -
創建組態檔 注冊樂觀鎖插件
創建包config,創建檔案MybatisPlusConfig.java
此時可以洗掉主類中的 @MapperScan 掃描注解
package com.mj.demomptest.config; import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @MapperScan("com.mj.demomptest.mapper") public class MpConfig { //樂觀鎖插件 @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } }
6.查詢
1,查詢
-
通過多個id批量查詢
//多個id批量查詢 @Test public void testSelect1(){ List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3)); System.out.println(users); } -
簡單的條件查詢
@Test public void testSelect2(){ Map<String,Object> columnMap = new HashMap<>(); columnMap.put("name","Jone"); columnMap.put("age",20); List<User> users = userMapper.selectByMap(columnMap); System.out.println(users); }
2,分頁
-
配置分頁查詢插件
//分頁查詢插件 @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } -
撰寫分頁代碼
-
插件Page物件,傳入兩個引數
當前頁
每頁顯示數
-
呼叫mp的方法實作分頁
//分頁查詢 @Test public void testSelectPage(){ Page<User> page = new Page(1,3); //new 的物件,條件 Page<User> userPage = userMapper.selectPage(page, null); //回傳物件得到分頁所有資料 long pages = userPage.getPages();//總頁數 long current = userPage.getCurrent();//當前頁 List<User> records = userPage.getRecords();//查詢資料集合 long total = userPage.getTotal();//總記錄數 boolean hasNext = userPage.hasNext();//現在當前頁是否有下一頁 boolean hasPrevious = userPage.hasPrevious();//現在當前頁是否有上一頁 }
-
7.洗掉與邏輯洗掉
1,洗掉
-
根據Id洗掉
//id洗掉 @Test public void testDeleteId(){ int rows = userMapper.deleteById(1); System.out.println(rows); } -
批量洗掉
@Test public void testDeleteBatchIds() { int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10)); system.out.println(result); } -
簡單條件洗掉
@Test public void testDeleteByMap() { HashMap<String, Object> map = new HashMap<>(); map.put("name", "Helen"); map.put("age", 18); int result = userMapper.deleteByMap(map); system.out.println(result); }
2,邏輯洗掉
-
物理洗掉和邏輯洗掉
物理洗掉:表中資料不存在了
邏輯洗掉:表中資料還存在,但在查詢時,查不出來
? 在表添加欄位,作為邏輯洗掉標志,每次洗掉時,修改標志位
-
邏輯洗掉實作流程
-
資料庫修改
添加delete欄位 作為邏輯洗掉的標志
-
物體類修改
添加deleted 欄位,并加上 @TableLogic 注解
@TableLogic @TableField(fill = FieldFill.INSERT) private Integer deleted; //邏輯洗掉標志MyMetaObjectHandler.java
this.setFieldValByName("deleted",0,metaObject); -
配置(可選)
0 - - -不洗掉
1 - - - 洗掉
-
測驗
注意:被洗掉前,資料的deleted 欄位的值必須是 0,才能被選取出來執行邏輯洗掉的操作
@Test public void testLogicDelete() { int result = userMapper.deleteById(1585882038232223746L); System.out.println(result); }資料庫中的資料并沒有被洗掉,只是修改了 deleted的值 為1

-
測驗邏輯后的洗掉查詢

-
8.條件構造器和常用介面
1,wapper介紹
Wrapper : 條件構造抽象類,最頂端父類
AbstractWrapper : 用于查詢條件封裝,生成 sql 的 where 條件
QueryWrapper : 查詢條件封裝
UpdateWrapper : Update 條件封裝
AbstractLambdaWrapper : 使用Lambda 語法
LambdaQueryWrapper :用于Lambda語法使用的查詢Wrapper
LambdaUpdateWrapper : Lambda 更新封裝Wrapper
2,測驗用例
-
ge 、gt、le、lt、isNull、isNotNull
@Test public void testSel(){ //ge,gt,le,lt QueryWrapper<User> queryWrapper = new QueryWrapper<>(); //表中的欄位名字,值 age 大于等于21的 queryWrapper.ge("age",21);//大于等于 List<User> users = userMapper.selectList(queryWrapper); System.out.println(users); }sdf
-
eq(等于)、ne(不等于)
注意:seletOne()回傳的是一條物體記錄,當出現多條時會報錯
//eq ne @Test public void testSelectOne(){ QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("name","Tom"); List<User> users = userMapper.selectList(queryWrapper); System.out.println(users); } -
between、notBetween
包含大小邊界
//between,notbetween @Test public void testSelectA(){ QueryWrapper<User> queryWrapper = new QueryWrapper<>(); //欄位,開始值,結束值 age [22,28] queryWrapper.between("age",22,28); List<User> users = userMapper.selectList(queryWrapper); System.out.println(users); } -
like、notlike、likeLeft、likeRight(%的右邊)
update user set name like '%張'selectMap()回傳Map集合串列,通常配合select()使用
@Test public void testSelectB(){ QueryWrapper<User> queryWrapper = new QueryWrapper<>(); // queryWrapper.like("name","J"); List<User> users = userMapper.selectList(queryWrapper); System.out.println(users); } -
orderBy、orderByDesc、orderByAsc 排序
@Test public void testSelectC(){ QueryWrapper<User> queryWrapper = new QueryWrapper<>(); // queryWrapper.orderByDesc("id"); List<User> users = userMapper.selectList(queryWrapper); System.out.println(users); }
3,查詢方式
| 查詢方式 | 說明 |
|---|---|
| setSqlSelect | 設定 SELECT 查詢欄位 |
| where | WHERE 陳述句,拼接 + WHERE 條件 |
| and | AND 陳述句,拼接 + AND 欄位=值 |
| andNew | AND 陳述句,拼接 + AND (欄位=值) |
| or | OR 陳述句,拼接 + OR 欄位=值 |
| orNew | OR 陳述句,拼接 + OR (欄位=值) |
| eq | 等于= |
| allEq | 基于 map 內容等于= |
| ne | 不等于<> |
| gt | 大于> |
| ge | 大于等于>= |
| lt | 小于< |
| le | 小于等于<= |
| like | 模糊查詢 LIKE |
| notLike | 模糊查詢 NOT LIKE |
| in | IN 查詢 |
| notIn | NOT IN 查詢 |
| isNull | NULL 值查詢 |
| isNotNull | IS NOT NULL |
| groupBy | 分組 GROUP BY |
| having | HAVING 關鍵詞 |
| orderBy | 排序 ORDER BY |
| orderAsc | ASC 排序 ORDER BY |
| orderDesc | DESC 排序 ORDER BY |
| exists | EXISTS 條件陳述句 |
| notExists | NOT EXISTS 條件陳述句 |
| between | BETWEEN 條件陳述句 |
| notBetween | NOT BETWEEN 條件陳述句 |
| addFilter | 自由拼接 SQL |
| last | 拼接在最后,例如:last(“LIMIT 1”) |
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/522858.html
標籤:Java
下一篇:java基礎-泛型與正則運算式
