MyBatis-Plus入門
1、簡介
MyBatis-Plus(簡稱 MP)是一個 MyBatis 的增強工具,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑。只需簡單配置,即可快速進行 CRUD 操作,從而節省大量時間。代碼生成、分頁、性能分析等功能一應俱全。
2、插入操作
//添加 |
注意:數據庫插入id值默認為:全局唯一id
2、MP的主鍵策略
2.1 ASSIGN_ID
MyBatis-Plus默認的主鍵策略是:ASSIGN_ID (使用了雪花算法)
@TableId(type = IdType.ASSIGN_ID) private String id; |
雪花算法:分布式ID生成器,雪花算法是由Twitter公布的分布式主鍵生成算法,它能夠保證不同表的主鍵的不重復性,以及相同表的主鍵的有序性。長度共64bit(一個long型)。首先是一個符號位,1bit標識,由於long基本類型在Java中是帶符號的,最高位是符號位,正數是0,負數是1,所以id一般是正數,最高位是0。41bit時間截(毫秒級),存儲的時間截的差值(當前時間截 - 開始時間截),結果約等於69.73年。10bit作為機器的ID(5個bit是數據中心,5個bit的機器ID,可以部署在1024個節點)。12bit作為毫秒內的流水號(意味着每個節點在每毫秒可以產生 4096 個 ID)。優點:整體上按照時間自增排序,並且整個分布式系統內不會產生ID碰撞,並且效率較高。
2.2 AUTO 自增策略
需要在創建數據表的時候設置主鍵自增,實體字段中配置 @TableId(type = IdType.AUTO)
@TableId(type = IdType.AUTO) private Long id; |
要想影響所有實體的配置,可以設置全局主鍵配置
#全局設置主鍵生成策略 mybatis-plus.global-config.db-config.id-type=auto |
2、更新操作
注意:update時生成的sql自動是動態sql:UPDATE user SET age=? WHERE id=?
//修改 |
3、查詢
3.1通過多個id批量查詢
完成了動態sql的foreach的功能
//多個id批量查詢 |
3.2簡單的條件查詢
通過map封裝查詢條件
注意:map中的key對應數據庫中的列名。如:數據庫user_id,實體類是userId,這時map的key需要填寫user_id
//簡單條件查詢 |
3.3分頁插件
MyBatis Plus自帶分頁插件,只要簡單的配置即可實現分頁功能
3.3.1添加分頁插件
配置類中添加@Bean配置
/** |
3.3.2測試selectPage分頁
測試:最終通過page對象獲取相關數據
//分頁查詢 |
3.3.3.測試selectMapsPage分頁
當指定了特定的查詢列時,希望分頁結果列表只返回被查詢的列,而不是很多null值
測試selectMapsPage分頁:結果集是Map
@Test public void testSelectMapsPage() { //Page不需要泛型 Page<Map<String, Object>> page = newPage<>(1, 5); Page<Map<String, Object>> pageParam = userMapper.selectMapsPage(page, null); List<Map<String, Object>> records = pageParam.getRecords(); records.forEach(System.out::println); System.out.println(pageParam.getCurrent()); System.out.println(pageParam.getPages()); System.out.println(pageParam.getSize()); System.out.println(pageParam.getTotal()); System.out.println(pageParam.hasNext()); System.out.println(pageParam.hasPrevious()); } |
4、刪除
4.1根據id刪除記錄
@Test public void testDeleteById(){ int result = userMapper.deleteById(5L); system.out.println(result); } |
4.2批量刪除
@Test public void testDeleteBatchIds() { int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10)); system.out.println(result); } |
4.3簡單條件刪除
@Test public void testDeleteByMap() { HashMap<String, Object> map = new HashMap<>(); map.put("name", "Helen"); map.put("age", 18); int result = userMapper.deleteByMap(map); system.out.println(result); } |
5、邏輯刪除
5.1物理刪除和邏輯刪除
物理刪除:真實刪除,將對應數據從數據庫中刪除,之后查詢不到此條被刪除數據
邏輯刪除:假刪除,將對應數據中代表是否被刪除字段狀態修改為“被刪除狀態”,之后在數據庫中仍舊能看到此條數據記錄
邏輯刪除的使用場景:
可以進行數據恢復,有關聯數據,不便刪除
5.2 邏輯刪除實現流程
5.2.1數據庫修改
添加 deleted字段
ALTERTABLE `user` ADD COLUMN `deleted` boolean DEFAULT false |
5.2.2實體類修改
添加deleted 字段,並加上 @TableLogic 注解
@TableLogic private Integer deleted; |
5.2.3配置(可選)
application.properties 加入以下配置,此為默認值,如果你的默認值和mp默認的一樣,該配置可無
mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0 |
5.2.4 測試
測試后發現,數據並沒有被刪除,deleted字段的值由0變成了1測試后分析打印的sql語句,是一條update
注意:被刪除前,數據的deleted 字段的值必須是 0,才能被選取出來執行邏輯刪除的操作
@Test public void testLogicDelete() { int result = userMapper.deleteById(1L); system.out.println(result); } |
5.2.5測試邏輯刪除后的查詢
MyBatis Plus中查詢操作也會自動添加邏輯刪除字段的判斷
@Test public void testLogicDeleteSelect() { List<User> users = userMapper.selectList(null); users.forEach(System.out::println); } |
MyBatis_Plus條件構造器和常用接口
1、wapper介紹
Wrapper : 條件構造抽象類,最頂端父類
AbstractWrapper : 用於查詢條件封裝,生成 sql 的 where 條件
QueryWrapper : 查詢條件封裝
UpdateWrapper : Update 條件封裝
AbstractLambdaWrapper : 使用Lambda 語法
LambdaQueryWrapper :用於Lambda語法使用的查詢Wrapper
LambdaUpdateWrapper : Lambda 更新封裝Wrapper
2、測試用例
2.1 ge大於等於、gt大於、le小於等於、lt小於、isNull是null、isNotNull不是null
@Test public void testQuery() { QueryWrapper<User>queryWrapper = newQueryWrapper<>(); queryWrapper .isNull("name") .ge("age", 12) .isNotNull("email"); int result = userMapper.delete(queryWrapper); System.out.println("delete return count = " + result); } |
2.2 eq、ne
注意:seletOne()返回的是一條實體記錄,當出現多條時會報錯
@Test public void testSelectOne() { QueryWrapper<User>queryWrapper = newQueryWrapper<>(); queryWrapper.eq("name", "Tom"); Useruser = userMapper.selectOne(queryWrapper);//只能返回一條記錄,多余一條則拋出異常 System.out.println(user); } |
2.3 between、notBetween
包含大小邊界
@Test public void testSelectCount() { QueryWrapper<User>queryWrapper = newQueryWrapper<>(); queryWrapper.between("age", 20, 30); Integer count = userMapper.selectCount(queryWrapper); //返回數據數量 System.out.println(count); } |
2.4 like、notLike、likeLeft、likeRight
selectMaps()返回Map集合列表,通常配合select()使用
@Test public void testSelectMaps() { QueryWrapper<User>queryWrapper = newQueryWrapper<>(); queryWrapper .select("name", "age") .like("name", "e") .likeRight("email", "5"); List<Map<String, Object>>maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表 maps.forEach(System.out::println); } |
2.5 orderBy、orderByDesc、orderByAsc
@Test public void testSelectListOrderBy() { QueryWrapper<User>queryWrapper = newQueryWrapper<>(); queryWrapper.orderByDesc("age", "id"); List<User>users = userMapper.selectList(queryWrapper); users.forEach(System.out::println); } |
2、查詢方式
查詢方式 |
說明 |
setSqlSelect |
設置 SELECT 查詢字段 |
where |
WHERE 語句,拼接 + WHERE 條件 |
and |
AND 語句,拼接 + AND 字段=值 |
andNew |
AND 語句,拼接 + AND (字段=值) |
or |
OR 語句,拼接 + OR 字段=值 |
orNew |
OR 語句,拼接 + OR (字段=值) |
eq |
等於= |
allEq |
基於 map 內容等於= |
ne |
不等於<> |
gt |
大於> |
ge |
大於等於>= |
lt |
小於< |
le |
小於等於<= |
like |
模糊查詢 LIKE |
notLike |
模糊查詢 NOT LIKE |
in |
IN 查詢 |
notIn |
NOT IN 查詢 |
isNull |
NULL 值查詢 |
isNotNull |
IS NOT NULL |
groupBy |
分組 GROUP BY |
having |
HAVING 關鍵詞 |
orderBy |
排序 ORDER BY |
orderAsc |
ASC 排序 ORDER BY |
orderDesc |
DESC 排序 ORDER BY |
exists |
EXISTS 條件語句 |
notExists |
NOT EXISTS 條件語句 |
between |
BETWEEN 條件語句 |
notBetween |
NOT BETWEEN 條件語句 |
addFilter |
自由拼接 SQL |
last |
拼接在最后,例如:last(“LIMIT 1”) |