MyBatis-Plus之代碼自動(dòng)生成器使用
前言
回想我們之前進(jìn)行開(kāi)發(fā)的過(guò)程,首先我們需要編寫(xiě)與數(shù)據(jù)庫(kù)表對(duì)應(yīng)的實(shí)體類(lèi),接著再進(jìn)行創(chuàng)建各種層次的包(mapper,service,impl),這個(gè)過(guò)程是不是感覺(jué)特別漫長(zhǎng)呢,而現(xiàn)在一款神器登場(chǎng)了,它就是:MpBatis-Plus的代碼自動(dòng)生成器。
一、介紹
代碼自動(dòng)生成器非常好用,我們只需要提供我們數(shù)據(jù)庫(kù)的表名,然后就可以讓生成器自動(dòng)幫我們完成各種代碼的創(chuàng)建,整個(gè)過(guò)程非常清爽,可以說(shuō)是加班人的福利!
現(xiàn)在我們就來(lái)講解怎么搭建這個(gè)代碼自動(dòng)生成器!
二、代碼自動(dòng)生成器搭建
準(zhǔn)備工作
CREATE DATABASE mybatis_plus_db; USE `mybatis_plus_db`; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用戶(hù)主鍵', `name` varchar(20) DEFAULT NULL COMMENT '用戶(hù)名字', `age` int DEFAULT NULL COMMENT '用戶(hù)年齡', `version` int DEFAULT '1' COMMENT '樂(lè)觀(guān)鎖', `deleted` int DEFAULT '0' COMMENT '邏輯刪除', `create_time` datetime DEFAULT NULL COMMENT '創(chuàng)建時(shí)間', `update_time` datetime DEFAULT NULL COMMENT '更新時(shí)間', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1482996505408204804 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
數(shù)據(jù)庫(kù)結(jié)構(gòu)如下:

2.1 創(chuàng)建一個(gè)SpringBoot項(xiàng)目
選擇web依賴(lài)。

2.2 導(dǎo)入依賴(lài)
<!-- 數(shù)據(jù)庫(kù)驅(qū)動(dòng) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<!-- 代碼自動(dòng)生成器依賴(lài)-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>2.3 編寫(xiě)配置文件
application.properties:
# mysql 5 驅(qū)動(dòng)不同 com.mysql.jdbc.Driver # mysql 8 驅(qū)動(dòng)不同com.mysql.cj.jdbc.Driver、需要增加時(shí)區(qū)的配置 serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # 配置日志 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl # 配置邏輯刪除 mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0
2.4 搭建代碼自動(dòng)生成器
package com.yixin;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
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 org.junit.platform.commons.util.StringUtils;
import java.util.ArrayList;
import java.util.Scanner;
public class CodeGenerator {
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("請(qǐng)輸入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotBlank(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("請(qǐng)輸入正確的" + tip + "!");
}
public static void main(String[] args) {
// 代碼生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");//設(shè)置代碼生成路徑
gc.setFileOverride(true);//是否覆蓋以前文件
gc.setOpen(false);//是否打開(kāi)生成目錄
gc.setAuthor("yixin");//設(shè)置項(xiàng)目作者名稱(chēng)
gc.setIdType(IdType.AUTO);//設(shè)置主鍵策略
gc.setBaseResultMap(true);//生成基本ResultMap
gc.setBaseColumnList(true);//生成基本ColumnList
gc.setServiceName("%sService");//去掉服務(wù)默認(rèn)前綴
gc.setDateType(DateType.ONLY_DATE);//設(shè)置時(shí)間類(lèi)型
mpg.setGlobalConfig(gc);
// 數(shù)據(jù)源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mybatis_plus_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.yixin");
pc.setMapper("mapper");
pc.setXml("mapper.xml");
pc.setEntity("pojo");
pc.setService("service");
pc.setServiceImpl("service.impl");
pc.setController("controller");
mpg.setPackageInfo(pc);
// 策略配置
StrategyConfig sc = new StrategyConfig();
sc.setNaming(NamingStrategy.underline_to_camel);
sc.setColumnNaming(NamingStrategy.underline_to_camel);
sc.setEntityLombokModel(true);//自動(dòng)lombok
sc.setRestControllerStyle(true);
sc.setControllerMappingHyphenStyle(true);
sc.setLogicDeleteFieldName("deleted");//設(shè)置邏輯刪除
//設(shè)置自動(dòng)填充配置
TableFill gmt_create = new TableFill("create_time", FieldFill.INSERT);
TableFill gmt_modified = new TableFill("update_time", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills=new ArrayList<>();
tableFills.add(gmt_create);
tableFills.add(gmt_modified);
sc.setTableFillList(tableFills);
//樂(lè)觀(guān)鎖
sc.setVersionFieldName("version");
sc.setRestControllerStyle(true);//駝峰命名
// sc.setTablePrefix("tbl_"); 設(shè)置表名前綴
sc.setInclude(scanner("表名,多個(gè)英文逗號(hào)分割").split(","));
mpg.setStrategy(sc);
// 生成代碼
mpg.execute();
}
}
2.5 啟動(dòng)運(yùn)行代碼生成器類(lèi)
在控制臺(tái)輸入我們的表名:user

接著就完成啦!
看效果:

對(duì)于java下的所有包都不是我們自己寫(xiě)的,而是代碼生成器自動(dòng)幫我們搭建好了!
2.6 編寫(xiě)自動(dòng)填充處理器
我們?cè)诖a生成器給我們搭建的基礎(chǔ)上,只需像之前一樣,編寫(xiě)自動(dòng)填充的處理器類(lèi)即可。
package com.yixin.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Slf4j
@Component // 一定不要忘記把處理器加到IOC容器中!
public class MyMetaObjectHandler implements MetaObjectHandler {
// 插入時(shí)的填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill.....");
// setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
// 更新時(shí)的填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill.....");
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}2.7 樂(lè)觀(guān)鎖和邏輯刪除配置
package com.yixin.config;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
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;
import org.springframework.transaction.annotation.EnableTransactionManagement;
// 掃描我們的 mapper 文件夾
@MapperScan("com.yixin.mapper")
@EnableTransactionManagement
@Configuration // 配置類(lèi)
public class MyBatisPlusConfig {
// 注冊(cè)樂(lè)觀(guān)鎖插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
// 邏輯刪除組件!
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
}
這樣就大功告成啦!我們?nèi)ゾ帉?xiě)測(cè)試類(lèi)測(cè)試一下。
2.8 測(cè)試
(1)測(cè)試添加數(shù)據(jù)
package com.yixin;
import com.yixin.pojo.User;
import com.yixin.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class AutoApplicationTests {
@Autowired
private UserService userService;
@Test
void test1() {
User user=new User();
user.setName("yixin");
user.setAge(18);
boolean flag=userService.save(user);
System.out.println(flag);
}
}輸出:
可以發(fā)現(xiàn),成功插入一條數(shù)據(jù)。

(2)測(cè)試controller層獲取數(shù)據(jù)
package com.yixin.controller;
import com.yixin.pojo.User;
import com.yixin.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author yixin
* @since 2022-01-17
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@ResponseBody
@RequestMapping("/all")
public List<User> get(){
return userService.list(null);
}
}
啟動(dòng)主啟動(dòng)類(lèi):
package com.yixin;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.yixin.mapper")
public class AutoApplication {
public static void main(String[] args) {
SpringApplication.run(AutoApplication.class, args);
}
}
在瀏覽器輸入:http://localhost:8080/user/all
成功獲取到我們的數(shù)據(jù)了。

三、Service中的CRUD
3.1 插入操作
Save
// 插入一條記錄(選擇字段,策略插入) boolean save(T entity); // 插入(批量) boolean saveBatch(Collection<T> entityList);
參數(shù)說(shuō)明
| 類(lèi)型 | 參數(shù)名 | 描述 |
|---|---|---|
| T | entity | 實(shí)體對(duì)象 |
| Collection<T> | entityList | 實(shí)體對(duì)象集合 |
使用
(1)插入一條數(shù)據(jù)
@Test
void contextLoads() {
User user=new User();
user.setName("yixin");
user.setAge(18);
boolean flag=userService.save(user);
System.out.println(flag);
}(2)批量插入數(shù)據(jù)
@Test
void test3() {
List<User> userList=new ArrayList<>();
User user=new User();
user.setName("zhangsan");
user.setAge(26);
User user2=new User();
user2.setName("lisi");
user2.setAge(27);
userList.add(user);
userList.add(user2);
boolean flag=userService.saveBatch(userList);
System.out.println(flag);
}3.2 插入或更新操作
SaveOrUpdate
// TableId 注解存在更新記錄,否插入一條記錄 boolean saveOrUpdate(T entity); // 根據(jù)updateWrapper嘗試更新,否繼續(xù)執(zhí)行saveOrUpdate(T)方法 boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper); // 批量修改插入 boolean saveOrUpdateBatch(Collection<T> entityList);
參數(shù)說(shuō)明
| 類(lèi)型 | 參數(shù)名 | 描述 |
|---|---|---|
| T | entity | 實(shí)體對(duì)象 |
| Wrapper<T> | updateWrapper | 實(shí)體對(duì)象封裝操作類(lèi) UpdateWrapper |
| Collection<T> | entityList | 實(shí)體對(duì)象集合 |
使用
需求:插入一條數(shù)據(jù),如果這條數(shù)據(jù)在數(shù)據(jù)庫(kù)中存在,那么進(jìn)行更新操作,如果不存在則進(jìn)行插入操作。
@Test
void test5() {
User user=new User();
user.setName("wangwu");
user.setAge(18);
boolean flag=userService.saveOrUpdate(user);
System.out.println(flag);
}3.3 刪除操作
Remove
// 根據(jù) entity 條件,刪除記錄 boolean remove(Wrapper<T> queryWrapper); // 根據(jù) ID 刪除 boolean removeById(Serializable id); // 根據(jù) columnMap 條件,刪除記錄 boolean removeByMap(Map<String, Object> columnMap); // 刪除(根據(jù)ID 批量刪除) boolean removeByIds(Collection<? extends Serializable> idList);
參數(shù)說(shuō)明
| 類(lèi)型 | 參數(shù)名 | 描述 |
|---|---|---|
| Wrapper<T> | queryWrapper | 實(shí)體包裝類(lèi) QueryWrapper |
| Serializable | id | 主鍵 ID |
| Map<String, Object> | columnMap | 表字段 map 對(duì)象 |
| Collection<? extends Serializable> | idList | 主鍵 ID 列表 |
使用
需求:刪除所有名字帶“lisi"的用戶(hù)信息。
@Test
void test6() {
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper.like("name","lisi");
boolean flag=userService.remove(wrapper);
System.out.println(flag);
}3.4 更新操作
Update
// 根據(jù) UpdateWrapper 條件,更新記錄 需要設(shè)置sqlset boolean update(Wrapper<T> updateWrapper); // 根據(jù) whereWrapper 條件,更新記錄 boolean update(T updateEntity, Wrapper<T> whereWrapper); // 根據(jù) ID 選擇修改 boolean updateById(T entity); // 根據(jù)ID 批量更新 boolean updateBatchById(Collection<T> entityList);
參數(shù)說(shuō)明
| 類(lèi)型 | 參數(shù)名 | 描述 |
|---|---|---|
| Wrapper<T> | updateWrapper | 實(shí)體對(duì)象封裝操作類(lèi) UpdateWrapper |
| T | entity | 實(shí)體對(duì)象 |
| Collection<T> | entityList | 實(shí)體對(duì)象集合 |
使用
需求:將用戶(hù)名為”yixin"的用戶(hù)更改為“一心同學(xué)”。
@Test
void test7() {
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper.eq("name","yixin");
User user =userService.getOne(wrapper);
user.setName("一心同學(xué)");
boolean flag=userService.updateById(user);
System.out.println(flag);
}3.5 查詢(xún)操作
3.5.1 單條查詢(xún)
Get
// 根據(jù) ID 查詢(xún)
T getById(Serializable id);
// 根據(jù) Wrapper,查詢(xún)一條記錄。結(jié)果集,如果是多個(gè)會(huì)拋出異常,隨機(jī)取一條加上限制條件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根據(jù) Wrapper,查詢(xún)一條記錄
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根據(jù) Wrapper,查詢(xún)一條記錄
Map<String, Object> getMap(Wrapper<T> queryWrapper);參數(shù)說(shuō)明
| 類(lèi)型 | 參數(shù)名 | 描述 |
|---|---|---|
| Serializable | id | 主鍵 ID |
| Wrapper<T> | queryWrapper | 實(shí)體對(duì)象封裝操作類(lèi) QueryWrapper |
| boolean | throwEx | 有多個(gè) result 是否拋出異常 |
| T | entity | 實(shí)體對(duì)象 |
使用
需求:查詢(xún)名字帶“一心”的一名用戶(hù),記住,只要一名。
@Test
void test8() {
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper.like("name","一心").last("LiMIT 1");
User user=userService.getOne(wrapper);
System.out.println(user);
}3.5.2 批量查詢(xún)操作
List
// 查詢(xún)所有 List<T> list(); // 查詢(xún)列表 List<T> list(Wrapper<T> queryWrapper); // 查詢(xún)(根據(jù)ID 批量查詢(xún)) Collection<T> listByIds(Collection<? extends Serializable> idList); // 查詢(xún)(根據(jù) columnMap 條件) Collection<T> listByMap(Map<String, Object> columnMap); // 查詢(xún)所有列表 List<Map<String, Object>> listMaps(); // 查詢(xún)列表 List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper); // 查詢(xún)?nèi)坑涗? List<Object> listObjs(); // 根據(jù) Wrapper 條件,查詢(xún)?nèi)坑涗? List<Object> listObjs(Wrapper<T> queryWrapper);
參數(shù)說(shuō)明
| 類(lèi)型 | 參數(shù)名 | 描述 |
|---|---|---|
| Wrapper<T> | queryWrapper | 實(shí)體對(duì)象封裝操作類(lèi) QueryWrapper |
| Collection<? extends Serializable> | idList | 主鍵 ID 列表 |
| Map<?String, Object> | columnMap | 表字段 map 對(duì)象 |
使用
需求:查詢(xún)所有名字帶“一心”的用戶(hù)信息.
@Test
void test9() {
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper.like("name","一心");
List<User> userList=userService.list(wrapper);
System.out.println(userList);
}3.5.3 查詢(xún)數(shù)量
Count
// 查詢(xún)總記錄數(shù) int count(); // 根據(jù) Wrapper 條件,查詢(xún)總記錄數(shù) int count(Wrapper<T> queryWrapper);
參數(shù)說(shuō)明
| 類(lèi)型 | 參數(shù)名 | 描述 |
|---|---|---|
| Wrapper<T> | queryWrapper | 實(shí)體對(duì)象封裝操作類(lèi) QueryWrapper |
使用
需求:查詢(xún)所有年齡為18歲的用戶(hù)數(shù)量。
@Test
void test10() {
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper.eq("age",18);
int count=userService.count(wrapper);
System.out.println(count);
}總結(jié)
以上就是【一心同學(xué)】整理的如何【搭建代碼自動(dòng)生成器】以及在【Service層】中的【CRUD操作】,學(xué)到這里,相信大家對(duì)MyBatis-Plus越來(lái)越能感覺(jué)到其的【高效率】性了,在我們的開(kāi)發(fā)當(dāng)中,這確實(shí)能幫我們省了不少力氣呀!
這些僅為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringCloud-Hystrix-Dashboard客戶(hù)端服務(wù)監(jiān)控的實(shí)現(xiàn)方法
這篇文章主要介紹了SpringCloud-Hystrix-Dashboard客戶(hù)端服務(wù)監(jiān)控的實(shí)現(xiàn)方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
Java基礎(chǔ)之多線(xiàn)程的三種實(shí)現(xiàn)方式
這篇文章主要介紹了Java基礎(chǔ)之多線(xiàn)程的三種實(shí)現(xiàn)方式,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04
Intellij IDEA基于Springboot的遠(yuǎn)程調(diào)試(圖文)
這篇文章主要介紹了Intellij IDEA基于Springboot的遠(yuǎn)程調(diào)試(圖文),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
SpringBoot實(shí)現(xiàn)支付寶沙箱支付的完整步驟
沙箱支付是一種用于模擬真實(shí)支付環(huán)境的測(cè)試工具,它提供了一個(gè)安全的測(cè)試環(huán)境,供開(kāi)發(fā)者在不影響真實(shí)交易的情況下進(jìn)行支付功能的開(kāi)發(fā)和測(cè)試,這篇文章給大家介紹了SpringBoot實(shí)現(xiàn)支付寶沙箱支付的完整步驟,需要的朋友可以參考下2024-04-04
Spring循環(huán)依賴(lài)實(shí)例詳解
Spring循環(huán)依賴(lài)是指兩個(gè)或多個(gè)Bean相互依賴(lài),形成閉環(huán),Spring通過(guò)巧妙的機(jī)制(如三級(jí)緩存)默認(rèn)支持setter注入的循環(huán)依賴(lài),但不支持constructor注入的循環(huán)依賴(lài)(會(huì)拋異常),本文介紹spring循環(huán)依賴(lài)的相關(guān)操作,感興趣的朋友跟隨小編一起看看吧2026-03-03

