Springboot集成Mybatis-Flex的示例詳解
1 Mybatis-Flex 介紹
1.1簡(jiǎn)介
Mybatis-Flex 是一個(gè)優(yōu)雅的 Mybatis 增強(qiáng)框架,它非常輕量、同時(shí)擁有極高的性能與靈活性。我們可以輕松的使用 Mybaits-Flex 鏈接任何數(shù)據(jù)庫(kù),其內(nèi)置的 QueryWrapper 亮點(diǎn)幫助我們極大的減少了 SQL 編寫(xiě)的工作的同時(shí),減少出錯(cuò)的可能性。
1.2特征
1.輕量:除了 MyBatis,沒(méi)有任何第三方依賴、沒(méi)有任何攔截器,在執(zhí)行的過(guò)程中,沒(méi)有任何的 Sql 解析(Parse)。 這帶來(lái)了幾個(gè)好處:極高的性能、極易對(duì)代碼進(jìn)行跟蹤和調(diào)試、把控性更高。
2.靈活:支持 Entity 的增刪改查、以及分頁(yè)查詢的同時(shí),MyBatis-Flex 提供了 Db + Row 工具,可以無(wú)需實(shí)體類對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查以及分頁(yè)查詢。 與此同時(shí),MyBatis-Flex 內(nèi)置的 QueryWrapper 可以輕易的幫助我們實(shí)現(xiàn) 多表查詢、鏈接查詢、子查詢 等等常見(jiàn)的 SQL 場(chǎng)景。
3.強(qiáng)大:支持任意關(guān)系型數(shù)據(jù)庫(kù),還可以通過(guò)方言持續(xù)擴(kuò)展,同時(shí)支持 多(復(fù)合)主鍵、邏輯刪除、樂(lè)觀鎖配置、數(shù)據(jù)脫敏、數(shù)據(jù)審計(jì)、 數(shù)據(jù)填充 等等功能。
簡(jiǎn)單來(lái)說(shuō),Mybatis-Flex 相比 Mybatis-Plus 等框架 速度更快、功能更多、代碼更簡(jiǎn)潔~
1.3Mybatis-Flex和同類框架對(duì)比
1)功能對(duì)比:


2)性能對(duì)比:
這里直接貼測(cè)試結(jié)果:
MyBatis-Flex 的查詢單條數(shù)據(jù)的速度,大概是 MyBatis-Plus 的 5 ~ 10+ 倍。
MyBatis-Flex 的查詢 10 條數(shù)據(jù)的速度,大概是 MyBatis-Plus 的 5~10 倍左右。
Mybatis-Flex 的分頁(yè)查詢速度,大概是 Mybatis-Plus 的 5~10 倍左右。
Mybatis-Flex 的數(shù)據(jù)更新速度,大概是 Mybatis-Plus 的 5~10+ 倍。
2 準(zhǔn)備工作
以 Spring Boot + Maven + Mysql 項(xiàng)目做演示
2.1 數(shù)據(jù)庫(kù)中創(chuàng)建表及插入數(shù)據(jù)
此處省略~
2.2 Spring Boot 項(xiàng)目初始化
此時(shí)需要?jiǎng)?chuàng)建 Spring Boot 項(xiàng)目,并添加 Maven 依賴;此處我通過(guò) IDEA 使用 Spring Initializer 快速初始化一個(gè) Spring Boot 工程。
項(xiàng)目創(chuàng)建省略~
2.3 添加 Maven 主要依賴
往 pom.xml 文件中添加以下依賴。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
<version>1.7.3</version>
</dependency>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-processor</artifactId>
<version>1.7.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--++++++++++++++++++++++++++++++++++++++++++++++++++++-->
<!-- MyBatis分頁(yè)插件 -->
<!--++++++++++++++++++++++++++++++++++++++++++++++++++++-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>2.4 配置數(shù)據(jù)源
在 application.properties 或 application.yml 中配置數(shù)據(jù)源:
server.port=8999 spring.application.name=mybatisPlus spring.datasource.username=root spring.datasource.password=root3306 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
3 Mybatis-Flex 實(shí)踐
3.1 編寫(xiě)實(shí)體類和 Mapper 接口
?? User 實(shí)體類
- 使用 @Table("flex_user") 設(shè)置實(shí)體類與表名的映射關(guān)系
- 使用 @Id(keyType = KeyType.Auto) 標(biāo)識(shí)主鍵為自增
package com.mybatisflex.flex.domain;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
/**
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
//使用 @Table("tb_account") 設(shè)置實(shí)體類與表名的映射關(guān)系
@Table("user")
public class User implements Serializable {
private Integer id;
@Column(value = "name")
private String name;
@Column(value = "age")
private Integer age;
@Column(value = "email")
private String email;
@Column(value = "create_time", onInsertValue = "now()")
private Date createTime;
@Column(value = "update_time", onUpdateValue = "now()")
private Date updateTime;
@Column(value = "del_flag")
private int delFlag;
@Column(value = "dept_code")
private String deptCode;
}
?? Mapper 接口繼承 BaseMapper 接口
package com.mybatisflex.flex.mapper;
import com.mybatisflex.core.BaseMapper;
import com.mybatisflex.flex.domain.User;
/**
*
*/
public interface UserMapper extends BaseMapper<User> {
}3.2 在主啟動(dòng)類添加 @MapperScan 注解
用于掃描 Mapper 文件夾:
package com.mybatisflex.flex;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.mybatisflex.flex.mapper")
public class FlexApplication {
public static void main(String[] args) {
SpringApplication.run(FlexApplication.class, args);
}
}3.3 創(chuàng)建service
package com.mybatisflex.flex.service;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.flex.domain.User;
import com.mybatisflex.flex.domain.UserDto;
import com.mybatisflex.flex.domain.table.SysDeptTableDef;
import com.mybatisflex.flex.domain.table.UserTableDef;
import com.mybatisflex.flex.mapper.UserMapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description:
* @Date Create in 10:39 2023/11/22
* @Modified By:
*/
@Service
public class UserService extends ServiceImpl<UserMapper, User> {
/**
* 查詢?nèi)?
* @return
*/
public List<User> selectAll(){
return this.getMapper().selectAll();
}
public List<User> selectList(){
QueryWrapper wrapper = QueryWrapper.create()
// 這里可以指定查詢字段
.select()
// sql from表名
.from(User.class)
.where(User::getName).like("徐")
.or(UserTableDef.USER.ID.in(2,3).and(UserTableDef.USER.NAME.like("o")));
return this.getMapper().selectListByQuery(wrapper);
}
/**
* 根據(jù)userId獲取User數(shù)據(jù)
* @param userId
* @return
*/
public User listById(Integer userId){
QueryWrapper wrapper = QueryWrapper.create()
// 這里可以指定查詢字段
.select()
// sql from表名
.from(User.class)
.where(User::getId).eq(userId).and(User::getName).like("徐");
return this.getMapper().selectOneByQuery(wrapper);
}
/**
* 關(guān)聯(lián)查詢--鏈?zhǔn)讲樵?
*/
public List<UserDto> getInfo(Integer userId){
QueryWrapper query = QueryWrapper.create()
.select(UserTableDef.USER.ALL_COLUMNS)
.select(SysDeptTableDef.SYS_DEPT.DEPT_NAME)
.from(UserTableDef.USER).as("u")
.leftJoin(SysDeptTableDef.SYS_DEPT).as("d").on(UserTableDef.USER.DEPT_CODE.eq(SysDeptTableDef.SYS_DEPT.DEPT_CODE))
.where(UserTableDef.USER.ID.eq(userId));
return this.getMapper().selectListByQueryAs(query,UserDto.class);
}
/**
* 新增
* @param user
*/
public void insert(User user){
this.getMapper().insert(user);
}
/**
* 更新User
* @param user
*/
public void updateEntity(User user){
this.getMapper().update(user);
}
/**
* 局部更新
* @param userId
* @param userName
*/
public void updateRow(Integer userId, String userName){
UpdateChain.of(User.class)
.set(User::getName, userName)
.where(User::getId).eq(userId).update();
}
/**
* 刪除
* @param userName
*/
public void deleteByWrapper(String userName){
QueryWrapper queryWrapper = QueryWrapper.create().where(User::getName).eq(userName);
this.getMapper().deleteByQuery(queryWrapper);
}
}
3.4創(chuàng)建Controller接口測(cè)試
package com.mybatisflex.flex.controller;
import com.mybatisflex.flex.domain.User;
import com.mybatisflex.flex.domain.UserDto;
import com.mybatisflex.flex.page.TableDataInfo;
import com.mybatisflex.flex.service.UserService;
import com.mybatisflex.flex.utils.ResponseUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @Author: best_liu
* @Description:
* @Date Create in 10:33 2023/11/22
* @Modified By:
*/
@RestController
@RequestMapping("/user")
public class SysUserController {
@Resource
private UserService userService;
/**
* 查詢?nèi)?
* @return
*/
@GetMapping("listall")
public List<User> listall(){
return userService.selectAll();
}
/**
* 分頁(yè)查詢
* @return
**/
@GetMapping("/page")
public TableDataInfo findPage() {
ResponseUtils.startPage();
return ResponseUtils.getDataTable(userService.selectAll());
}
/**
* 按條件查詢
* @return
*/
@GetMapping("getList")
public List<User> selectList(){
return userService.selectList();
}
/**
* 按userId查詢
* @return
*/
@GetMapping("listById")
public User listById(){
return userService.listById(0);
}
/**
* 按userId關(guān)聯(lián)查詢部門(mén)
* @return
*/
@GetMapping("getInfo")
public List<UserDto> getInfo(){
return userService.getInfo(0);
}
/**
* 新增
* @return
*/
@GetMapping("insert")
public Boolean insert(){
User user = User.builder().id(10).name("張三").age(100).email("zhangsan@163.com").build();
userService.insert(user);
return Boolean.TRUE;
}
/**
* 更新
* @return
*/
@GetMapping("update")
public Boolean update(){
userService.updateRow(10, "張三三");
return Boolean.TRUE;
}
/**
* 刪除
* @return
*/
@GetMapping("delete")
public Boolean delete(){
userService.deleteByWrapper("張三三");
return Boolean.TRUE;
}
}
4 鏈?zhǔn)讲樵?/h2>
若想使用鏈?zhǔn)讲樵?/strong>還得需要 APT 配置,MyBatis-Flex 使用了 APT(Annotation Processing Tool)技術(shù),在項(xiàng)目編譯的時(shí)候,會(huì)自動(dòng)根據(jù) Entity/pojo 類定義的字段幫你生成 "USER" 類(可用于鏈?zhǔn)讲樵儯?/p>
通過(guò)開(kāi)發(fā)工具構(gòu)建項(xiàng)目(如下圖),或者執(zhí)行 maven 編譯命令: mvn clean package 都可以自動(dòng)生成。 正常情況下,會(huì)在 target 包下生成如下資源 若生成該資源并導(dǎo)入成功,那么此時(shí),可使用鏈?zhǔn)讲樵?/p>
總的來(lái)說(shuō),MyBatis-Flex 的鏈?zhǔn)讲樵兿啾?nbsp;MyBatis-Plus 多了一步配置環(huán)節(jié),目前來(lái)看其他步驟類似。 接下來(lái)看一下MyBatis-Flex 和 MyBatis-Plus 各部分功能代碼的差別,Employee、Account、Article 都是實(shí)體類。 MyBatis-Flex: MyBatis-Plus: MyBatis-Flex: MyBatis-Plus: 缺點(diǎn):字段硬編碼,容易拼錯(cuò)。無(wú)法使用 IDE 的字段進(jìn)行重構(gòu),無(wú)法使用 IDE 自動(dòng)提示,發(fā)生錯(cuò)誤不能及時(shí)發(fā)現(xiàn),不過(guò)MyBatis-Plus的 lambdawrapper 也是能解決這個(gè)問(wèn)題。 假設(shè)我們要構(gòu)建如下的 SQL 進(jìn)行查詢(需要在 SQL 中添加括號(hào))。 MyBatis-Flex: MyBatis-Plus: MyBatis-Flex: MyBatis-Plus:不支持 假設(shè)一個(gè)實(shí)體類 Account 中,我們要更新其內(nèi)容如下: 其他字段保持?jǐn)?shù)據(jù)庫(kù)原有內(nèi)容不變,要求執(zhí)行的 SQL 如下: MyBatis-Flex 代碼如下: MyBatis-Plus 代碼如下(或可使用 MyBatis-Plus 的 LambdaUpdateWrapper,但性能沒(méi)有 UpdateWrapper 好): 如上,MyBatis-Flex 在代碼編寫(xiě)來(lái)說(shuō)更加靈活,編寫(xiě)方式更多一些,還是有些優(yōu)勢(shì)。 MyBatis-Flex 使用多租戶需要 2 個(gè)步驟: TenantFactory 是用于生產(chǎn)租戶ID的,或者說(shuō)是用于獲取當(dāng)前租戶ID的。 以下是代碼示例: 通過(guò) 到此這篇關(guān)于Springboot集成Mybatis-Flex的示例詳解的文章就介紹到這了,更多相關(guān)Springboot集成Mybatis-Flex內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

/**
* 關(guān)聯(lián)查詢
*/
public List<UserDto> getInfo(Integer userId){
QueryWrapper query = QueryWrapper.create()
.select(UserTableDef.USER.ALL_COLUMNS)
.select(SysDeptTableDef.SYS_DEPT.DEPT_NAME)
.from(UserTableDef.USER).as("u")
.leftJoin(SysDeptTableDef.SYS_DEPT).as("d").on(UserTableDef.USER.DEPT_CODE.eq(SysDeptTableDef.SYS_DEPT.DEPT_CODE))
.where(UserTableDef.USER.ID.eq(userId));
return this.getMapper().selectListByQueryAs(query,UserDto.class);
}5 MyBatis-Flex/Plus 代碼對(duì)比
5.1 基礎(chǔ)查詢
QueryWrapper query = QueryWrapper.create()
.where(EMPLOYEE.LAST_NAME.like(searchWord)) //條件為null時(shí)自動(dòng)忽略
.and(EMPLOYEE.GENDER.eq(1))
.and(EMPLOYEE.AGE.gt(24));
List<Employee> employees = employeeMapper.selectListByQuery(query);QueryWrapper<Employee> queryWrapper = Wrappers.query()
.like(searchWord != null, "last_name", searchWord)
.eq("gender", 1)
.gt("age", 24);
List<Employee> employees = employeeMapper.selectList(queryWrapper);
//lambda 寫(xiě)法:
LambdaQueryWrapper<Employee> queryWrapper = Wrappers.<Employee>lambdaQuery()
.like(StringUtils.isNotEmpty(searchWord), Employee::getUserName,"B")
.eq(Employee::getGender, 1)
.gt(Employee::getAge, 24);
List<Employee> employees = employeeMapper.selectList(queryWrapper);5.2 集合查詢
QueryWrapper query = QueryWrapper.create()
.select(
ACCOUNT.ID,
ACCOUNT.USER_NAME,
max(ACCOUNT.BIRTHDAY),
avg(ACCOUNT.SEX).as("sex_avg")
);
List<Employee> employees = employeeMapper.selectListByQuery(query);QueryWrapper<Employee> queryWrapper = Wrappers.query()
.select(
"id",
"user_name",
"max(birthday)",
"avg(birthday) as sex_avg"
);
List<Employee> employees = employeeMapper.selectList(queryWrapper);5.3 and(...) 和 or(...)
SELECT * FROM tb_account
WHERE id >= 100
AND (sex = 1 OR sex = 2)
OR (age IN (18,19,20) AND user_name LIKE "%michael%" )
QueryWrapper query = QueryWrapper.create()
.where(ACCOUNT.ID.ge(100))
.and(ACCOUNT.SEX.eq(1).or(ACCOUNT.SEX.eq(2)))
.or(ACCOUNT.AGE.in(18, 19, 20).and(ACCOUNT.USER_NAME.like("michael")));QueryWrapper<Employee> query = Wrappers.query()
.ge("id", 100)
.and(i -> i.eq("sex", 1).or(x -> x.eq("sex", 2)))
.or(i -> i.in("age", 18, 19, 20).like("user_name", "michael"));
// or lambda
LambdaQueryWrapper<Employee> query = Wrappers.<Employee>lambdaQuery()
.ge(Employee::getId, 100)
.and(i -> i.eq(Employee::getSex, 1).or(x -> x.eq(Employee::getSex, 2)))
.or(i -> i.in(Employee::getAge, 18, 19, 20).like(Employee::getUserName, "michael"));5.4 多表查詢
QueryWrapper query = QueryWrapper.create()
.select().from(ACCOUNT)
.leftJoin(ARTICLE).on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID))
.where(ACCOUNT.AGE.ge(10));
List<Account> accounts = mapper.selectListByQuery(query);QueryWrapper query = new QueryWrapper()
.select(
ACCOUNT.ID
, ACCOUNT.USER_NAME
, ARTICLE.ID.as("articleId")
, ARTICLE.TITLE)
.from(ACCOUNT.as("a"), ARTICLE.as("b"))
.where(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID));5.5 部分字段更新
update tb_account
set user_name = "michael", age = 18, birthday = null
where id = 100
Account account = UpdateEntity.of(Account.class);
account.setId(100); //設(shè)置主鍵
account.setUserName("michael");
account.setAge(18);
account.setBirthday(null);
accountMapper.update(account);UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", 100);
updateWrapper.set("user_name", "michael");
updateWrapper.set("age", 18);
updateWrapper.set("birthday", null);
accountMapper.update(null, updateWrapper);6 mybatis-flex使用多租戶
@Column(tenantId = true) 標(biāo)識(shí)租戶列。TenantManager 配置 TenantFactory。@Table("tb_article")
public class Article {
@Id(keyType = KeyType.Auto)
private Long id;
@Column(tenantId = true)
private Long tenantId;
}@Column(tenantId = true) 表示租戶ID。 6.1 創(chuàng)建MyTenantFactory類
import com.mybatisflex.core.tenant.TenantFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
/**
* @Author:
* @Description: 當(dāng)然,MyTenantFactory 需要正常工作,我們需要在 Spring 攔截器里,需要通過(guò) request 去獲取當(dāng)前的租戶 ID,并設(shè)置到 request 的 attribute
* @Date Create in 15:24 2023/11/24
* @Modified By:
*/
public class MyTenantFactory implements TenantFactory {
@Override
public Object[] getTenantIds(){
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
// Long tenantId = (Long) attributes.getAttribute("tenantId", RequestAttributes.SCOPE_REQUEST);
Long tenantId = 1L;
return new Object[]{tenantId};
}
}6.2 創(chuàng)建MyConfiguration類,注入MyTenantFactory
import com.mybatisflex.core.tenant.TenantFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: best_liu
* @Description:
* @Date Create in 15:25 2023/11/24
* @Modified By:
*/
@Configuration
public class MyConfiguration {
@Bean
public TenantFactory tenantFactory(){
TenantFactory tenantFactory = new MyTenantFactory();
return tenantFactory;
}
} 6.3 實(shí)現(xiàn)ConfigurationCustomizer接口的customize()自定義方法
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.mybatis.FlexConfiguration;
import com.mybatisflex.spring.boot.ConfigurationCustomizer;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.springframework.context.annotation.Configuration;
/**
* @Author: best_liu
* @Description: Mybatis-flex sql日志打印
* @Date Create in 15:30 2023/11/24
* @Modified By:
*/
@Configuration
public class MyConfigurationCustomizer implements ConfigurationCustomizer {
/**
* 自定義的FlexConfiguration配置
* @param configuration
*/
@Override
public void customize(FlexConfiguration configuration) {
//在 MyBatis-Flex 中,可以使用 FlexGlobalConfig 在 MyBatis-Flex 啟動(dòng)之前,指定項(xiàng)目中的多租戶列的列名。
FlexGlobalConfig.getDefaultConfig().setTenantColumn("tenant_id");
//全局配置主鍵生成策略
FlexGlobalConfig.KeyConfig keyConfig = new FlexGlobalConfig.KeyConfig();
keyConfig.setKeyType(KeyType.Generator);
keyConfig.setValue(KeyGenerators.snowFlakeId);
keyConfig.setBefore(true);
//sql日志打印
configuration.setLogImpl(StdOutImpl.class);
}
}
相關(guān)文章
Java Json字符串的雙引號(hào)("")括號(hào)如何去掉
這篇文章主要介紹了Java Json字符串的雙引號(hào)("")括號(hào)如何去掉?具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
關(guān)于Spring多數(shù)據(jù)源TransactionManager沖突的解決方案
這篇文章主要介紹了關(guān)于Spring多數(shù)據(jù)源TransactionManager沖突的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
SpringBoot讀取properties文件配置項(xiàng)過(guò)程解析
這篇文章主要介紹了SpringBoot讀取properties文件配置項(xiàng)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
淺析EasyExcel如何導(dǎo)出自動(dòng)回顯中文
這篇文章主要為大家詳細(xì)介紹了EasyExcel如何通過(guò)全局轉(zhuǎn)換器和自定義注解實(shí)現(xiàn)導(dǎo)出自動(dòng)回顯中文,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-04-04
使用java為pdf添加書(shū)簽的方法(pdf書(shū)簽制作)
下載一些pdf格式的電子書(shū)沒(méi)有書(shū)簽,用JAVA寫(xiě)了一個(gè)小工具,將特定格式的文本解析成為書(shū)簽,然后保存到pdf格式中2014-02-02
在SpringBoot項(xiàng)目中獲取Request的四種方法
這篇文章主要為大家詳細(xì)介紹了SpringBoot項(xiàng)目中獲取Request的四種方法,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下2023-11-11
SpringBoot訪問(wèn)請(qǐng)求404解決方法
這篇文章主要介紹了SpringBoot訪問(wèn)請(qǐng)求404解決方法,文中有詳細(xì)的解決方法供大家參考,對(duì)我們學(xué)習(xí)或工作有一定的幫助,需要的朋友跟著小編一起來(lái)學(xué)習(xí)吧2023-07-07

