重生之我在暑假學習微服務第一天《MybatisPlus-上篇》

?

本系列參考黑馬程序員微服務課程,有興趣的可以去查看相關視頻,本系列內容采用漸進式方式講解微服務核心概念與實踐方法,每日更新確保知識點的連貫性。通過系統化學習路徑幫助開發者掌握分布式系統構建的關鍵技術。讀者可通過平臺訂閱功能獲取最新章節推送,及時了解服務拆分、容器化部署、服務網格等前沿技術動態。

  • ?個人主頁:VON
  • 文章所屬專欄:微服務
  • 系列文章鏈接:暫無
  • 時間:每天12點準時更新

目錄

前言

一、MyBatis-Plus 與 MyBatis 的區別

功能增強

開發效率

擴展性

適用場景

示例對比

二、引入Mybits-Plus

1.下載依賴

?2.繼承BaseMapper?編輯

?3、修改代碼

4.測試?

插入

查詢 (單條數據)

?查詢 (多條數據)

更新數據?

?編輯?刪除數據

三、常見注解

@TableName

?示例:

@TableId

示例:

@TableField

常見的配置

?四、條件構造器

1、基于QueryWrapper查詢

?2、基于UpdateWrapper更新

?五、自定義SQL

六、Service接口

1、基礎用法

2、實現簡單業務接口

3、實現復雜業務接口

4.開始測試

(1)增加用戶信息

(2)查詢用戶信息

(3)批量查詢用戶信息

(4)扣減用戶余額

(5)刪除用戶信息

?(6)根據Lambda查詢用戶信息

?編輯

?(7)IService批量新增

結語


前言

蟬鳴撕心裂肺時,VON從冷汗里彈起來。?

泛黃的墻壁,潦草的名字,2030?年 7 月 15 日的日歷 —— 這不是他被總監罵 "連 MybatisPlus 都不會" 的會議室。?

他重生回了高考后的暑假。?

前世因荒廢假期,他在大學跟不上課程,工作后寫幾百行冗余 SQL 被嘲笑,看同事玩轉微服務自己卻連基礎都摸不透。那些羞辱像針一樣扎著。?

班長的消息彈出來:"學長推薦了入門微服務的資料,從 MybatisPlus 開始。"?

VON盯著那行字,心臟狂跳。前世他就是嫌難,把整個夏天耗在了游戲里。?

"這次不能再錯過。"?

他抓起手機,點開前世屏蔽的技術公眾號,目光落在《MybatisPlus 基礎入門》上。窗外的蟬鳴突然溫順了,陽光在嶄新的教程封面上,映出他眼里的光。?

重生第一天,就從搞懂 MybatisPlus 開始。

一、MyBatis-Plus 與 MyBatis 的區別

Mybits-Plus官網

Mybits官網

MyBatis-Plus(簡稱 MP)是基于 MyBatis 的增強工具,旨在簡化開發并提高效率,核心區別如下:


功能增強

MyBatis-Plus 在 MyBatis 基礎上提供了大量開箱即用的功能:

  • 自動化 CRUD:內置通用 Mapper 和 Service,無需手動編寫基礎 SQL。
  • 條件構造器:通過 QueryWrapperUpdateWrapper 等實現動態 SQL 拼接。
  • 代碼生成器:自動生成實體類、Mapper、Service 等代碼。
  • 分頁插件:內置分頁支持,無需額外配置。

開發效率

MyBatis 需要手動編寫 SQL 和結果映射,而 MyBatis-Plus 通過約定優于配置減少冗余代碼:

  • 默認映射實體類與數據庫表字段(支持駝峰轉換)。
  • 提供 Lambda 表達式寫法,避免硬編碼字段名。

擴展性

  • MyBatis-Plus 完全兼容原生 MyBatis,可混合使用。
  • 支持自定義全局操作(如邏輯刪除、自動填充字段)。

適用場景

  • MyBatis:需高度定制復雜 SQL 或已有成熟 MyBatis 項目。
  • MyBatis-Plus:快速開發常規業務(如后臺管理系統),減少樣板代碼。

示例對比

MyBatis 示例

MyBatis-Plus 等價操作

二、引入Mybits-Plus

1.下載依賴

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency>

?2.繼承BaseMapper

?3、修改代碼

原來代碼👇

?將原來代碼中的語句直接刪除

Mapper也同理

?修改測試類中的方法即可,根據提示直接回車即可

4.測試?

插入

?插入成功

查詢 (單條數據)

?查詢 (多條數據)

更新數據?

?刪除數據

?由此可見增刪改查功能全部正常,目前的代碼極大的簡化了原本的代碼

三、常見注解

@TableName

用于指定實體類對應的數據庫表名。當實體類名與數據庫表名不一致時,使用該注解進行映射。

@TableName("user_info")
public class User {// 類字段
}

?示例:

@TableId

用于標識主鍵字段,并可以指定主鍵生成策略。常見的屬性包括value(數據庫主鍵字段名)和type(主鍵生成策略)。

@TableId(value = "id", type = IdType.AUTO)
private Long id;

主鍵生成策略(IdType)常見選項:

  • AUTO:數據庫自增
  • INPUT:手動輸入
  • ASSIGN_ID:雪花算法生成ID
  • ASSIGN_UUID:生成UUID

示例:

這里測試一下自增

@TableField

用于標注非主鍵字段,解決字段名與數據庫列名不一致的問題,或標識非表字段(如 transient 字段)。

@TableField("user_name")
private String name;@TableField(exist = false)
private String tempData;

常見屬性:

  • value:數據庫字段名(默認與屬性名一致時可不填)
  • exist:是否為數據庫字段(默認為true
  • fill:字段自動填充策略(如FieldFill.INSERT插入時填充)

注:當exist設置為false時該字段不顯示

注:在數據庫設計或查詢中,偶爾會遇到表名與數據庫保留關鍵字相同的情況。這可能導致語法錯誤或執行失敗。以下是幾種常見的解決方法:

使用引號或方括號包裹表名?不同數據庫系統對保留關鍵字的處理方式不同。MySQL使用反引號(`),SQL Server使用方括號([]),PostgreSQL和Oracle使用雙引號("")。例如:

-- MySQL
SELECT * FROM `order`;-- SQL Server
SELECT * FROM [order];-- PostgreSQL/Oracle
SELECT * FROM "order";

修改表名?避免使用數據庫保留關鍵字作為表名是最佳實踐。可以通過添加前綴或后綴來修改表名,例如tbl_orderorders

使用別名?在查詢中為表指定別名可以避免直接使用關鍵字。例如:

SELECT o.* FROM `order` AS o WHERE o.id = 1;

數據庫保留關鍵字列表?不同數據庫系統的保留關鍵字各不相同。

常見的配置

mybitis-plus:# 配置Mapper XML文件的位置mapper-locations: classpath*:mapper/*.xmlconfiguration:# 開啟下劃線轉駝峰命名映射map-underscore-to-camel-case: true# 指定MyBatis日志實現方式,輸出到控制臺log-impl: org.apache.ibatis.logging.stdout.StdOutImpl# 關閉二級緩存cache-enabled: falseglobal-config:db-config:# 主鍵生成策略:自動遞增id-type: auto# 邏輯刪除字段名logic-delete-field: is_deleted# 邏輯刪除值(標記為已刪除)logic-delete-value: 1# 邏輯未刪除值(標記為未刪除)logic-not-delete-value: 0# 邏輯刪除列名logic-delete-column: is_deleted# 邏輯刪除類型為列模式logic-delete-type: COLUMN# 數據庫類型db-type: mysql# 表前綴table-prefix: tbl_# 字段策略:智能判斷非空字段field-strategy: smart# 更新策略:智能判斷非空字段update-strategy: smart# 插入策略:智能判斷非空字段insert-strategy: smart

一般配置成這樣就可以了?

想要了解更多的可以看官方文檔👇

文章開頭部分已經引入了文檔官網

?四、條件構造器

1、基于QueryWrapper查詢

//條件構造器測試案例@Testvoid textOne1(){//查詢名字帶o,并且存款大于1000的用戶List<User> users = userMapper.selectList(new QueryWrapper<User>().like("username", "o").gt("balance", 1000));users.forEach(System.out::println);}@Testvoid textOne2(){//將張三存款改為10000User user = new User();user.setBalance(10000);QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "張a三");userMapper.update(user, wrapper);}

?可見查詢到了一條符合的語句

?可見余額已經修改為10000了

?2、基于UpdateWrapper更新

@Testvoid textTwo1(){//基于UpdateWrapper更新id為1,2,3的用戶余額減500UpdateWrapper<User> wrapper = new UpdateWrapper<User>().in("id", 1, 2, 3).setSql("balance = balance - 500");userMapper.update(null, wrapper);}

更新前的數據如下

?更新后的數據

?五、自定義SQL

這種寫法是?“用分層設計讓代碼更干凈,用動態條件適配變化,用 XML 管好 SQL ,用測試保障質量”?,本質是為了讓數據庫操作的?“開發更靈活、維護更簡單、協作更順暢、質量更可控”

測試用例驅動(功能觸發層)
編寫?textCustomSqlQuery?測試方法,先定義更新參數(用戶 ID 列表?ids、扣除金額?amount?),再用?QueryWrapper?構建?id IN (1,2,3)?的條件,最后調用?userMapper.updateBalanceByIds?,作為功能入口觸發數據庫操作。

Mapper 接口約定(方法聲明層)
在?UserMapper?接口中定義?updateBalanceByIds?方法,通過?@Param?明確入參(條件?wrapper、金額?amount?),約定參數傳遞規則,作為 XML 映射 SQL 的 “調用聲明”。

XML 映射執行(SQL 實現層)
XML 中通過?<update id="updateBalanceByIds">?綁定接口方法,編寫 SQL :UPDATE tb_user SET balance = balance - #{amount} ${ew.customSqlSegment}?,既用?#{amount}?安全傳參,又通過?${ew.customSqlSegment}?拼接條件,最終在數據庫執行 “按 ID 批量扣余額” 的更新。

測試用例負責場景觸發,Mapper 接口定義調用契約,XML 映射實現具體 SQL ,協同完成數據庫更新邏輯。

六、Service接口

1、基礎用法

只需繼承一下接口即可

這里做一個簡單的測試

?直接就可以對數據庫中的數據進行修改

2、實現簡單業務接口

?添加配置文件

<!--swagger--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId><version>4.1.0</version></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

修改yaml文件,加入以下代碼

knife4j:enable: trueopenapi:group:default:group-name: defaultapi-rule: packageapi-rule-resources:- com.itheima.mp.controller

添加UserVO和UserFormDTO兩個實體類

開始寫Controller代碼

package com.itheima.mp.controller;import cn.hutool.core.bean.BeanUtil;
import com.itheima.mp.domain.dto.UserFormDTO;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.vo.UserVO;
import com.itheima.mp.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;import java.util.List;@Api(tags = "用戶管理相關接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor
public class UserController {private final IUserService userService;@ApiOperation("新增用戶")@PostMappingpublic void saveUser(@RequestBody UserFormDTO userDTO){//1.把DTO轉換成POUser user = BeanUtil.copyProperties(userDTO,User.class);//2.調用service完成新增userService.save(user);}@ApiOperation("刪除用戶")@DeleteMapping("/{id}")public void deleteUserById(@ApiParam("用戶id") @PathVariable("id") Long id){userService.removeById(id);}@ApiOperation("查詢用戶")@GetMapping("/{id}")public UserVO queryUserById(@ApiParam("用戶id") @PathVariable("id") Long id){//1.查詢用戶POUser user = userService.getById(id);//2.把PO轉換成VOreturn BeanUtil.copyProperties(user,UserVO.class);}@ApiOperation("批量查詢用戶")@GetMapping("/{id}")public List<UserVO> queryUserByIds(@ApiParam("用戶id集合") @RequestParam("ids") List<Long> ids){//1.查詢用戶POList<User> users = userService.listByIds(ids);//2.把PO轉換成VOreturn BeanUtil.copyToList(users,UserVO.class);}
}

3、實現復雜業務接口

這里的請求方式是PUT請求,這里寫錯了,留意一下

最后一行的id應該是id的,這里寫成ew了🤡🤡🤡

4.開始測試

這里用的是Apifox

(1)增加用戶信息

發送post請求

?成功插入數據

(2)查詢用戶信息

注意下這里是GET請求

(3)批量查詢用戶信息

(4)扣減用戶余額

這里是PUT請求

這里扣減id為5的用戶

?余額變成9000了

(5)刪除用戶信息

刪除id為7的用戶

可以看到id為7的用戶被刪除了?

以上的測試后端也都響應回來了?

?(6)根據Lambda查詢用戶信息

先創建一個實體類,參數多的情況下不建議一個一個輸入

controller和service層代碼

?注意下這里的請求路徑為了和上文區分改成了list

看下實體類中的參數,都可以進行查詢

這里的狀態碼全為1,所以沒有查詢到狀態碼為2的。?

細心的話不難發現2號余額為負數

?先將他的余額設置成100,然后在減余額

這里的邏輯改了一下,用戶余額為0時會改變狀態,也就是凍結用戶

?調整好代碼后接著測試扣減余額

注意下這里的請求方式和參數

可以看到狀態和余額都改變了

?(7)IService批量新增

注:這里需要打開mysql的一個參數

將這個字段設置為true即可。

結語

這篇關于 MyBatis - Plus 學習的文章,其誕生如同一場與代碼世界的深度邂逅。從暮色浸染的傍晚 6 點,到星光綴滿夜空的凌晨 0:37,除去 30 分鐘短暫的用餐時光,近 6 小時的全神貫注,最終打磨出這篇約 7000 字的學習記錄。?

每一個字符都凝結著對 MyBatis - Plus 知識點的反復推敲,每一步操作過程的呈現都力求精準還原技術實踐,每一處運行結果的記錄都飽含對細節的極致追求 —— 這份從指尖流淌而出的文字,不僅是時間的沉淀,更是對 MyBatis - Plus 實操細節的細致捕捉。?

唯愿這份帶著鉆研熱忱與滿滿誠意的記錄,能為正在學習 MyBatis - Plus 的你掃清障礙,提供切實的參考與助益,讓你的學習之路更順暢。

最后附上文章全套代碼

代碼參考黑馬程序員資料

UserController

package com.itheima.mp.controller;import cn.hutool.core.bean.BeanUtil;
import com.itheima.mp.domain.dto.UserFormDTO;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.query.UserQuery;
import com.itheima.mp.domain.vo.UserVO;
import com.itheima.mp.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;import java.util.List;@Api(tags = "用戶管理相關接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor
public class UserController {private final IUserService userService;@ApiOperation("新增用戶")@PostMappingpublic void saveUser(@RequestBody UserFormDTO userDTO){//1.把DTO轉換成POUser user = BeanUtil.copyProperties(userDTO,User.class);//2.調用service完成新增userService.save(user);}@ApiOperation("刪除用戶")@DeleteMapping("/{id}")public void deleteUserById(@ApiParam("用戶id") @PathVariable("id") Long id){userService.removeById(id);}@ApiOperation("查詢用戶")@GetMapping("/{id}")public UserVO queryUserById(@ApiParam("用戶id") @PathVariable("id") Long id){//1.查詢用戶POUser user = userService.getById(id);//2.把PO轉換成VOreturn BeanUtil.copyProperties(user,UserVO.class);}@ApiOperation("批量查詢用戶")@GetMappingpublic List<UserVO> queryUserByIds(@ApiParam("用戶id集合") @RequestParam("ids") List<Long> ids){//1.查詢用戶POList<User> users = userService.listByIds(ids);//2.把PO轉換成VOreturn BeanUtil.copyToList(users,UserVO.class);}@ApiOperation("扣減余額")@PutMapping("/{id}/deduction/{money}")public void deductBalance(@ApiParam("用戶id") @PathVariable("id") Long id,@ApiParam("金額") @PathVariable("money") Integer money){userService.deductBalance(id,money);}@ApiOperation("根據復雜條件查詢用戶")@GetMapping("/list")public List<UserVO> queryUserByIds(UserQuery query){//1.查詢用戶POList<User> users = userService.queryUsers(query.getName(),query.getStatus(),query.getMinBalance(),query.getMaxBalance());//2.把PO轉換成VOreturn BeanUtil.copyToList(users,UserVO.class);}
}

User

package com.itheima.mp.domain.po;import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.time.LocalDateTime;
@TableName("tb_user")
@Data
public class User {/*** 用戶id*/private Long id;/*** 用戶名*/private String username;/*** 密碼*/private String password;/*** 注冊手機號*/private String phone;/*** 詳細信息*/private String info;/*** 使用狀態(1正常 2凍結)*/private Integer status;/*** 賬戶余額*/private Integer balance;/*** 創建時間*/private LocalDateTime createTime;/*** 更新時間*/private LocalDateTime updateTime;
}

UserQuery

package com.itheima.mp.domain.query;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(description = "用戶查詢條件實體")
public class UserQuery {@ApiModelProperty("用戶名關鍵字")private String name;@ApiModelProperty("用戶狀態:1-正常,2-凍結")private Integer status;@ApiModelProperty("余額最小值")private Integer minBalance;@ApiModelProperty("余額最大值")private Integer maxBalance;
}

UserVO

package com.itheima.mp.domain.vo;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(description = "用戶VO實體")
public class UserVO {@ApiModelProperty("用戶id")private Long id;@ApiModelProperty("用戶名")private String username;@ApiModelProperty("詳細信息")private String info;@ApiModelProperty("使用狀態(1正常 2凍結)")private Integer status;@ApiModelProperty("賬戶余額")private Integer balance;
}

UserMapper

package com.itheima.mp.mapper;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import org.springframework.core.Constants;import java.util.List;public interface UserMapper extends BaseMapper<User> {
//    List<User> queryUserByIds(@Param("ids") List<Long> ids);void updateBalanceByIds(@Param("ew") QueryWrapper<User> wrapper, @Param("amount") int amount);@Update("update tb_user set balance = balance - #{money} where id = #{id}")void deductBalance(@Param("id") Long id, @Param("money") Integer money);
}

UserServiceImpl

package com.itheima.mp.service.impl;import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.mapper.UserMapper;
import com.itheima.mp.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Override@Transactionalpublic void deductBalance(Long id, Integer money) {//1.查詢用戶User user = getById(id);//2.更新用戶余額if(user == null || user.getStatus() == 2){throw new RuntimeException("用戶不存在");}if(user.getBalance() < money){throw new RuntimeException("余額不足");}//余額為0時凍結用戶int remainBalance = user.getBalance() - money;lambdaUpdate().set(User::getBalance, remainBalance).set(remainBalance == 0, User::getStatus, 2).eq(User::getBalance,user.getBalance()).eq(User::getId, id).update();}@Overridepublic List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {return lambdaQuery().like(name!=null, User::getUsername, name).eq(status!=null, User::getStatus, status).ge(minBalance!=null, User::getBalance, minBalance).le(maxBalance!=null, User::getBalance, maxBalance).list();}
}

IUserService

package com.itheima.mp.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.mp.domain.po.User;import java.util.List;public interface IUserService extends IService<User> {void deductBalance(Long id, Integer money);List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance);
}

yaml

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=truetype: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456
logging:level:com.itheima: debugpattern:dateformat: HH:mm:ss
#mybatis:
#  mapper-locations: classpath*:mapper/*.xml
mybitis-plus:mapper-locations: classpath*:mapper/*.xmlconfiguration:map-underscore-to-camel-case: truecache-enabled: falseglobal-config:db-config:id-type: autoupdate-strategy: not_null
knife4j:enable: trueopenapi:group:default:group-name: defaultapi-rule: packageapi-rule-resources:- com.itheima.mp.controller

UserMapperTest

package com.itheima.mp.mapper;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDateTime;
import java.util.List;@SpringBootTest
class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testvoid testInsert() {User user = new User();//user.setId(5L);user.setUsername("張a三");user.setPassword("123");user.setPhone("18688990012");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老師\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userMapper.insert(user);}@Testvoid testSelectById() {User user = userMapper.selectById(5L);System.out.println("user = " + user);}@Testvoid testQueryByIds() {List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L));users.forEach(System.out::println);}@Testvoid testUpdateById() {User user = new User();user.setId(5L);user.setBalance(20000);userMapper.updateById(user);}@Testvoid testDeleteUser() {userMapper.deleteById(5L);}//條件構造器測試案例@Testvoid textOne1() {//查詢名字帶o,并且存款大于1000的用戶List<User> users = userMapper.selectList(new QueryWrapper<User>().like("username", "o").gt("balance", 1000));users.forEach(System.out::println);}@Testvoid textOne2() {//將張三存款改為10000User user = new User();user.setBalance(10000);QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "張a三");userMapper.update(user, wrapper);}@Testvoid textTwo1() {//基于UpdateWrapper更新id為1,2,3的用戶余額減500UpdateWrapper<User> wrapper = new UpdateWrapper<User>().in("id", 1, 2, 3).setSql("balance = balance - 500");userMapper.update(null, wrapper);}@Testvoid textCustomSqlQuery() {//1.更新條件List<Long> ids = List.of(1L, 2L, 3L);int amount = 100;//2.定義條件QueryWrapper<User> wrapper = new  QueryWrapper<User>().in("id", ids);//3.調用 方法userMapper.updateBalanceByIds(wrapper, amount);}
}

IUserServiceTest

package com.itheima.mp.service;import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestExecutionListeners;import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class IUserServiceTest {@Autowiredprivate IUserService userService;@Testvoid testSaveUser(){User user = new User();//user.setId(5L);user.setUsername("張三aaa");user.setPassword("123");user.setPhone("18688990012");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老師\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userService.save(user);}@Testvoid testQuery(){List<User> list = userService.listByIds(List.of(1L, 2L, 3L));list.forEach(System.out::println);}@Testvoid testSaveBatch(){List<User> list = new ArrayList<>(10000);long b = System.currentTimeMillis();for (int i = 1; i <= 100000; i++) {User user = new User();user.setUsername("user" + i);user.setPassword("<PASSWORD>");user.setPhone("12345678901");user.setStatus(1);user.setBalance(100);user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());list.add(user);if(i%10000==0){userService.saveBatch(list);list.clear();}}long e = System.currentTimeMillis();System.out.println("耗時:"+(e-b));}
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.itheima.mp</groupId><artifactId>mp-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>mp-demo</name><description>Demo project for Spring Boot</description><properties><java.version>11</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
<!--        <dependency>-->
<!--            <groupId>org.mybatis.spring.boot</groupId>-->
<!--            <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!--            <version>2.3.1</version>-->
<!--        </dependency>-->
<!--        mybits plus依賴--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><!--swagger--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId><version>4.1.0</version></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.11</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

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

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

相關文章

odoo-060 git版本:發布/生產版本落后開發版本部署

文章目錄問題起源目前解決問題起源 周五提交了一個版本&#xff0c;本來打算使用這個版本的&#xff0c;周末更新。 下一個功能比較復雜&#xff0c;周一提交&#xff0c;結果周末沒有更新&#xff0c;導致現在還有沒測試過的不能發布的。 說明&#xff1a; 原來只有一個mast…

YotoR模型:Transformer與YOLO新結合,打造“又快又準”的目標檢測模型

【導讀】在目標檢測領域&#xff0c;YOLO系列以其高效的推理速度廣受歡迎&#xff0c;而Transformer結構則在精度上展現出強大潛力。如何兼顧二者優勢&#xff0c;打造一個“又快又準”的模型&#xff0c;是近年來研究熱點之一。本文介紹的一項新研究——YotoR&#xff08;You …

白楊SEO:流量的本質是打開率?搞用戶搜索流量的玩法怎么做?

大家好&#xff0c;我是白楊SEO&#xff0c;專注研究SEO十年以上&#xff0c;全網SEO流量實戰派&#xff0c;AI搜索優化研究者。上周六參加了生財航海家在杭州舉行的私域運營大會&#xff0c;主題是圍繞私域獲客&#xff0c;私域IP&#xff0c;AI私域&#xff0c;精細化管理。白…

Java優雅使用Spring Boot+MQTT推送與訂閱

在物聯網&#xff08;IoT&#xff09;和智能設備橫行的今天&#xff0c;你有沒有遇到這樣的問題&#xff1a;服務端需要實時把報警、狀態更新、控制指令推送給客戶端&#xff1b;安卓 App、嵌入式設備、網頁等終端&#xff0c;需要輕量且穩定的連接方式&#xff1b;HTTP 太“重…

多目標粒子群優化(MOPSO)解決ZDT1問題

前言 提醒&#xff1a; 文章內容為方便作者自己后日復習與查閱而進行的書寫與發布&#xff0c;其中引用內容都會使用鏈接表明出處&#xff08;如有侵權問題&#xff0c;請及時聯系&#xff09;。 其中內容多為一次書寫&#xff0c;缺少檢查與訂正&#xff0c;如有問題或其他拓展…

Coze Studio概覽(三)--智能體管理

本文簡要分析了Coze Studio中智能體管理功能&#xff0c;包括功能、架構以及核心流程。Coze Studio 智能體管理功能分析 1. 智能體管理架構概覽 Coze Studio的智能體管理系統基于DDD架構&#xff0c;主要包含以下核心模塊&#xff1a; 后端架構層次&#xff1a; API層 (coze): …

idea運行tomcat日志亂碼問題

原因在于idea和tomcat文件編碼格式不一樣。可以把idea編碼改成UTF-8 File | Settings | Editor | File Encodings 里面把GBK都改成UTF-8help里面 Edit Custom VM Options 添加一行-Dfile.encodingUTF-8重啟idea

Javaweb - 13 - AJAX

發送請求的幾種方式1. 瀏覽器的地址框中輸入地址&#xff0c;回車2. html --> head --> scrip / linkimg 自動發送請求&#xff0c;無需手動觸發3. a 標簽&#xff0c;form 表單標簽需要手動控制提交產生&#xff0c;且往往需要在新的頁面上獲得響應信息4. 運行 JS 代碼…

qt常用控件-06

文章目錄qt常用控件-06spinBox/doubleSpinBoxdateTimeEditdialSliderlistWIdgettableWidgettreeWidget結語很高興和大家見面&#xff0c;給生活加點impetus&#xff01;&#xff01;開啟今天的編程之路&#xff01;&#xff01; 今天我們進一步c11中常見的新增表達 作者&#…

小智源碼分析——音頻部分(二)

一、利用創建好的對象來調用音頻服務 上周從上圖的getaudiocode()方法進去感受了一下底層小智的構造如何實現。所以用一個codec來接收我們所構造的音頻對象。下來是用構造好的音頻對象來調用音頻初始化服務Initialize&#xff0c;因為啟動函數Application函數的類中有audio_ser…

菜鳥的C#學習(四)

文章目錄一、格式說明符1.1、數字格式說明符&#xff08;適用于數值類型&#xff1a;int, double, decimal 等&#xff09;1. 標準數字格式2. 自定義數字格式1.2、日期時間格式說明符&#xff08;適用于 DateTime, DateTimeOffset&#xff09;1. 標準日期時間格式2. 自定義日期…

基于黑馬教程——微服務架構解析(二)

本篇文章基于黑馬程序員的微服務課程內容&#xff0c;結合個人學習過程中的理解與思考進行整理。本節將圍繞以下幾個問題展開&#xff1a;什么是網關和配置管理前面那篇文章&#xff0c;我們了解如何把一個單體的項目拆成分布式微服務項目&#xff0c;并且講解一下各個服務之間…

Text2SQL智能問答系統開發(一)

開發一個面向企業的chatBI工作流 已完成 基礎 Text2SQL 功能實現 實現用戶輸入自然語言問題后&#xff0c;系統能夠自動生成 SQL 并執行返回結果。用戶交互優化 支持用戶通過補充信息對查詢進行調整&#xff0c;提升易用性。模糊時間處理機制 對“最近”“近期”等模糊時間關…

Python HTML模塊詳解:從基礎到實戰

一、模塊體系全景圖 Python生態中處理HTML的工具可分為三大層級&#xff1a; 標準庫基礎層&#xff1a;html模塊 html.parser第三方增強層&#xff1a;BeautifulSoup&#xff08;搭配解析器&#xff09;專業級工具層&#xff1a;lxml requests-html 二、標準庫核心模塊詳解…

PyTorch常用Tensor形狀變換函數詳解

PyTorch常用Tensor形狀變換函數詳解 在PyTorch中&#xff0c;對張量&#xff08;Tensor&#xff09;進行形狀變換是深度學習模型構建中不可或缺的一環。無論是為了匹配網絡層的輸入要求&#xff0c;還是為了進行數據預處理和維度調整&#xff0c;都需要靈活運用各種形狀變換函數…

自主智能Agent如何重塑工作流自動化:技術、經濟與未來展望

自主智能Agent的崛起與工作流自動化的范式革命2025年7月&#xff0c;當OpenAI向付費用戶推出具備網頁瀏覽和代碼執行能力的ChatGPT Agent時&#xff0c;工作流自動化領域迎來了一場靜默但徹底的革命。這款不再滿足于簡單問答的智能體&#xff0c;在一個安全的虛擬計算機環境中運…

技術架構、行業應用、工具鏈整合、挑戰應對及未來趨勢五大模塊,引用多個權威來源數據與開源項目實現細節。

以下是一份關于AI技術落地的實戰經驗總結報告&#xff0c;結合代碼示例、可視化圖表與行業案例&#xff0c;內容分為技術架構、行業應用、工具鏈整合、挑戰應對及未來趨勢五大模塊&#xff0c;引用多個權威來源數據與開源項目實現細節。AI技術落地實戰指南&#xff1a;從架構設…

第 9 篇:神經網絡初探——當AI擁有了“大腦”,世界從此不同

《人工智能AI之機器學習基石》系列⑨ 專欄核心理念: 用通俗語言講清楚機器學習的核心原理,強調“洞察 + 技術理解 + 應用連接”,構建一個完整的、富有啟發性的知識體系。

音頻焦點 Android Audio Focus 進階

舊焦點處理 示例調用鏈: requestAudioFocus() → propagateFocusLossFromGain_syncAf() → handleFocusLossFromGain()。 系統事件(如來電)→ 強制焦點變化 → handleFocusLossFromGain()。 函數 propagateFocusLossFromGain_syncAf 焦點持有者發生的焦點丟失通知 主要功能…

MFC UI對話框

文章目錄對話框模態對話框創建銷毀關閉CDialog::OnCancel()EndDialog()CDialog::DestroyWindow()非模態對話框創建銷毀關閉delete this對話框 模態對話框 ??阻塞父窗口??&#xff0c;強制用戶先處理對話框。關閉前父窗口無法響應事件。 創建 推薦&#xff1a;非指針方式…