<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本篇的主要程式碼依賴於之前的通用Mapper和通用Service篇
在我們平時的日常開發中,會經常遇到我們的資料小夥伴們在資料庫中所建立的 表名要與我們Java開發人員所建的domian層的類名有一個對應關係
,這往往在不同的公司都有著不同的要求。
打個比方:資料庫表名 t_user
-------- 後臺domian的實體類名User
。這樣很明顯會操做報錯。
所以我們的MyBtais-Plus為我們提供了一系列的註解,下面我們來正式學習他們
在實體類上加上註解@TableName("t_user")
,標識這個類所對應的表名是t_user,這樣才可以成功對映到對應的欄位。
@TableName("t_user") public class User { private Long id; private String userName; private Integer age; private String email; }
以上是通過註解的方式完成,我們也可以通過組態檔來設定
mybatis-plus: configuration: # 設定MyBatis紀錄檔 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: # 設定MyBatis-Plus操作表的預設字首 table-prefix: t_
通過table_prefix設定字首隻適用於資料庫表有字首的,如果表名與實體類名差別甚遠,則建議使用註解
MyBatis-Plus在實現CRUD時,會預設將id作為主鍵列,並在插入資料時,預設是基於雪花演演算法的策略生成id
ASSIGN_ID
【產生的問題】
【對策】
在實體類中uid屬性上通過@TableId將其標識為主鍵
,即可成功執行SQL語句
@TableName("t_user") public class User { @TableId(value = "id", type = IdType.AUTO) private Long id; private String userName; private Integer age; private String email; }
這裡有必要說下,idType,這個IdType
是MyBatis-plus裡面所提供的一種主鍵生成策略的列舉類
【原始碼】
@Getter public enum IdType { /** * 資料庫ID自增 * <p>該型別請確保資料庫設定了 ID自增 否則無效</p> */ AUTO(0), /** * 該型別為未設定主鍵型別(註解裡等於跟隨全域性,全域性里約等於 INPUT) */ NONE(1), /** * 使用者輸入ID * <p>該型別可以通過自己註冊自動填充外掛進行填充</p> */ INPUT(2), /* 以下3種型別、只有當插入物件ID 為空,才自動填充。 */ /** * 分配ID (主鍵型別為number或string), * 預設實現類 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(雪花演演算法) * * @since 3.3.0 */ ASSIGN_ID(3), /** * 分配UUID (主鍵型別為 string) * 預設實現類 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(UUID.replace("-","")) */ ASSIGN_UUID(4); private final int key; IdType(int key) { this.key = key; } }
也就是說MP提供了5種測類,下面簡要的介紹其中的某些:
AUTO:
資料庫自增策略,注意,該型別請確保資料庫設定了id自增, 否則無效
TableField與TableId的區別就是:
@TableName("t_user") public class User { // 處理主鍵相關的欄位名不一致 以及設定主鍵自增策略 @TableId(value = "id", type = IdType.AUTO) private Long id; // 在mp種預設的設定可以將資料庫中的欄位名xxx_xxx轉化為相應的駝峰命名 @TableField(value = "user_name") private String userName; @TableField(value = "age") private Integer age; // exist=false 表示查詢時候不顯示 @TableField(exist = false) private String email; }
當我們使用了@TableField(exist = false)
則在查詢的時候就不會顯示查詢出來的值
邏輯刪除
在我們的日常開發中,會經常遇到這種邏輯刪除的操做,因為這樣仍然會在資料庫中儲存這條資料,防止後期如果還想用的話還可以找到。我們要時刻銘記,資料的CUD操做,一定要謹慎,謹慎,再謹慎!!!
如果我們的業務對資料的要求是可以恢復的,我們就要使用邏輯刪除操做,一般我們就在資料庫種加一個欄位is_deleted
物理刪除
:真實刪除,將對應資料從資料庫中刪除,之後查詢不到此條被刪除的資料邏輯刪除
:假刪除,將對應資料中代表是否被刪除欄位的狀態修改為“被刪除狀態”,之後在資料庫中仍舊能看到此條資料記錄@TableName("t_user") public class User { // 處理主鍵相關的欄位名不一致 以及設定主鍵自增策略 @TableId(value = "id", type = IdType.AUTO) private Long id; // 在mp種預設的設定可以將資料庫中的欄位名xxx_xxx轉化為相應的駝峰命名 @TableField(value = "user_name") private String userName; @TableField(value = "age") private Integer age; @TableField(value = "email") private String email; // 邏輯刪除 0 標識未刪除 1表示刪除了 @TableLogic private Integer isDeleted; }
注意:
當我們使用了邏輯刪除則刪除操作就變成了修改操作
測試刪除功能,真正執行的是修改
UPDATE t_user SET is_deleted=1 WHERE id=? AND is_deleted=0
測試查詢功能,被邏輯刪除的資料預設不會被查詢
SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0
Wrapper在MyBatis-plus裡面主要分為兩種:一種適用於查詢的 QueryWrapper;一種是用於修改的UpdateWrapper
【繼承關係】
Wrapper : 條件構造抽象類,最頂端父類別
這裡主要就是介紹QueryWrapper和UpdateWrapper
上圖是BaseMapper裡面的關於引數是Warpper的方法,下面我們一一介紹:
2.1.1 組裝查詢條件selectCount
/** * 測試wraper封裝查詢條件1 * * @throws Exception */ @Test public void testQuery5() { QueryWrapper<User> queryWrapper = new QueryWrapper<User>(); // sql: SELECT COUNT( * ) FROM t_user WHERE is_deleted=0 AND (age BETWEEN ? AND // ?) queryWrapper.between("age", 18, 23); Long list = userMapper.selectCount(queryWrapper); System.out.println(list); }
2.1.2 組裝查詢條件selectList
/** * 測試wraper封裝查詢條件2 * * @throws Exception */ @Test public void testQuery9() { QueryWrapper<User> queryWrapper = new QueryWrapper<User>(); // SELECT id,user_name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND // (email IS NOT NULL AND email LIKE ?) queryWrapper.isNotNull("email").like("email", "163.com"); List<User> list = userMapper.selectList(queryWrapper); list.forEach(System.out::println); }
2.1.3 組裝查詢引數selectMaps
/** * 測試wraper封裝查詢條件3 * * @throws Exception */ @Test public void testQuery10() { QueryWrapper<User> queryWrapper = new QueryWrapper<User>(); // SELECT age,email,user_name FROM t_user WHERE is_deleted=0 queryWrapper.select("age", "email", "user_name"); List<Map<String, Object>> list = userMapper.selectMaps(queryWrapper); list.forEach(System.out::println); }
2.1.4 組裝查詢selectOne
/** * 測試wraper封裝查詢條件4 * * @throws Exception */ @Test public void testQuery11() { QueryWrapper<User> queryWrapper = new QueryWrapper<User>(); // SELECT age,email,user_name FROM t_user WHERE is_deleted=0 AND (user_name = ?) queryWrapper.select("age", "email", "user_name"); queryWrapper.eq("user_name", "test"); User list = userMapper.selectOne(queryWrapper); System.out.println(list); }
根據上述的方法,我們可以很輕鬆地觀察到,querywrapper裡面封裝了許多的方法就是用於設定我們的查詢條件,而且比較通俗易懂,比如ge大於等於
,between介於
等等,這裡只演示這些,剩下的自己在開發中用到繼續摸索。
2.1.5 調整條件優先順序
注意:
這裡說明下如何調整引數的優先順序
,我們都知道在sql中可以通過()完成查詢條件的優先順序提升,那麼在MP中如何操做???
【程式碼演示】
通過and方法,利用lambda表示式實現
@Test public void testQuery7() throws Exception { User user = new User(); // 將使用者名稱中包含有a並且(年齡大於20或郵箱為null)的使用者資訊修改 user.setEmail("modifyTest@gogel.com"); QueryWrapper<User> queryWrapper = new QueryWrapper<User>(); // UPDATE t_user SET age=?, email=? WHERE (user_name LIKE ? AND (age > ? OR email IS NULL)) queryWrapper.like("user_name", "a") .and( i -> i.ge("age", 20) .or() .isNull("email")); List<User> list = userMapper.selectList(queryWrapper); list.forEach(System.out::println); }
2.1.6 實現子查詢inSql
@GetMapping("/queryZI") public List<User> queryZI() { // SELECT id,user_name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (id IN ( SELECT id FROM t_user WHERE id <=100)) QueryWrapper<User> queryWrapper = new QueryWrapper<User>(); queryWrapper.inSql("id", " SELECT id FROM t_user WHERE id <=100"); List<User> maps = userMapper.selectList(queryWrapper); return maps; }
2.2.1 組裝修改條件update
@Test public void testUpdate2() throws Exception { User user = new User(); user.setEmail("modifyTest@gogel.com"); UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>(); updateWrapper.ge("age", 20).like("user_name", "a").or().isNull("email"); /** * 根據 whereEntity 條件,更新記錄 * * @param entity 實體物件 (set 條件值,可以為 null) 修改的引數 * @param updateWrapper 實體物件封裝操作類(可以為 null,裡面的 entity 用於生成 where 語句)條件引數 */ int row = userMapper.update(user, updateWrapper); log.info("刪除資料={}條", row); }
MyBatis Plus自帶分頁外掛,只要簡單的設定即可實現分頁功能
1️⃣新增設定類
/** * MybatisPlus的分頁外掛設定類 * @author wangruoxian * */ @Configuration @MapperScan("com.wei.mapper") public class MyBatisPlusPageConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }
2️⃣ 測試
@GetMapping("/page") public IPage<User> pageList(){ Page<User> page = new Page<User>(1,3); // QueryWrapper<User> queryWrapper = new QueryWrapper<User>(); // // 當前頁碼 // page.setCurrent(1); // // 每頁顯示的條數 // page.setSize(5); IPage<User> selectPage = userMapper.selectPage(page, null); log.info("當前頁數={}",selectPage.getCurrent()); log.info("總頁數={}",selectPage.getPages()); selectPage.getRecords().forEach(System.out::println); log.info("每頁大小={}",selectPage.getSize()); log.info("總資料條數={}",selectPage.getTotal()); return selectPage; }
表中的有些欄位值是固定的,例如性別(男或女),此時我們可以使用MyBatis-Plus的通用列舉來實現
4.2 設定掃描通用列舉
# 設定掃描通用列舉 type-enums-package: com.wei.enums
4.3 新建列舉類
@Getter public enum SexEnum { MALE(0,"男"), FEMALE(1,"女"); @EnumValue private Integer sexCode; private String sexValue; private SexEnum(Integer sexCode, String sexValue) { this.sexCode = sexCode; this.sexValue = sexValue; } }
4.3.1 @EnumValue註解
通用的列舉類註解,將資料庫欄位對映成實體類的列舉型別成員變數
將列舉改成成員變數和資料庫的欄位對映起來,根據資料庫欄位的值找到對應列舉的物件
適用於多種場景:純粹多庫、 讀寫分離、 一主多從、 混合模式等
,目前我們就來模擬一個純粹多庫的一個場景,其他場景類似
場景說明:
我們建立兩個庫,分別為:mybatis_plus(以前的庫不動)與mybatis_plus_1(新建),將
mybatis_plus庫的product表移動到mybatis_plus_1庫,這樣每個庫一張表,通過一個測試用例
分別獲取使用者資料與商品資料,如果獲取到說明多庫模擬成功
CREATE DATABASE `mybatis_plus_slave` use `mybatis_plus_slave`; CREATE TABLE t_product ( id BIGINT(20) NOT NULL COMMENT '主鍵ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名稱', price INT(11) DEFAULT 0 COMMENT '價格', version INT(11) DEFAULT 0 COMMENT '樂觀鎖版本號', PRIMARY KEY (id) ); INSERT INTO product (id, NAME, price) VALUES (1, '外星人筆電', 100);
5.2 引入依賴
<!-- 引入依賴 多資料來源 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.3.1</version> </dependency>
注意
註釋掉之前的設定 ,也可以新建一個專案進行測試
spring: # 設定資料來源資訊 datasource: dynamic: # 設定預設的資料來源或者資料來源組,預設值即為master primary: master # 嚴格匹配資料來源,預設false.true未匹配到指定資料來源時拋異常,false使用預設資料來源 strict: false datasource: master: url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 slave_1: url: jdbc:mysql://localhost:3306/mybatis_plus_1?characterEncoding=utf-8&useSSL=false driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456
此處省略domain,mapper,service,serviceImpl的建立
【controller層】
@RestController @RequestMapping("/product") @Api(value = "測試 ProductController 的介面", tags = "產品管理相關的介面", description = "product產品測試介面") public class ProductController { @Autowired private IProductService IProductService; @GetMapping("/list") // @ApiOperation("查詢所有商品的介面") public List<Product> queryAllProduct(){ return IProductService.list(); } }
到此這篇關於MyBatis-Plus 條件查詢器的實現的文章就介紹到這了,更多相關MyBatis-Plus 條件查詢器內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45