一、 MyBatis Plus 七大功能
0. 數(shù)據(jù)準(zhǔn)備
數(shù)據(jù)庫表:
CREATE TABLE `user` (
`id` bigint(20) NOT NULL COMMENT '主鍵 ',
`name` varchar(30) DEFAULT NULL COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年齡',
`email` varchar(50) DEFAULT NULL COMMENT '郵箱',
`manager_id` bigint(20) DEFAULT NULL COMMENT '直屬上級id',
`create_time` datetime DEFAULT NULL COMMENT '創(chuàng)建時間',
`update_time` datetime DEFAULT NULL COMMENT '修改時間',
`version` int(11) DEFAULT '1' COMMENT '版本',
`deleted` int(1) DEFAULT '0' COMMENT '邏輯刪除標(biāo)識(0未刪除,1已刪除)',
PRIMARY KEY (`id`),
KEY `manager_fk` (`manager_id`),
CONSTRAINT `manager_fk` FOREIGN KEY (`manager_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
實(shí)體類:
@Data
@Accessors(chain = true)
@TableName("user")
public class User extends Model<User> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主鍵ID
*/
@TableId(value = "id",type = IdType.AUTO)
private Long id;
/**
* 姓名
*/
@TableField("name")
private String name;
/**
* 年齡
*/
@TableField("age")
private Integer age;
/**
* 郵箱
*/
@TableField("email")
private String email;
@TableField("manager_id")
private Long manageId;
/**
* 出生時間
*/
@TableField("create_time")
private LocalDateTime createTime;
@TableField("update_time")
private LocalDateTime updateTime;
/**
* 是否置頂
*/
@TableField("version")
private Integer version;
/**
* 字段排除
*/
@TableLogic
@TableField("deleted")
private Integer deleted;
}
xml配置:
server:
port: 8088
spring:
# 配置數(shù)據(jù)源信息
datasource:
# 配置連接數(shù)據(jù)庫信息
#本地地址:“127.0.0.1”
#數(shù)據(jù)庫名稱:“db2”
url: jdbc:mysql://127.0.0.1:3306/db2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
#數(shù)據(jù)庫賬戶
username: root
#數(shù)據(jù)庫密碼
password: root
mybatis-plus:
global-config:
db-config:
#邏輯刪除字段
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
1. 邏輯刪除
邏輯刪除語句:
int i = userMapper.deleteById(2);
System.out.println(i);
真實(shí)執(zhí)行語句:
==> Preparing: UPDATE user SET deleted=1 WHERE id=? AND deleted=0
==> Parameters: 2(Integer)
<== Updates: 1
實(shí)際未刪除,只修改刪除字段的值
這時候如果執(zhí)行查詢語句,則只會展示邏輯刪除為0的字段記錄:
List<User> list = userMapper.selectList(null);
list.forEach(System.out::println);
雖然庫中有三條記錄但是有兩條刪除字段為1,則list中只展示一條
@TableField(value = "deleted",select = false)
private Integer deleted;
select=false; 查詢語句將不出現(xiàn)deleted字段
2. 自動填充
自動填充 創(chuàng)建和 更新時間
@TableField(value = "create_time",fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(value = "update_time",fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
System.out.println("==============insertFill");
setFieldValByName("createTime", LocalDateTime.now(),metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
System.out.println("==============updateFill");
}
}
2.1 優(yōu)化1 自動填充 有的類沒有更新和創(chuàng)建時間字段
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
boolean hasSetter = metaObject.hasSetter("createTime");
if (hasSetter){
System.out.println("==============insertFill");
setFieldValByName("createTime", LocalDateTime.now(),metaObject);
}
}
@Override
public void updateFill(MetaObject metaObject) {
boolean hasSetter = metaObject.hasSetter("updateTime");
if (hasSetter){
setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
System.out.println("==============updateFill");
}
}
}
2.2 優(yōu)化2 自己設(shè)置時間時填充自己設(shè)置的,不設(shè)置時自動填充
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
Object createTime = getFieldValByName("createTime", metaObject);
if (ObjectUtils.isNull(createTime)){
boolean hasSetter = metaObject.hasSetter("createTime");
if (hasSetter){
System.out.println("==============insertFill");
setFieldValByName("createTime", LocalDateTime.now(),metaObject);
}
}
}
@Override
public void updateFill(MetaObject metaObject) {
Object updateTime = getFieldValByName("updateTime", metaObject);
if (ObjectUtils.isNull(updateTime)){
boolean hasSetter = metaObject.hasSetter("updateTime");
if (hasSetter){
setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
System.out.println("==============updateFill");
}
}
}
}
3. 樂觀鎖插件 注:wrapper不能服用
樂觀鎖和悲觀鎖是在并發(fā)編程中用來處理資源競爭和保證數(shù)據(jù)一致性的兩種不同策略。它們各自適用于不同的使用場景:
樂觀鎖:
樂觀鎖的核心思想是假設(shè)并發(fā)訪問的操作不會發(fā)生沖突,因此在讀取資源時不會進(jìn)行加鎖,而是在更新資源時進(jìn)行沖突檢測。如果發(fā)現(xiàn)有其他線程已經(jīng)對資源進(jìn)行修改,則放棄當(dāng)前操作或嘗試重新執(zhí)行。
使用場景:
并發(fā)寫入操作較少的情況下,沖突發(fā)生的概率較低。
數(shù)據(jù)庫表中的數(shù)據(jù)很少被修改,在持續(xù)時間較短的事務(wù)中進(jìn)行讀取操作。
適合處理樂觀并發(fā)控制機(jī)制,如版本號或時間戳等。
悲觀鎖:
悲觀鎖的核心思想是假設(shè)并發(fā)訪問的操作會發(fā)生沖突,因此在訪問資源之前會進(jìn)行加鎖操作,確保在整個操作期間資源不被其他線程修改。
使用場景:
并發(fā)寫入操作較多的情況下,沖突發(fā)生的概率較高。
數(shù)據(jù)庫表中的數(shù)據(jù)經(jīng)常被修改,在持續(xù)時間較長的事務(wù)中進(jìn)行讀取操作。
適合使用數(shù)據(jù)庫的行級鎖、表級鎖或者分布式鎖等來實(shí)現(xiàn)。
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加:分頁插件
//參數(shù):new PaginationInnerInterceptor(DbType.MYSQL),是專門為mysql定制實(shí)現(xiàn)的內(nèi)部的分頁插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//添加:樂觀鎖插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
實(shí)體類字段:
@TableField("version")
@Version
private Integer version;
測試:
int version=2;
User user = new User();
user.setId(1683667832465985538L);
user.setEmail("lwx@qq.com");
user.setName("lwx");
user.setVersion(version);
int update = userMapper.updateById(user);
System.out.println(update);
4. 性能分析插件
4.1 PerformanceInterceptor 3.2.0版本被廢除
@Bean
@Profile({"dev","test"}) // 指定環(huán)境
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor interceptor = new PerformanceInterceptor();
// sql美化打印
interceptor.setFormat(true);
// 設(shè)置SQL超時時間
interceptor.setMaxTime(500);
//格式化語句
performanceInterceptor.setFormat(true);
return interceptor;
}
4.2 p6spy 使用
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.8.7</version>
</dependency>
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定義日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志輸出到控制臺
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系統(tǒng)記錄 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 設(shè)置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前綴
useprefix=true
# 配置記錄 Log 例外,可去掉的結(jié)果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 實(shí)際驅(qū)動可多個
#driverlist=org.h2.Driver
# 是否開啟慢SQL記錄
outagedetection=true
# 慢SQL記錄標(biāo)準(zhǔn) 2 秒
outagedetectioninterval=2
server:
port: 8088
spring:
# 配置數(shù)據(jù)源信息
datasource:
# 配置連接數(shù)據(jù)庫信息
#本地地址:“127.0.0.1”
#數(shù)據(jù)庫名稱:“db2”
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://localhost:3306/db2?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
#數(shù)據(jù)庫賬戶
username: root
#數(shù)據(jù)庫密碼
password: root
mybatis-plus:
global-config:
db-config:
#邏輯刪除字段
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
文章來源地址http://www.zghlxwxcb.cn/news/detail-617114.html
5. 多租戶SQL解析器
6. 動態(tài)表名SQL解析器
7. SQL注入器
文章來源:http://www.zghlxwxcb.cn/news/detail-617114.html
到了這里,關(guān)于【MyBatis-Plus 進(jìn)階學(xué)習(xí)筆記】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!