MyBatis-Plus聯(lián)表查詢及分頁代碼舉例
一、準(zhǔn)備工作
mybatis-plus作為mybatis的增強(qiáng)工具,它的出現(xiàn)極大的簡化了開發(fā)中的數(shù)據(jù)庫操作,但是長久以來,它的聯(lián)表查詢能力一直被大家所詬病。一旦遇到left join或right join的左右連接,你還是得老老實(shí)實(shí)的打開xml文件,手寫上一大段的sql語句。
直到前幾天,偶然碰到了這么一款叫做mybatis-plus-join的工具(后面就簡稱mpj了),使用了一下,不得不說真香!徹底將我從xml地獄中解放了出來,終于可以以類似mybatis-plus中QueryWrapper的方式來進(jìn)行聯(lián)表查詢了,話不多說,我們下面開始體驗(yàn)。
- mapper繼承MPJBaseMapper (必選)
- service繼承MPJBaseService (可選)
- serviceImpl繼承MPJBaseServiceImpl (可選)
1、數(shù)據(jù)庫結(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, '蘋果'); 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, '蘋果13', 8.00); INSERT INTO `test_yjdsns`.`op_product_info`(`id`, `product_id`, `name`, `price`) VALUES (2, 1, '蘋果15', 9.00);
2、依賴
<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、配置類讓mybatis-plus-join在DataScopeSqlInjector中生效
/**
* @author licy
* @description
* @date 2022/10/20
*/
@Configuration
public class MybatisPlusConfig {
/**
* 新增分頁攔截器,并設(shè)置數(shù)據(jù)庫類型為mysql
*
* @return
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//分頁插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
/**
* sql注入
*/
@Bean
@Primary
public MySqlInjector myLogicSqlInjector() {
return new MySqlInjector();
}
}修改DataScopeSqlInjector中的繼承類為:MPJSqlInjector
public class MySqlInjector extends MPJSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
//將原來的保持
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
//多表查詢sql注入 從連表插件里移植過來的
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)類排除MPJSqlInjector.class
@SpringBootApplication(exclude = {MPJSqlInjector.class})載入自定義配置類
@Configuration
@MapperScan可以選擇tk下的路徑
import tk.mybatis.spring.annotation.MapperScan;

二、代碼
1、實(shí)體類
/**
* @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中,雖然說我們要完成3張表的聯(lián)表查詢,但是以O(shè)pProduct作為主表的話,那么只注入這一個(gè)對(duì)應(yīng)的OpProductMapper就可以,非常簡單。
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)//查詢表1的全部字段
.selectAll(OpProductInfo.class)//查詢表2的全部字段
.leftJoin(OpProductInfo.class, OpProductInfo::getProductId, OpProduct::getId);//左查詢表2條件為表二的productId=表一的id
List<ProductDTO> list = opProductMapper.selectJoinList(ProductDTO.class, mpjLambdaWrapper);
return list;
}
}4、測試
@SpringBootTest
@Slf4j
public class MybatisJoinTests {
@Autowired
private OpProductService opProductService;
@Test
void test1() {
List<ProductDTO> productDTOS = opProductService.queryAllProduct();
log.info(productDTOS.toString());
}
}5、結(jié)果

三、分頁查詢
1、MPJLambdaWrapper幾個(gè)方法
接下來的MPJLambdaWrapper就是構(gòu)建查詢條件的核心了,看一下我們在上面用到的幾個(gè)方法:
- selectAll():查詢指定實(shí)體類的全部字段
- select():查詢指定的字段,支持可變長參數(shù)同時(shí)查詢多個(gè)字段,但是在同一個(gè)select中只能查詢相同表的字段,所以如果查詢多張表的字段需要分開寫
- selectAs():字段別名查詢,用于數(shù)據(jù)庫字段與接收結(jié)果的dto中屬性名稱不一致時(shí)轉(zhuǎn)換
- leftJoin():左連接,其中第一個(gè)參數(shù)是參與聯(lián)表的表對(duì)應(yīng)的實(shí)體類,第二個(gè)參數(shù)是這張表聯(lián)表的ON字段,第三個(gè)參數(shù)是參與聯(lián)表的ON的另一個(gè)實(shí)體類屬性
除此之外,還可以正常調(diào)用mybatis-plus中的各種原生方法,文檔中還提到,默認(rèn)主表別名是t,其他的表別名以先后調(diào)用的順序使用t1、t2、t3以此類推。
和mybatis-plus非常類似,除了LamdaWrapper外還提供了普通QueryWrapper的寫法,舉例代碼:
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)//查詢表1的全部字段
.selectAs(OpProductInfo::getId,"ProductInfoId")//起別名
.selectAs(OpProductInfo::getName,ProductDTO::getName)//起別名
.selectAs(OpProductInfo::getPrice,ProductDTO::getPrice)//起別名
.leftJoin(OpProductInfo.class, OpProductInfo::getProductId, OpProduct::getId);//左查詢表2條件為表二的productId=表一的id
List<ProductDTO> list = opProductMapper.selectJoinList(ProductDTO.class, mpjLambdaWrapper);
return list;
2、分頁代碼舉例
public IPage<ProductDTO> queryPageProduct(Integer pageNo, Integer pageCount) {
MPJLambdaWrapper mpjLambdaWrapper = new MPJLambdaWrapper<ProductDTO>()
.selectAll(OpProduct.class)//查詢表1的全部字段
.selectAll(OpProductInfo.class)//查詢表2的全部字段
.leftJoin(OpProductInfo.class, OpProductInfo::getProductId, OpProduct::getId);//左查詢表2條件為表二的productId=表一的id
IPage<ProductDTO> page = opProductMapper.selectJoinPage(new Page<ProductDTO>(pageNo, pageCount), ProductDTO.class, mpjLambdaWrapper);
return page;
}
到此這篇關(guān)于MyBatis-Plus聯(lián)表查詢及分頁的文章就介紹到這了,更多相關(guān)MyBatis-Plus聯(lián)表查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用JDBC連接Oracle_MSSQL實(shí)例代碼
這篇文章主要介紹了Java使用JDBC連接Oracle_MSSQL實(shí)例代碼,需要的朋友可以參考下2014-01-01
Spring MVC之WebApplicationContext_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Spring MVC之WebApplicationContext的相關(guān)資料,需要的朋友可以參考下2017-08-08
Spring boot事件監(jiān)聽實(shí)現(xiàn)過程解析
這篇文章主要介紹了,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
druid監(jiān)控?zé)o法關(guān)閉的坑以及處理方式
這篇文章主要介紹了druid監(jiān)控?zé)o法關(guān)閉的坑以及處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Java OpenCV實(shí)現(xiàn)圖像鏡像翻轉(zhuǎn)效果
這篇文章主要為大家詳細(xì)介紹了Java OpenCV實(shí)現(xiàn)圖像鏡像翻轉(zhuǎn)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07

