mybatis中association和collection的column傳入多個參數值
項目中在使用association和collection實現一對一和一對多關係時需要對關係中結果集進行篩選,如果使用懶加載模式,即聯合使用select
標籤時,主sql和關係映射裏的sql是分開的,查詢參數傳遞成爲問題。
mybatis文檔:
property | description |
---|---|
column | 數據庫的列名或者列標籤別名。與傳遞給resultSet.getString(columnName)的參數名稱相同。注意: 在處理組合鍵時,您可以使用column=“{prop1=col1,prop2=col2}”這樣的語法,設置多個列名傳入到嵌套查詢語句。這就會把prop1和prop2設置到目標嵌套選擇語句的參數對象中。 |
<resultMap id="findCountryCityAddressMap" type="map">
<result property="country" column="country"/>
<collection property="cityList"
column="{cityId=city_id,adr=addressCol, dis=districtCol}" //adr作爲第二個sql查詢條件key,即prop1屬性
ofType="map" //addressCol即爲虛擬列名
javaType="java.util.List" select="selectAddressByCityId"/>
</resultMap>
<resultMap id="selectAddressByCityIdMap" type="map">
<result property="city" column="city"/>
<collection property="addressList" column="city" ofType="map" javaType="java.util.List">
<result property="address" column="address"/>
<result property="district" column="district"/>
</collection>
</resultMap>
<select id="findCountryCityAddress" resultMap="findCountryCityAddressMap">
SELECT
ct.country,
ci.city_id,
IFNULL(#{addressQuery},'') addressCol, //爲傳入查詢條件,構造虛擬列,虛擬列爲查詢條件參數值
IFNULL(#{districtQuery},'') districtCol
FROM
country ct
LEFT JOIN city ci ON ct.country_id = ci.country_id
ORDER BY ct.country_id
</select>
<select id="selectAddressByCityId" parameterType="java.util.Map" resultMap="selectAddressByCityIdMap">
SELECT
ci.city,
ads.address,
ads.district
FROM
(
SELECT
city,
city_id
FROM
city ci
WHERE
ci.city_id = #{cityId}
) ci
LEFT JOIN address ads ON ads.city_id = ci.city_id
<where>
<if test="adr!=null and adr!=''">
and ads.address RegExp #{adr}
</if>
<if test="dis!=null and dis!=''">
ads.district Regexp #{dis}
</if>
</where>
</select>
測試文件:
@Test
public void findCountryCityAddressTest() throws JsonProcessingException {
Map<String,Object> param = new HashMap<>();
param.put("addressQuery","1168");
List<Map<String, Object>> rs = countryManager.findCountryCityAddress(param);
ObjectMapper mapper = new ObjectMapper();
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
System.out.println(writer.writeValueAsString(rs));
}
測試結果:
[
{
"country": "Afghanistan",
"cityList": [{
"city": "Kabul",
"addressList": [{
"address": "1168 Najafabad Parkway",
"district": "Kabol"
}
]
}
],
"city_id": 251
},
{
"country": "Algeria",
"cityList": [],
"city_id": 59
}
]
可以看到,確實將查詢條件通過column參數傳入到第二個sql中,並執行成功
ps: ------tree table
vue:
<el-table-column label="機構名稱" prop="orgName" min-width="150">
<template slot-scope="scope">
<p :style="`margin-left: ${scope.row.__level * 20}px;margin-top:0;margin-bottom:0`">
<i @click="toggleFoldingStatus(scope.row)" class="permission_toggleFold" :class="toggleFoldingClass(scope.row)"></i>
<span class="c-click" @click="handleViewSyorg(scope.row)">{{ scope.row.orgName }}</span>
</p>
</template>
</el-table-column>
sql:
(#{syuserId}) as syuserId就可以別sql轉化未屬性
<!--tree table 返回結果集Map -->
<resultMap id="treeTable_ResultMap" type="com.alex.hainan.oas.base.entity.OrgTreeTableBO">
<result column="ORG_ID" jdbcType="VARCHAR" property="orgId" />
<result column="pid" jdbcType="VARCHAR" property="pid" />
<result column="syuserId" jdbcType="VARCHAR" property="syuserId" />
<collection property="children" ofType="com.alex.hainan.oas.base.entity.OrgTreeTableBO" javaType="java.util.List"
column="{pid=pid,syuserId=syuserId}" select="getChildSyorgList">
</collection>
</resultMap>
<!--alex企業tree table init顯示接口 查詢列表 -->
<select id="query" resultMap="treeTable_ResultMap" parameterType="java.util.Map">
select
o.org_id pid, o.org_id, o.org_name,
o.parent_org_id,
### (#{syuserId}) as syuserId
IFNULL(#{syuserId},'') as syuserId
from alex.syorg o where o.del_flg=0
and o.parent_org_id is null or o.parent_org_id =''
<if test="syuserId !=null and syuserId !=''">
AND o.org_id IN (select u.org_id from alex.syuser_syorg u where
u.syuser_id = #{syuserId,jdbcType=VARCHAR} and u.del_flg=0)
</if>
</select>
<select id="getChildSyorgList" resultMap="treeTable_ResultMap" parameterType="java.util.Map">
SELECT
o.org_id pid, o.org_id, o.org_name,
IFNULL(#{syuserId},'') as syuserId
FROM
alex.syorg o
LEFT JOIN alex.review registRv ON (o.review_seq = registRv.review_seq AND o.del_flg =0 AND registRv.apply_type = '1')
LEFT JOIN alex.review platRv ON (o.review_seq = platRv.review_seq AND o.del_flg = 0 AND platRv.apply_type = '2')
LEFT JOIN ( select e.org_id, f.batch_code as batch_code
from alex.org_batch_data e
INNER JOIN alex.batch_data f ON (e.batch_seq = f.batch_seq AND f.del_flg = 0 AND f.batch_type = '1')
where e.del_flg = 0
)as ef ON o.org_id = ef.org_id
WHERE
o.del_flg = 0
<if test="pid !=null and pid !=''">
and o.parent_org_id =#{pid,jdbcType=VARCHAR}
</if>
<if test="syuserId !=null and syuserId !=''">
AND o.org_id IN (select u.org_id from alex.syuser_syorg u where
u.syuser_id = #{syuserId,jdbcType=VARCHAR} and u.del_flg=0)
</if>
</select>
js:
method:{
formatConversion(parent, children, index = 0, family = [], elderIdentity = 'x') {
// children如果長度等於0,則代表已經到了最低層
// let page = (this.startPage - 1) * 10
if (children.length > 0) {
children.map((x, i) => {
// 設置 __level 標誌位 用於展示區分層級
Vue.set(x, '__level', index);
// 設置 __family 爲家族關係 爲所有父級,包含本身在內
Vue.set(x, '__family', [...family, elderIdentity + '_' + i]);
// 本身的唯一標識 可以理解爲個人的身份證咯 一定唯一。
Vue.set(x, '__identity', elderIdentity + '_' + i);
parent.push(x);
// 如果仍有子集,則進行遞歸
if (x.children.length > 0) this.formatConversion(parent, x.children, index + 1, [...family, elderIdentity + '_' + i], elderIdentity + '_' + i);
});
}
return parent;
}
}