若依-关联查询

背景

众所周知,一个合同可能包含多个产品,因此基于产品的查询并关联合同是一个多对一的查询。我们就以产品-合同这两者为例介绍MyBatis的代码写法及配置

过程

代码生成

参考若依代码生成的步骤,生成产品模块合同模块

代码生成

注意,一般的代码生成流程需要先运行一下.sql文件,这里我们只需要运行产品模块.sql文件,不需要运行合同模块.sql文件。同时,这两模块的代码文件均需要放置到对应位置

数据库添加外键(无需此步骤)

如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键(来自百度百科)。因此,我们需要为qlj_product产品表添加外键

外键

domain文件添加字段

产品代码文件中添加

1
2
3
4
5
6
private QljContract contract;
public QljContract getQljContract() { return contract; }
public void setQljContract(QljContract contract) { this.contract = contract; }

// toString()函数中添加下面这一行
.append("contract", getQljContract())

合同代码文件中添加

1
2
3
4
5
6
private List<QljProduct> product;
public List<QljProduct> getProduct() { return product; }
public void setProduct(List<QljProduct> product) { this.product = product; }

// toString()函数中添加下面这一行
.append("product", getProduct())

xml文件

产品模板中添加关联语句

1
2
3
4
5
6
7
8
9
10
<resultMap type="QljProduct" id="QljProductResult">
...
<result property="createTime" column="create_time" />
<result property="changeUser" column="change_user" />
<result property="changeTime" column="change_time" />
<result property="deleteFlag" column="delete_flag" />

<association property="contract" select="getContract" column="contract_id" javaType="QljContract"/> // 添加这一句

</resultMap>

其中,property字段映射实体类的字段或属性,select字段根据对应id绑定相关语句,column字段是数据库的列名或者列标签别名,javaType字段是完整Java类名或别名

同时,添加对应的查询语句

1
2
3
<select id="getContract" parameterType="int" resultMap="QljContractResult">
select * from qlj_contract where id = #{contract_id}
</select>

最后,再将qljContractResult对应的模板从合同文件中复制过来

1
2
3
4
5
6
7
8
<resultMap type="QljContract" id="QljContractResult">
...
<result property="createUser" column="create_user" />
<result property="createTime" column="create_time" />
<result property="changeUser" column="change_user" />
<result property="changeTime" column="change_time" />
<result property="deleteFlag" column="delete_flag" />
</resultMap>

浏览器控制台查看结果

启动项目,打开浏览器开发者工具,点击Network,如果可以关联到合同信息,说明成功

开发者

之后只需要在前端界面修改字段属性即可对应的展示了,例如

1
<el-table-column label="用户" align="center" prop="qljContract.user" />

效果

关联查询

背景

查询

那么要如何进行关联查询呢

关联查询(基于本例)

准备工作

首先,请确保自己能够实现本文前半段的内容

自定义查询类

ruoyi-system/src/main/java/com/ruoyi/qljsystem/domain目录下,添加一个查询类ProductQueryParam.java,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.ruoyi.qljsystem.domain;
public class ProductQueryParam {

private String productModel; //产品型号
private String productType; //产品分类
private String productNumber; //产品编号
private String drawingNumber; //图号
private String contractNum; //合同号
private String projectName; //项目名称
private Long deleteFlag; //删除标识

public String getProductModel() { return productModel; }
public void setProductModel(String productModel) { this.productModel = productModel; }

public String getProductType() { return productType; }
public void setProductType(String productType) { this.productType = productType; }

public String getProductNumber() { return productNumber; }
public void setProductNumber(String productNumber) { this.productNumber = productNumber; }

public String getDrawingNumber() { return drawingNumber; }
public void setDrawingNumber(String drawingNumber) { this.drawingNumber = drawingNumber; }

public String getContractNum() { return contractNum; }
public void setContractNum(String contractNum) { this.contractNum = contractNum; }

public String getProjectName() { return projectName; }
public void setProjectName(String projectName) { this.projectName = projectName; }

public Long getDeleteFlag() { return deleteFlag; }
public void setDeleteFlag(Long deleteFlag) { this.deleteFlag = deleteFlag; }

}

新建接口

在对应的js文件中,添加接口如下

1
2
3
4
5
6
7
8
// 关联查询
export function list(query) {
return request({
url: 'yoururl',
method: 'get',
params: query
})
}
修改controller、mapper、service层的参数

这里仅仅以controller为例,mapper和service同理

1
2
3
4
5
6
7
8
/** 关联查询 */
@PreAuthorize("@ss.hasPermi('qljsystem:qljproduct:list')")
@GetMapping("/listpc")
public TableDataInfo list(ProductQueryParam productQueryParam) {
startPage();
List<QljProduct> list = qljProductService.selectProductList(productQueryParam);
return getDataTable(list);
}
xml

在对应的xml文件中添加查询如下

1
2
3
4
5
6
7
8
9
10
11
12
<select id="selectProductList" parameterType="ProductQueryParam" resultMap="QljProductResult">
select p.*
from qlj_product p left join qlj_contract c on p.contract_id=c.id
where 1=1
<if test="productModel != null ">and p.product_model like concat('%',#{productModel},'%')</if>
<if test="productType != null ">and p.product_type like concat('%',#{productType},'%')</if>
<if test="productNumber != null ">and p.product_number like concat('%',#{productNumber},'%')</if>
<if test="drawingNumber != null ">and p.drawing_number like concat('%',#{drawingNumber},'%')</if>
<if test="contractNum != null ">and c.contract_num like concat('%',#{contractNum},'%')</if>
<if test="projectName != null ">and c.project_name like concat('%',#{projectName},'%')</if>
<if test="deleteFlag != null ">and p.delete_flag like concat('%',#{deleteFlag},'%')</if>
</select>

注意,这里需要准备好resultMap对应的模板

1
2
3
4
<resultMap type="QljProduct" id="QljProductResult">
...
<association property="contract" select="getContract" column="contract_id" javaType="QljContract"/>
</resultMap>
前端写好对应参数
1
2
3
4
5
6
7
<el-form-item label="合同号" prop="contractNum">
<el-input
v-model="queryParams.contractNum"
placeholder="请输入合同号"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
1
2
3
4
5
6
7
8
9
data() {
return {
queryParams: {
...
contractNum: null,
projectName: null
},
}
}

三表关联

查询
1
2
3
4
5
6
7
8
9
10
11
<select id="selectProductlistSupply" parameterType="ProductQueryParam" resultMap="QljProductResult">
select p.*, c.*, qip.*
from qlj_product p left join qlj_contract c on p.contract_id=c.id left join qlj_implementation_plan qip on p.id
= qip.product_id
where 1=1
<if test="contractNum != null ">and c.contract_num like concat('%',#{contractNum},'%')</if>
<if test="productModel != null ">and p.product_model like concat('%',#{productModel},'%')</if>
<if test="buyer != null ">and c.buyer like concat('%',#{buyer},'%')</if>
<if test="drawingNumber != null ">and p.drawing_number like concat('%',#{drawingNumber},'%')</if>
and p.delete_flag=0 order by p.id
</select>
更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<update id="updateQljProductContractIm" parameterType="QljProduct">
update qlj_product p left join qlj_contract cc
on p.contract_id = cc.id left join qlj_implementation_plan qip
on p.id = qip.product_id
set qip.project_importance = #{qljImplementationPlan.projectImportance},
cc.contract_num = #{qljContract.contractNum},
qip.project_type = #{qljImplementationPlan.projectType},
qip.material_batch = #{qljImplementationPlan.materialBatch},
p.product_number = #{productNumber},
cc.buyer = #{qljContract.buyer},
cc.ultimate_user = #{qljContract.ultimateUser},
cc.project_name = #{qljContract.projectName},
cc.project_name = #{qljContract.projectName},
p.product_model = #{productModel},
p.drawing_number = #{drawingNumber},
p.power = #{power},
p.product_type = #{productType},
qip.contract_delivery_date = #{qljImplementationPlan.contractDeliveryDate},
qip.user_required_date = #{qljImplementationPlan.userRequiredDate},
qip.planning_product_date = #{qljImplementationPlan.planningProductDate},
qip.change_statement = #{qljImplementationPlan.changeStatement},
qip.project_leading = #{qljImplementationPlan.projectLeading},
qip.product_manager = #{qljImplementationPlan.productManager},
qip.project_manager = #{qljImplementationPlan.projectManager},
cc.contract_signer = #{qljContract.contractSigner},
cc.contract_sign_depart = #{qljContract.contractSignDepart},
cc.internal_project_tracker = #{qljContract.internalProjectTracker}
where p.id = #{id}
</update>