MyBatis-Plus聯(lián)表查詢(xún)以及分頁(yè)代碼實(shí)例
一、準(zhǔn)備工作
mybatis-plus作為mybatis的增強(qiáng)工具,它的出現(xiàn)極大的簡(jiǎn)化了開(kāi)發(fā)中的數(shù)據(jù)庫(kù)操作,但是長(zhǎng)久以來(lái),它的聯(lián)表查詢(xún)能力一直被大家所詬病。一旦遇到left join或right join的左右連接,你還是得老老實(shí)實(shí)的打開(kāi)xml文件,手寫(xiě)上一大段的sql語(yǔ)句。
直到前幾天,偶然碰到了這么一款叫做mybatis-plus-join的工具(后面就簡(jiǎn)稱(chēng)mpj了),使用了一下,不得不說(shuō)真香!徹底將我從xml地獄中解放了出來(lái),終于可以以類(lèi)似mybatis-plus中QueryWrapper的方式來(lái)進(jìn)行聯(lián)表查詢(xún)了,話不多說(shuō),我們下面開(kāi)始體驗(yàn)。
- mapper繼承MPJBaseMapper (必選)
- service繼承MPJBaseService (可選)
- serviceImpl繼承MPJBaseServiceImpl (可選)
1、數(shù)據(jù)庫(kù)結(jié)構(gòu)以及數(shù)據(jù)
CREATE TABLE `op_product` ( `id` int(11) NOT NULL AUTO_INCREMENT, `type` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; INSERT INTO `test_yjdsns`.`op_product`(`id`, `type`) VALUES (1, '蘋(píng)果'); CREATE TABLE `op_product_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, `product_id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, `price` decimal(10,2) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; INSERT INTO `test_yjdsns`.`op_product_info`(`id`, `product_id`, `name`, `price`) VALUES (1, 1, '蘋(píng)果13', 8.00); INSERT INTO `test_yjdsns`.`op_product_info`(`id`, `product_id`, `name`, `price`) VALUES (2, 1, '蘋(píng)果15', 9.00);
2、依賴(lài)
<dependency> <groupId>com.github.yulichang</groupId> <artifactId>mybatis-plus-join</artifactId> <version>1.2.4</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency>
3、配置類(lèi)讓mybatis-plus-join在DataScopeSqlInjector中生效
/** * @author licy * @description * @date 2022/10/20 */ @Configuration public class MybatisPlusConfig { /** * 新增分頁(yè)攔截器,并設(shè)置數(shù)據(jù)庫(kù)類(lèi)型為mysql * * @return */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); //分頁(yè)插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } /** * sql注入 */ @Bean @Primary public MySqlInjector myLogicSqlInjector() { return new MySqlInjector(); } }
修改DataScopeSqlInjector中的繼承類(lèi)為:MPJSqlInjector
public class MySqlInjector extends MPJSqlInjector { @Override public List<AbstractMethod> getMethodList(Class<?> mapperClass) { //將原來(lái)的保持 List<AbstractMethod> methodList = super.getMethodList(mapperClass); //多表查詢(xún)sql注入 從連表插件里移植過(guò)來(lái)的 methodList.add(new SelectJoinOne()); methodList.add(new SelectJoinList()); methodList.add(new SelectJoinPage()); methodList.add(new SelectJoinMap()); methodList.add(new SelectJoinMaps()); methodList.add(new SelectJoinMapsPage()); return methodList; } }
4、啟動(dòng)類(lèi)排除MPJSqlInjector.class
@SpringBootApplication(exclude = {MPJSqlInjector.class})
載入自定義配置類(lèi)
@Configuration
@MapperScan可以選擇tk下的路徑
import tk.mybatis.spring.annotation.MapperScan;
二、代碼
1、實(shí)體類(lèi)
/** * @author licy * @description * @date 2022/10/25 */ @Data @NoArgsConstructor @AllArgsConstructor @TableName("op_product") public class OpProduct implements Serializable { private static final long serialVersionUID = -3918932563888251866L; @TableId(value = "ID", type = IdType.AUTO) private Long id; @TableField("TYPE") private String type; }
/** * @author licy * @description * @date 2022/10/25 */ @Data @NoArgsConstructor @AllArgsConstructor @TableName("op_product_info") public class OpProductInfo implements Serializable { private static final long serialVersionUID = 4186082342917210485L; @TableId(value = "ID", type = IdType.AUTO) private Long id; @TableField("PRODUCT_ID") private Long productId; @TableField("NAME") private String name; @TableField("PRICE") private Double price; }
/** * @author licy * @description * @date 2022/10/25 */ @Data @NoArgsConstructor @AllArgsConstructor public class ProductDTO implements Serializable { private static final long serialVersionUID = -2281333877153304329L; private Long id; private String type; private String name; private Double price; }
2、Mapper
/** * @author licy * @description * @date 2022/10/26 */ public interface OpProductInfoMapper extends MPJBaseMapper<OpProductInfo> { }
/** * @author licy * @description * @date 2022/10/25 */ public interface OpProductMapper extends MPJBaseMapper<OpProduct> { }
3、Service
Mapper接口改造完成后,我們把它注入到Service中,雖然說(shuō)我們要完成3張表的聯(lián)表查詢(xún),但是以O(shè)pProduct作為主表的話,那么只注入這一個(gè)對(duì)應(yīng)的OpProductMapper就可以,非常簡(jiǎn)單。
public interface OpProductService extends MPJBaseService<OpProduct> { List<ProductDTO> queryAllProduct(); }
@Service @Slf4j @AllArgsConstructor public class OpProductServiceImpl extends MPJBaseServiceImpl<OpProductMapper, OpProduct> implements OpProductService { @Resource private OpProductMapper opProductMapper; @Override public List<ProductDTO> queryAllProduct() { MPJLambdaWrapper mpjLambdaWrapper = new MPJLambdaWrapper<ProductDTO>() .selectAll(OpProduct.class)//查詢(xún)表1的全部字段 .selectAll(OpProductInfo.class)//查詢(xún)表2的全部字段 .leftJoin(OpProductInfo.class, OpProductInfo::getProductId, OpProduct::getId);//左查詢(xún)表2條件為表二的productId=表一的id List<ProductDTO> list = opProductMapper.selectJoinList(ProductDTO.class, mpjLambdaWrapper); return list; } }
4、測(cè)試
@SpringBootTest @Slf4j public class MybatisJoinTests { @Autowired private OpProductService opProductService; @Test void test1() { List<ProductDTO> productDTOS = opProductService.queryAllProduct(); log.info(productDTOS.toString()); } }
5、結(jié)果
三、分頁(yè)查詢(xún)
1、MPJLambdaWrapper幾個(gè)方法
接下來(lái)的MPJLambdaWrapper就是構(gòu)建查詢(xún)條件的核心了,看一下我們?cè)谏厦嬗玫降膸讉€(gè)方法:
- selectAll():查詢(xún)指定實(shí)體類(lèi)的全部字段
- select():查詢(xún)指定的字段,支持可變長(zhǎng)參數(shù)同時(shí)查詢(xún)多個(gè)字段,但是在同一個(gè)select中只能查詢(xún)相同表的字段,所以如果查詢(xún)多張表的字段需要分開(kāi)寫(xiě)
- selectAs():字段別名查詢(xún),用于數(shù)據(jù)庫(kù)字段與接收結(jié)果的dto中屬性名稱(chēng)不一致時(shí)轉(zhuǎn)換
- leftJoin():左連接,其中第一個(gè)參數(shù)是參與聯(lián)表的表對(duì)應(yīng)的實(shí)體類(lèi),第二個(gè)參數(shù)是這張表聯(lián)表的ON字段,第三個(gè)參數(shù)是參與聯(lián)表的ON的另一個(gè)實(shí)體類(lèi)屬性
除此之外,還可以正常調(diào)用mybatis-plus中的各種原生方法,文檔中還提到,默認(rèn)主表別名是t,其他的表別名以先后調(diào)用的順序使用t1、t2、t3以此類(lèi)推。
和mybatis-plus非常類(lèi)似,除了LamdaWrapper外還提供了普通QueryWrapper的寫(xiě)法,舉例代碼:
public void getOrderSimple() { List<xxxxxDto> list = xxxxxMapper.selectJoinList(xxxxx.class, new MPJQueryWrapper<xxxxx>() .selectAll(xxxxx.class) .select("t2.unit_price","t2.name as product_name") .select("t1.name as user_name") .leftJoin("t_user t1 on t1.id = t.user_id") .leftJoin("t_product t2 on t2.id = t.product_id") .eq("t.status", "3") ); log.info(list.toString()); }
或者
MPJLambdaWrapper mpjLambdaWrapper = new MPJLambdaWrapper<ProductDTO>() .selectAll(OpProduct.class)//查詢(xún)表1的全部字段 .selectAs(OpProductInfo::getId,"ProductInfoId")//起別名 .selectAs(OpProductInfo::getName,ProductDTO::getName)//起別名 .selectAs(OpProductInfo::getPrice,ProductDTO::getPrice)//起別名 .leftJoin(OpProductInfo.class, OpProductInfo::getProductId, OpProduct::getId);//左查詢(xún)表2條件為表二的productId=表一的id List<ProductDTO> list = opProductMapper.selectJoinList(ProductDTO.class, mpjLambdaWrapper); return list;
2、分頁(yè)代碼舉例
public IPage<ProductDTO> queryPageProduct(Integer pageNo, Integer pageCount) { MPJLambdaWrapper mpjLambdaWrapper = new MPJLambdaWrapper<ProductDTO>() .selectAll(OpProduct.class)//查詢(xún)表1的全部字段 .selectAll(OpProductInfo.class)//查詢(xún)表2的全部字段 .leftJoin(OpProductInfo.class, OpProductInfo::getProductId, OpProduct::getId);//左查詢(xún)表2條件為表二的productId=表一的id IPage<ProductDTO> page = opProductMapper.selectJoinPage(new Page<ProductDTO>(pageNo, pageCount), ProductDTO.class, mpjLambdaWrapper); return page; }
總結(jié)
到此這篇關(guān)于MyBatis-Plus聯(lián)表查詢(xún)以及分頁(yè)的文章就介紹到這了,更多相關(guān)MyBatis-Plus聯(lián)表查詢(xún)分頁(yè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Idea中maven項(xiàng)目實(shí)現(xiàn)登錄驗(yàn)證碼功能
這篇文章主要介紹了Idea中maven項(xiàng)目實(shí)現(xiàn)登錄驗(yàn)證碼功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12java按鈕控件數(shù)組實(shí)現(xiàn)計(jì)算器界面示例分享
本文主要介紹了JAVA通過(guò)按鈕數(shù)組來(lái)管理界面中的所有按鈕控件,從而使用最少的代碼實(shí)現(xiàn)模擬的計(jì)算器界面2014-02-02Java中幾種常用數(shù)據(jù)庫(kù)連接池的使用
數(shù)據(jù)庫(kù)連接池在編寫(xiě)應(yīng)用服務(wù)是經(jīng)常需要用到的模塊,太過(guò)頻繁的連接數(shù)據(jù)庫(kù)對(duì)服務(wù)性能來(lái)講是一個(gè)瓶頸,使用緩沖池技術(shù)可以來(lái)消除這個(gè)瓶頸,本文就來(lái)介紹Java常見(jiàn)的幾種,感興趣的可以了解一下2021-05-05JAVA JNI原理詳細(xì)介紹及簡(jiǎn)單實(shí)例代碼
這篇文章主要介紹了JAVA JNI原理的相關(guān)資料,這里提供簡(jiǎn)單實(shí)例代碼,需要的朋友可以參考下2016-12-12SpringBoot的三大開(kāi)發(fā)工具小結(jié)
本文主要介紹了SpringBoot的三大開(kāi)發(fā)工具,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02screw?Maven插件方式運(yùn)行時(shí)在編譯打包時(shí)跳過(guò)執(zhí)行的問(wèn)題解決方法
這篇文章主要介紹了screw?Maven插件方式運(yùn)行時(shí)在編譯打包時(shí)跳過(guò)執(zhí)行的問(wèn)題解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03spring為java.util.Properties類(lèi)型的屬性進(jìn)行賦值過(guò)程解析
這篇文章主要介紹了spring為java.util.Properties類(lèi)型的屬性進(jìn)行賦值過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01Java8 Optional優(yōu)雅空值判斷的示例代碼
這篇文章主要介紹了Java8 Optional優(yōu)雅空值判斷的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-05-05