天天看點

MybatisPlus學習筆記開始使用CRUD擴充性能分析插件wapper條件構造器。條件查詢

MybatisPlus一個自動完成基本CRUD對Mybatis的增強架構。主流同類有JPA、tk-mapper。

開始使用

步驟:

1.導入依賴

<!--資料庫驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--Lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
           

注意:不要同時導入mybatis和mybatisplus,或版本沖突。

2.編寫配置

3.編碼

(沒有使用mybatisPlus:連接配接資料庫、編寫dao-service-controller)

(使用mybatisPlus:編寫pojo、mapper接口、使用)

注意:需要在主啟動類中掃描mapper下的所有接口。@MapperScan(“com.hx.mybatis_plus.dao”)

4.編寫測試類

–問題:mybatisPlus幫我們寫好了sql,和方–

配置日志

#mybatis-plus配置
mybatis-plus:
configuration:
log-impl:org.apache.ibatis.logging.stdout.StdOutImpl#使用預設的控制台輸出
           

CRUD擴充

主鍵生成政策

UUID,自增id,雪花算法,redis生成,zookeeper生成

資料庫主鍵的值,必須為唯一的id

雪花算法

分布式系統唯一id生成方案彙總

snowflake是Twitter開源的分布式ID生成算法,結果是一個long型的ID。其核心思想是:使用41bit作為毫秒數,10bit作為機器的ID(5個bit是資料中心,5個bit的機器ID),12bit作為毫秒内的流水号(意味着每個節點在每毫秒可以産生4096個ID),最後還有一個符号位,永遠是0。

幾乎可以保證全球唯一!

@TableId(type=?)IdType

預設ID_WORKER是全局唯一id

主鍵自增

1.我們需要配置自增主鍵(資料庫字段一定是要自增的)

2.實體類字段上@TableId(type=IdType.AUTO)

publicenumIdType{
AUTO(0),//自增
NONE(1),//無
INPUT(2),//手動輸入
ID_WORKER(3),//預設全局id
UUID(4),//全局iduuid
ID_WORKER_STR(5);//id_worker的字元串表示法
}
           

#更新操作

==>Preparing:UPDATEuserSETname=?,age=?,email=?WHEREid=?

==>Parameters:嘻嘻(String),19(Integer),[email protected](String),1(Long)

<==Updates:1b

這裡mybatisPlus會自動的拼接動态sql

自動填充

一般的建立時間,修改時間希望資料庫自動填充,而不是手動的填充。

阿裡開發手冊:所有的資料庫表都需要具備gmt_create,gmt_modified。幾乎所有的表都需要配置

1.資料庫級别的

不建議在工作中使用這種方式。

1.在表中新增字段create_time,update_time

##2.代碼級别的

1.為實體類加上屬性,并添加注解

@TableField(fill=FieldFill.INSERT)
privateStringcreateTime;

@TableField(fill=FieldFill.INSERT_UPDATE)
privateStringupdateTime;
           

2.編寫處理器來處理這個注解。

樂觀鎖&悲觀鎖

原子引用。

樂觀鎖:總是認為不會出現問題,不加鎖。若出現問題則再次更新值測試。

悲觀鎖:悲觀的認為總會出現問題,無論什麼都加鎖。

樂觀鎖實作機制:

1.取記錄時,擷取目前version

2.更新時帶上version

3.執行更新時,setversion=newVersionwhereversion=oldVersion

4.ifversion不對,則更新失敗

步驟

1.給資料庫加上字段version(int)

2.實體加屬性與注解

@Version
privateintversion;
           

3.掃描注冊元件

@EnableTransactionManagement//預設也是開啟的
@Configuration//配置類
//掃描mapper所在的檔案夾
@MapperScan("com.hx.mybatis_plus.dao")
publicclassMybatisPlusConfig{
//注冊一個樂觀鎖插件
@Bean
publicOptimisticLockerInterceptoroptimisticLockerInterceptor(){
returnnewOptimisticLockerInterceptor();
}
}
           

測試

//測試樂觀鎖成功
@Test//在單線程情況下是可以成功的
voidtestOptimisticLockerSuccess(){
Useruser=userMapper.selectById(1L);
user.setName("Huathy-"+newDate().getTime());
userMapper.updateById(user);
}
           

控制台輸出結果

==>Preparing:UPDATEuserSETname=?,age=?,email=?,version=?,update_time=?WHEREid=?ANDversion=?

==>Parameters:Huathy1608825571198(String),19(Integer),[email protected](String),2(Integer),2020-12-2423:59:31.227(Timestamp),1(Long),1(Integer)

<==Updates:1

//測試樂觀鎖失敗
@Test
voidtestOptimisticLockerFailed(){
//線程1操作
Useruser=userMapper.selectById(1L);
user.setName("Huathy-"+newDate().getTime());

//模拟線程2執行插隊操作
Useruser2=userMapper.selectById(1L);
user2.setName("Huathy-"+newDate().getTime());
userMapper.updateById(user2);

//可以利用自旋鎖來多次嘗試送出
userMapper.updateById(user);
}
           

查詢操作

@Test//多id查詢
voidtestSelectByBatchIds(){
List<User>users=userMapper.selectBatchIds(Arrays.asList(1,2,3));
users.forEach(System.out::println);
}

@Test//多條件查詢
voidtestSelectByMap(){
Map<String,Object>map=newHashMap<>();
map.put("name","嘻嘻");
map.put("age",18);
List<User>users=userMapper.selectByMap(map);
users.forEach(System.out::println);
}
           

分頁插件

1.原始的limit分頁

2.pageHelper分頁

3.MP内置分頁插件分頁

使用步驟

1.導入攔截器元件

//分頁插件
@Bean
publicPaginationInterceptorpaginationInterceptor(){
returnnewPaginationInterceptor();
}
           

2.測試分頁查詢

@Test
voidtestPageSelect(){
//目前頁,頁面大小
Page<User>page=newPage<>(1,5);
IPage<User>userIPage=userMapper.selectPage(page,null);
userIPage.getRecords().forEach(System.out::println);
}
           

删除操作

@Test
voidtestDeleteById(){
intres=userMapper.deleteById(3L);
System.out.println(res);
}

@Test
voidtestDeleteBatchIds(){
intres=userMapper.deleteBatchIds(Arrays.asList(4L,5L));
System.out.println(res);
}

@Test
voidtestDeleteByMap(){
Map<String,Object>map=newHashMap<>();
map.put("name","嘻嘻1");
intres=userMapper.deleteByMap(map);
System.out.println(res);
}
           

邏輯删除

實體删除:直接的從資料庫中删除。

邏輯删除:通過辨別字段辨別此記錄失效。

步驟:

1.建立資料庫字段deleted,并在實體類中加上字段

@TableLogic//邏輯删除辨別
privateIntegerdeleted;
           

2.配置邏輯删除元件

@Bean//邏輯删除元件
publicISqlInjectorsqlInjector(){
returnnewLogicSqlInjector();
}
           

3.配置邏輯删除值

global-config:
db-config:
logic-delete-value:1
logic-not-delete-value:0
           

4.測試删除

@Test
voidtestDeleteById(){
intres=userMapper.deleteById(3L);
System.out.println(res);
}
//輸出日志:
==>Preparing:UPDATEuserSETdeleted=1WHEREid=?ANDdeleted=0
==>Parameters:3(Long)
<==Updates:1
           

5.再次測試查詢,檢查是否能夠查到資料

@Test
voidtestSelectById(){
Useru=userMapper.selectById(3L);
System.out.println(u);
}
//輸出日志
==>Preparing:SELECTid,name,age,email,version,create_time,update_time,deletedFROMuserWHEREid=?ANDdeleted=0
==>Parameters:3(Long)
<==Total:0
           

性能分析插件

開發中可能存在一些慢查詢。可以通過測試(壓力測試),druid分析。MP也提供了性能分析插件。

若超過一定的時間就停止運作。

##使用步驟

導入插件->測試使用

作用:性能分析攔截器,用于輸出每條sql語句及其執行時間

1.配置yml為開發環境

#設定springboot目前為開發環境
spring:
profiles:
active:dev
           
@Bean
@Profile({"dev","test"})
publicPerformanceInterceptorperformanceInterceptor(){
PerformanceInterceptorperformanceInterceptor=newPerformanceInterceptor();
//設定sql執行的最大時間ms
performanceInterceptor.setMaxTime(100);
//開啟格式化支援
performanceInterceptor.setFormat(true);
returnperformanceInterceptor;
}
           

wapper條件構造器。條件查詢

wapper用法:

wapper.isNotNull("coloum")//非空
wapper.ge("coloum",valObj)//大于等于
           

示例:

@Test
voidselectTest(){
//查詢name和email不為空的參數且年齡>18
QueryWrapper<User>queryWrapper=newQueryWrapper<>();
queryWrapper
.isNotNull("name")
.isNotNull("email")
.ge("age",18);
userMapper.selectList(queryWrapper).forEach(System.out::println);
}