長(zhǎng)春網(wǎng)站制作公司哪個(gè)好高端seo服務(wù)
最近遇到一個(gè)場(chǎng)景就是Java開(kāi)發(fā)中,需要循環(huán)多個(gè)表名,然后用同樣的查詢(xún)操作分別查表,最終得到N個(gè)表中查詢(xún)的結(jié)果集合。在查詢(xún)內(nèi)容不一致時(shí)Java中跨表查詢(xún)常用的是遍歷表名集合循環(huán)查庫(kù),比較耗費(fèi)資源,效率較低。在查詢(xún)內(nèi)容格式一致的情況下,便可以用Java的數(shù)據(jù)庫(kù)連接工具模擬mysql中union的操作,這里我用的數(shù)據(jù)庫(kù)交互工具是mybatis。
首先介紹下union:
在mysql中被稱(chēng)為集合操作,操作類(lèi)型分為兩種:UNION DISTINCT 和? UNION ALL;其中UNION和UNION DISTINCT是一樣的功能。UNION功能為合并多個(gè)查詢(xún)的結(jié)果并去重,UNION ALL的功能為合并多個(gè)查詢(xún)的結(jié)果不去重。
這里mybatis在實(shí)現(xiàn)union操作時(shí),用到的是foreach 標(biāo)簽,foreach標(biāo)簽用于循環(huán)語(yǔ)句,它很好的支持了數(shù)據(jù)和 List、set 接口的集合,并對(duì)此提供遍歷的功能。最常用的地方就是對(duì)于一些 SQL 語(yǔ)句中含有 in 條件,或者批量處理數(shù)據(jù)需要迭代條件時(shí),可以使用 foreach 。利用foreach這一迭代特性,也滿(mǎn)足了union多個(gè)表的使用場(chǎng)景,整體思路框架代碼如下:
實(shí)現(xiàn)層設(shè)置每一個(gè)union的查詢(xún)sql的業(yè)務(wù)代碼:
List<Map> queryCondition = new ArrayList<>();
//這里的namelIst代表存儲(chǔ)聯(lián)合查詢(xún)表名的集合
for (Map nameMap: namelIst) {Map conditionMap = new HashMap();//查詢(xún)內(nèi)容String fields = "a.*,b.*";//拼接表名String tableName = "table_aaa a ," + nameMap.get("tableName") + "` b";//查詢(xún)條件String joinsql = "a.nameId = b.id ";//將循環(huán)一次的查詢(xún)條件,表名,內(nèi)容放入一個(gè)集合中,當(dāng)做union的一個(gè)查詢(xún)部分conditionMap.put("fields", fields);conditionMap.put("tableName", tableName);conditionMap.put("joinsql", joinsql);//放入總的集合中作為傳入mapper查詢(xún)的條件queryCondition.add(conditionMap);}//執(zhí)行查詢(xún)List<Map> pages = this.baseMapper.getSelect(queryCondition);
傳入的查詢(xún)參數(shù)為一個(gè)list<map>集合。
/*** union查詢(xún)示范* @param queryCondition* @return*/List<Map> getSelect(@Param("queryCondition") List<Map> queryCondition);
xml文件的寫(xiě)法:
<select id="getSelect" resultType="java.util.Map"><foreach collection="queryCondition" item="condition" separator="union all">SELECT ${condition.fields}FROM ${condition.tableName}where ${condition.joinsql}</foreach></select>
這里對(duì)foreach標(biāo)簽中的標(biāo)簽進(jìn)行一下簡(jiǎn)單的總結(jié):
foreach 標(biāo)簽有六個(gè)屬性:item,index,collection,open, close,separator
屬性 | ?作用 |
item | 表示集合中每一個(gè)元素或子集合進(jìn)行迭代循環(huán)時(shí)的別名 |
index?? ? | 指定一個(gè)名字,表示在迭代過(guò)程中每次迭代到的位置 |
open?? ? | 表示該語(yǔ)句以什么開(kāi)始(如in 條件語(yǔ)句,以’('開(kāi)始) |
close?? ? | 表示該語(yǔ)句以什么結(jié)束(如in 條件語(yǔ)句,以’)'結(jié)束。 |
separator?? ? | 表示在每次進(jìn)行迭代之間以什么符號(hào)作為分隔符(如in 條件語(yǔ)句,以‘,’作為分隔符) |
collection?? ? | 該屬性是必選的,但在不同情況下該屬性的值是不一樣的,主要有以下 3 種情況: (1)如果傳入的是單參數(shù)且參數(shù)類(lèi)型是一個(gè) List,collection 屬性值為 list (2)如果傳入的是單參數(shù)且參數(shù)類(lèi)型是一個(gè) array 數(shù)組,collection 的屬性值為 array (3)如果傳入的參數(shù)是多個(gè),需要把它們封裝成一個(gè) Map,當(dāng)然單參數(shù)也可以封裝成 Map。Map 的 key 是參數(shù)名,collection 屬性值是傳入的 List 或 array 對(duì)象在自己封裝的 Map 中的 key。 |
通常在使用foreach標(biāo)簽時(shí)候,都是用來(lái)當(dāng)做批量查詢(xún)或者更新,或者where后面的條件使用,大概這樣:
<foreach collection="各種集合" item="循環(huán)體中的別名" index="index" open="(" separator="," close=")">自定義的各種參數(shù)
</foreach>
這里的操作屬于mybatis的一個(gè)靈活運(yùn)用,算是一個(gè)處理思路,鑒于網(wǎng)上現(xiàn)有相關(guān)思路不多,個(gè)人完成了測(cè)試,可以當(dāng)做一種解決辦法,提高一下程序的執(zhí)行效率,避免多次連庫(kù)。