MyBatis-Flex BaseMapper的接口基本用法小結(jié)
MyBatis-Flex簡(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ò)的可能性。
總而言之,MyBatis-Flex 能夠極大地提高我們的開(kāi)發(fā)效率和開(kāi)發(fā)體驗(yàn),讓我們有更多的時(shí)間專注于自己的事情。
特性
1、輕量
除了 MyBatis,沒(méi)有任何第三方依賴輕依賴、沒(méi)有任何攔截器,其原理是通過(guò) SqlProvider 的方式實(shí)現(xiàn)的輕實(shí)現(xiàn)。同時(shí),在執(zhí)行的過(guò)程中,沒(méi)有任何的 Sql 解析(Parse)輕運(yùn)行。 這帶來(lái)了幾個(gè)好處:1、極高的性能;2、極易對(duì)代碼進(jìn)行跟蹤和調(diào)試; 3、更高的把控性。
2、靈活
支持 Entity 的增刪改查、以及分頁(yè)查詢的同時(shí),MyBatis-Flex 提供了 Db + Row^靈活 工具,可以無(wú)需實(shí)體類(lèi)對(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ù)填充 等等功能。
基礎(chǔ)方法
INSERT
BaseMapper 的接口提供了 insert 和 insertBatch 方法,用于新增數(shù)據(jù)。
- insert(entity):插入實(shí)體類(lèi)數(shù)據(jù),不忽略 null 值。
- insertSelective(entity):插入實(shí)體類(lèi)數(shù)據(jù),但是忽略 null 的數(shù)據(jù),只對(duì)有值的內(nèi)容進(jìn)行插入。這樣的好處是數(shù)據(jù)庫(kù)已經(jīng)配置了一些默認(rèn)值,這些默認(rèn)值才會(huì)生效。
- insert(entity, ignoreNulls):插入實(shí)體類(lèi)數(shù)據(jù)。
- insertWithPk(entity):插入帶有主鍵的實(shí)體類(lèi),不忽略 null 值。
- insertSelectiveWithPk(entity):插入帶有主鍵的實(shí)體類(lèi),忽略 null 值。
- insertWithPk(entity, ignoreNulls):帶有主鍵的插入,此時(shí)實(shí)體類(lèi)不會(huì)經(jīng)過(guò)主鍵生成器生成主鍵。
- insertBatch(entities):批量插入實(shí)體類(lèi)數(shù)據(jù),只會(huì)根據(jù)第一條數(shù)據(jù)來(lái)構(gòu)建插入的字段內(nèi)容。
- insertBatch(entities, size):批量插入實(shí)體類(lèi)數(shù)據(jù),按 size 切分。
- insertOrUpdate(entity):插入或者更新,若主鍵有值,則更新,若沒(méi)有主鍵值,則插入,插入或者更新都不會(huì)忽略 null 值。
- insertOrUpdateSelective(entity):插入或者更新,若主鍵有值,則更新,若沒(méi)有主鍵值,則插入,插入或者更新都會(huì)忽略 null 值。
- insertOrUpdate(entity, ignoreNulls):插入或者更新,若主鍵有值,則更新,若沒(méi)有主鍵值,則插入。
① insert
/** * insert(entity):插入實(shí)體類(lèi)數(shù)據(jù),不忽略 null 值。 * insert(entity, ignoreNulls):插入實(shí)體類(lèi)數(shù)據(jù)。 */ @Test public void testInsert() { /** * 默認(rèn)不忽略null值 * INSERT INTO `tb_account`(`user_name`, `age`, `birthday`) VALUES (?, ?, ?) */ int row = accountMapper.insert(new Account().setUserName(null).setBirthday(new Date()).setAge(25)); Assertions.assertEquals(row, 1); /** * ignoreNulls true:忽略null , false:不忽略null * INSERT INTO `tb_account`(`user_name`) VALUES (?) */ int row2 = accountMapper.insert(new Account().setUserName("ly3").setBirthday(null).setAge(null), true); Assertions.assertEquals(row2, 1); }
② insertSelective
/** * insertSelective(entity):插入實(shí)體類(lèi)數(shù)據(jù),但是忽略 null 的數(shù)據(jù),只對(duì)有值的內(nèi)容進(jìn)行插入。這樣的好處是數(shù)據(jù)庫(kù)已經(jīng)配置了一些默認(rèn)值,這些默認(rèn)值才會(huì)生效。 */ @Test public void testInsertSelective() { /** * INSERT INTO `tb_account`(`user_name`) VALUES (?) */ int row = accountMapper.insertSelective(new Account().setUserName("陳遠(yuǎn)航").setAge(null)); Assertions.assertEquals(row, 1); }
③ insertWithPk
/** * insertWithPk(entity):插入帶有主鍵的實(shí)體類(lèi),不忽略 null 值。 */ @Test public void testInsertWithPk() { /** * INSERT INTO `tb_account`(`id`, `user_name`, `age`, `birthday`) VALUES (?, ?, ?, ?) */ int row = accountMapper.insertWithPk(new Account().setUserName("廖楷瑞").setId(5L).setBirthday(null)); Assertions.assertEquals(row, 1); }
④ insertBatch
/** * insertBatch(entities):批量插入實(shí)體類(lèi)數(shù)據(jù),只會(huì)根據(jù)第一條數(shù)據(jù)來(lái)構(gòu)建插入的字段內(nèi)容。 * insertBatch(entities, size):批量插入實(shí)體類(lèi)數(shù)據(jù),按 size 切分。 */ @Test public void testInsertBatch() { List<Account> accounts = new ArrayList<>(10); for (int i = 0; i < 10; i++) { Account account = new Account().setUserName("ly" + i).setBirthday(new Date()).setAge(20 + i); accounts.add(account); } /** * 批量插入,可以指定每次插入的數(shù)據(jù)大小size * size=2 : INSERT INTO `tb_account`(`user_name`, `age`, `birthday`) VALUES (?, ?, ?), (?, ?, ?) * size=3 : INSERT INTO `tb_account`(`user_name`, `age`, `birthday`) VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?) * ...... */ int rows = accountMapper.insertBatch(accounts, 2); System.out.println("rows = " + rows); }
⑤ insertOrUpdate
/** * insertOrUpdate(entity):插入或者更新,若主鍵有值,則更新,若沒(méi)有主鍵值,則插入,插入或者更新都不會(huì)忽略 null 值。 * insertOrUpdateSelective(entity):插入或者更新,若主鍵有值,則更新,若沒(méi)有主鍵值,則插入,插入或者更新都會(huì)忽略 null 值。 * insertOrUpdate(entity, ignoreNulls):插入或者更新,若主鍵有值,則更新,若沒(méi)有主鍵值,則插入。 */ @Test public void testInsertOrUpdate() { Account account = new Account().setUserName("ly-update2").setId(3L).setBirthday(new Date()).setAge(21); /** * UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ? */ int row = accountMapper.insertOrUpdate(account); Assertions.assertEquals(row, 0, 1); account = new Account().setUserName("ly-update2").setBirthday(null).setAge(21); /** * INSERT INTO `tb_account`(`user_name`, `age`) VALUES (?, ?) */ int row2 = accountMapper.insertOrUpdateSelective(account); Assertions.assertEquals(row2, 0, 1); }
DELETE
BaseMapper 的接口提供了 deleteById、deleteBatchByIds、deleteByMap、deleteByQuery 方法,用于刪除數(shù)據(jù);
- deleteById(id):根據(jù)主鍵刪除數(shù)據(jù)。如果是多個(gè)主鍵的情況下,需要傳入數(shù)組,例如:new Integer[]{100,101}。
- deleteBatchByIds(ids):根據(jù)多個(gè)主鍵批量刪除數(shù)據(jù)。
- deleteBatchByIds(ids, size):根據(jù)多個(gè)主鍵批量刪除數(shù)據(jù)。
- deleteByMap(whereConditions):根據(jù) Map 構(gòu)建的條件來(lái)刪除數(shù)據(jù)。
- deleteByCondition(whereConditions):根據(jù)查詢條件來(lái)刪除數(shù)據(jù)。
- deleteByQuery(queryWrapper):根據(jù)查詢條件來(lái)刪除數(shù)據(jù)。
① deleteById
/** * deleteById(id):根據(jù)主鍵刪除數(shù)據(jù)。 * ??? 如果是多個(gè)主鍵的情況下,需要傳入數(shù)組,例如:new Integer[]{100,101}。 ??? 懷疑態(tài)度 */ @Test public void testDeleteById() { /** * DELETE FROM `tb_account` WHERE `id` = ? */ int row = accountMapper.deleteById(9L); Assertions.assertTrue(row > 0); }
② deleteBatchByIds
/** * deleteBatchByIds(ids):根據(jù)多個(gè)主鍵批量刪除數(shù)據(jù)。 * deleteBatchByIds(ids, size):根據(jù)多個(gè)主鍵批量刪除數(shù)據(jù)。 */ @Test public void testDeleteBatchByIds() { List<Integer> ids = List.of(5, 6, 7, 8); /** * DELETE FROM `tb_account` WHERE `id` = ? OR `id` = ? OR `id` = ? OR `id` = ? */ int rows = accountMapper.deleteBatchByIds(ids); Assertions.assertTrue(rows > 0); /** * 分批刪除 * size=2 : DELETE FROM `tb_account` WHERE `id` = ? OR `id` = ? */ int rows2 = accountMapper.deleteBatchByIds(ids, 2); Assertions.assertTrue(rows2 > 0); }
③ deleteByMap
/** * deleteByMap(whereConditions):根據(jù) Map 構(gòu)建的條件來(lái)刪除數(shù)據(jù)。 */ @Test public void testDeleteByMap() { /** * DELETE FROM `tb_account` WHERE `tb_account`.`age` = ? */ int rows = accountMapper.deleteByMap(Map.of("age", 25)); Assertions.assertTrue(rows > 0); }
④ deleteByCondition
/** * deleteByCondition(whereConditions):根據(jù)查詢條件來(lái)刪除數(shù)據(jù)。 */ @Test public void testDeleteByCondition() { QueryCondition condition = QueryCondition.createEmpty().and("age = 27"); /** * DELETE FROM `tb_account` WHERE age = 27 */ int rows = accountMapper.deleteByCondition(condition); Assertions.assertTrue(rows > 0); /** * DELETE FROM `tb_account` WHERE `id` > ? */ int rows2 = accountMapper.deleteByCondition(ACCOUNT.ID.gt(35)); Assertions.assertTrue(rows2 > 0); }
⑤ deleteByQuery
/** * deleteByQuery(queryWrapper):根據(jù)查詢條件來(lái)刪除數(shù)據(jù)。 */ @Test public void testDeleteByQuery() { /** * DELETE FROM `tb_account` WHERE `age` >= ? */ QueryWrapper wrapper = QueryWrapper.create().where(ACCOUNT.AGE.ge(32)); int rows = accountMapper.deleteByQuery(wrapper); Assertions.assertTrue(rows > 0); }
UPDATE
BaseMapper 的接口提供了 update、updateByMap、updateByQuery 方法,用于更新數(shù)據(jù);
- update(entity):根據(jù)主鍵來(lái)更新數(shù)據(jù),若實(shí)體類(lèi)屬性數(shù)據(jù)為 null,該屬性不會(huì)新到數(shù)據(jù)庫(kù)。
- update(entity, ignoreNulls):根據(jù)主鍵來(lái)更新數(shù)據(jù)到數(shù)據(jù)庫(kù)。
- updateByMap(entity, whereConditions):根據(jù) Map 構(gòu)建的條件來(lái)更新數(shù)據(jù)。
- updateByMap(entity, ignoreNulls, whereConditions):根據(jù) Map 構(gòu)建的條件來(lái)更新數(shù)據(jù)。
- updateByCondition(entity, whereConditions):根據(jù)查詢條件來(lái)更新數(shù)據(jù)。
- updateByCondition(entity, ignoreNulls, whereConditions):根據(jù)查詢條件來(lái)更新數(shù)據(jù)。
- updateByQuery(entity, queryWrapper):根據(jù)查詢條件來(lái)更新數(shù)據(jù)。
- updateByQuery(entity, ignoreNulls, queryWrapper):根據(jù)查詢條件來(lái)更新數(shù)據(jù)。
① update
@Test public void testUpdate() { Account account = new Account().setId(5L) .setAge(39) .setUserName("測(cè)試修改") .setBirthday(new Date(2023, Calendar.SEPTEMBER, 6, 12, 12, 12)); /** * UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ? */ int rows = accountMapper.update(account); Assertions.assertTrue(rows > 0); } @Test public void testUpdateIgnoreNulls() { Account account = new Account().setId(6L) .setAge(null) .setUserName(null) .setBirthday(new Date(2023, Calendar.SEPTEMBER, 6, 12, 12, 12)); /** * 不忽略null值 * UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ? */ int rows = accountMapper.update(account, false); System.out.println("rows = " + rows); }
② updateByMap
@Test public void testUpdateByMap() { Account account = new Account() .setId(7L) // 不生效 .setUserName("updateByMap") .setAge(24) .setBirthday(null); // 注意:這樣更新實(shí)體類(lèi)的id是不生效的 Map<String, Object> whereCondition = Map.of("id", 13); /** * 忽略null * UPDATE `tb_account` SET `user_name` = ? , `age` = ? WHERE `id` = ? */ accountMapper.updateByMap(account, whereCondition); /** * 不忽略null * UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ? */ accountMapper.updateByMap(account, false, whereCondition); }
③ updateByCondition
/** * updateByCondition(entity, whereConditions):根據(jù)查詢條件來(lái)更新數(shù)據(jù)。 * updateByCondition(entity, ignoreNulls, whereConditions):根據(jù)查詢條件來(lái)更新數(shù)據(jù)。 */ @Test public void testUpdateByCondition() { Account account = new Account() .setId(8L) .setUserName("updateByCondition") .setBirthday(DateUtil.toDate(LocalDateTime.now())); QueryCondition condition = QueryCondition.create(new QueryColumn("id"), SqlConsts.EQUALS, 8); /** * 忽略null * UPDATE `tb_account` SET `user_name` = ? , `birthday` = ? WHERE `id` = ? */ accountMapper.updateByCondition(account, condition); /** * 不忽略null * UPDATE `tb_account` SET `user_name` = ? , `age` = ? , `birthday` = ? WHERE `id` = ? */ accountMapper.updateByCondition(account, false, condition); }
④ updateByQuery
/** * updateByQuery(entity, queryWrapper):根據(jù)查詢條件來(lái)更新數(shù)據(jù)。 * updateByQuery(entity, ignoreNulls, queryWrapper):根據(jù)查詢條件來(lái)更新數(shù)據(jù)。 */ @Test public void testUpdateByQuery() { Account account = new Account().setUserName("updateByQuery"); /** * UPDATE `tb_account` SET `user_name` = ? WHERE `id` = ? */ accountMapper.updateByQuery(account, QueryWrapper.create().where(ACCOUNT.ID.eq(9L))); }
⑤ UpdateEntity部分字段更新
@Test public void testUpdateEntity1() { Account account = UpdateEntity.of(Account.class, 10L); /** * 官方說(shuō)明:通過(guò) UpdateEntity 創(chuàng)建的對(duì)象,只會(huì)更新調(diào)用了 setter 方法的字段,若不調(diào)用 setter 方法,不管這個(gè)對(duì)象里的屬性的值是什么,都不會(huì)更新到數(shù)據(jù)庫(kù)。 */ account.setAge(66) .setUserName("UpdateEntity") .setBirthday(null); accountMapper.update(account); } @Test public void testUpdateEntity2() { Account account = new Account() .setId(10L) .setUserName("UpdateEntity2"); UpdateWrapper wrapper = UpdateWrapper.of(account); // wrapper.set(ACCOUNT.AGE, ACCOUNT.AGE.add(1)); wrapper.setRaw("age", "age + 1"); accountMapper.update(account); } @Test public void testUpdateEntity3() { Account account = new Account() .setId(10L) .setUserName("UpdateEntity2"); UpdateWrapper wrapper = UpdateWrapper.of(account); // wrapper.set(ACCOUNT.AGE, ACCOUNT.AGE.add(1)); wrapper.setRaw(ACCOUNT.AGE, "select * from t_account where id = 3"); // accountMapper.updateByCondition(account, wrapper); }
⑥ UpdateChain
@Test public void testUpdateChain() { /** * UPDATE `tb_account` SET `birthday` = ? , `age` = age + 1 WHERE `age` = ? */ UpdateChain.of(Account.class) .set(Account::getBirthday, new Date()) .setRaw(Account::getAge, "age + 1") .where(ACCOUNT.AGE.eq(11)).update(); }
set() 和 setRaw() 的區(qū)別在 Row、UpdateWrapper、UpdateChain 中,都提供了 set() 和 setRaw() 兩個(gè)方法用于設(shè)置數(shù)據(jù)。 那么,它們有什么區(qū)別呢?
- set() 方法用于設(shè)置參數(shù)數(shù)據(jù)。
- setRaw() 用于設(shè)置 SQL 拼接數(shù)據(jù)。
舉個(gè)例子,
//更新數(shù)據(jù) UpdateChain.of(Account.class) .set(Account::getAge, ACCOUNT.AGE.add(1)) .where(Account::getId).ge(100) .and(Account::getAge).eq(18) .update();
通過(guò) UpdateChain 進(jìn)行 update(),其執(zhí)行的 SQL 如下:
UPDATE `tb_account` SET `age` = `age` + 1 WHERE `id` >= 100 AND `age` = 18
到此這篇關(guān)于MyBatis-Flex BaseMapper的接口基本用法小結(jié)的文章就介紹到這了,更多相關(guān)MyBatis-Flex BaseMapper接口用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis-Flex 邏輯刪除的用法小結(jié)
- MyBatis-Flex實(shí)現(xiàn)分頁(yè)查詢的示例代碼
- Mybatis-flex整合達(dá)夢(mèng)數(shù)據(jù)庫(kù)的實(shí)現(xiàn)示例
- Spring Boot整合MyBatis-Flex全過(guò)程
- springboot3.0整合mybatis-flex實(shí)現(xiàn)逆向工程的示例代碼
- mybatis-flex實(shí)現(xiàn)鏈?zhǔn)讲僮鞯氖纠a
- MyBatis-Flex實(shí)現(xiàn)多表聯(lián)查(自動(dòng)映射)
- Mybatis增強(qiáng)版MyBatis-Flex的具體使用
- mybatis-flex與springBoot整合的實(shí)現(xiàn)示例
相關(guān)文章
javaweb項(xiàng)目如何實(shí)現(xiàn)手機(jī)短信登錄
這篇文章主要介紹了javaweb項(xiàng)目如何實(shí)現(xiàn)手機(jī)短信登錄,手機(jī)號(hào)登錄在現(xiàn)在的項(xiàng)目中用的場(chǎng)景非常多,實(shí)現(xiàn)起來(lái)也不難,今天我們就一起來(lái)通過(guò)演示實(shí)現(xiàn)登錄過(guò)程,需要的朋友可以參考下2019-07-07Mybatis-Plus支持GBase8s分頁(yè)查詢的實(shí)現(xiàn)示例
本文主要介紹了使?Mybatis-Plus?支持?GBase8s?的分頁(yè)查詢,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01RxJava+Retrofit+Mvp實(shí)現(xiàn)購(gòu)物車(chē)
這篇文章主要為大家詳細(xì)介紹了RxJava+Retrofit+Mvp實(shí)現(xiàn)購(gòu)物車(chē)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05淺談springMVC接收前端json數(shù)據(jù)的總結(jié)
下面小編就為大家分享一篇淺談springMVC接收前端json數(shù)據(jù)的總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03spring?boot?Mybatis?攔截器實(shí)現(xiàn)拼接sql和修改的代碼詳解
這篇文章主要介紹了spring?boot?Mybatis?攔截器實(shí)現(xiàn)拼接sql和修改,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05Java實(shí)現(xiàn)從jar包中讀取指定文件的方法
這篇文章主要介紹了Java實(shí)現(xiàn)從jar包中讀取指定文件的方法,涉及java針對(duì)jar文件的讀取及查找相關(guān)操作技巧,需要的朋友可以參考下2017-08-08Java中volatile關(guān)鍵字的作用是什么舉例詳解
這篇文章主要介紹了Java中volatile關(guān)鍵字的作用是什么的相關(guān)資料,volatile關(guān)鍵字在Java中用于修飾變量,提供可見(jiàn)性和禁止指令重排的特性,但不保證原子性,它通過(guò)內(nèi)存屏障實(shí)現(xiàn)這些特性,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-04-04Java數(shù)組轉(zhuǎn)List及Stream的基本方法使用方法
Java?的?Stream?流操作是一種簡(jiǎn)潔而強(qiáng)大的處理集合數(shù)據(jù)的方式,允許對(duì)數(shù)據(jù)進(jìn)行高效的操作,如過(guò)濾、映射、排序和聚合,這篇文章主要介紹了Java數(shù)組轉(zhuǎn)List及Stream的基本方法使用教程,需要的朋友可以參考下2024-08-08