有的時候咱們把一個表的id以逗號(,)分隔的字符串形式放在另外一個表裏表示一種包含關係,當咱們要查詢出咱們所須要的所有內容時,會在resultMap標籤中使用collection標籤來獲取這樣的一個集合。html
咱們以門店以及門店提供的服務來進行一個介紹java
這是一個門店表,service_ids是一家門店包含的全部的服務idgit
Java實體類爲mybatis
/** * 服務商門店 */ @NoArgsConstructor @Data public class Store { private Long id; private String name; private Address address; private String cityName; private List<Service> serviceList; private Double avgStar; //服務的數量 private Integer numService; }
服務的數據表app
Java實體類以下ide
/** * 商家服務 */ @NoArgsConstructor @AllArgsConstructor @Data public class Service { private Long id; private String name; private Price price; private String topUrls; private String details; private List<Evaluate> evaluateList; public Service deepClone() { Input input = null; try { Kryo kryo = new Kryo(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); Output output = new Output(stream); kryo.writeObject(output, this); output.close(); // System.out.println(Arrays.toString(stream.toByteArray())); input = new Input(new ByteArrayInputStream(stream.toByteArray())); return kryo.readObject(input,Service.class); }finally { input.close(); } } }
另外咱們還須要一個用來接引索引的表sequence,只有一個主鍵字段seq,裏面放入儘量多的從1開始的數字this
Mybatis dao以下lua
@Mapper public interface StoreDao { List<Store> findStoreByCity(String city); @Update("update store set service_ids=concat(service_ids,concat(',',#{serviceId})) where id=#{storeId}") int addServiceToStore(ParamId paramId); }
這裏咱們主要看的是findStoreByCity方法url
映射文件以下spa
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.cloud.serviceprovider.dao.StoreDao"> <resultMap id="store_map" type="com.cloud.model.serviceprovider.Store"> <id property="id" column="id" /> <result property="name" column="store_name" /> <result property="cityName" column="city_name" /> <association property="address" javaType="com.cloud.model.serviceprovider.Address"> <id property="name" column="address_name" /> <result property="longitude" column="address_longitude" /> <result property="latitude" column="address_latitude" /> </association> <collection property="serviceList" javaType="java.util.List" column="service_ids" ofType="com.cloud.model.serviceprovider.Service" select="findServiceByIds"> </collection> </resultMap> <resultMap id="service_Map" type="com.cloud.model.serviceprovider.Service"> <id column="id" property="id" /> <result column="name" property="name" /> <result column="top_urls" property="topUrls" /> <result column="details" property="details" /> <association property="price" javaType="com.cloud.model.serviceprovider.Price"> <id column="normal_price" property="normalPrice" /> <result column="seckill_price" property="secKillPrice" /> </association> </resultMap> <select id="findServiceByIds" parameterType="java.lang.String" resultMap="service_Map" resultType="java.util.List"> select id,name,normal_price,seckill_price,top_urls,details from service <where> id in (SELECT DISTINCT SUBSTRING_INDEX( SUBSTRING_INDEX(#{service_ids}, ',', seq), ',' ,- 1 ) FROM sequence where seq BETWEEN 1 AND ( SELECT 1 + LENGTH(#{service_ids}) - LENGTH(replace(#{service_ids}, ',', '')) )) </where> </select> <select id="findStoreByCity" parameterType="java.lang.String" resultMap="store_map"> select id,store_name,city_name,address_name, address_longitude,address_latitude,service_ids from store <where> city_name=#{city} </where> </select> <select id="findStoreById" parameterType="java.lang.Long" resultMap="store_map" resultType="com.cloud.model.serviceprovider.Store"> select id,store_name,city_name,address_name, address_longitude,address_latitude,service_ids from store <where> id=#{id} </where> </select> </mapper>
咱們重點來看的是
<collection property="serviceList" javaType="java.util.List" column="service_ids" ofType="com.cloud.model.serviceprovider.Service" select="findServiceByIds"> </collection>
<select id="findServiceByIds" parameterType="java.lang.String" resultMap="service_Map" resultType="java.util.List"> select id,name,normal_price,seckill_price,top_urls,details from service <where> id in (SELECT DISTINCT SUBSTRING_INDEX( SUBSTRING_INDEX(#{service_ids}, ',', seq), ',' ,- 1 ) FROM sequence where seq BETWEEN 1 AND ( SELECT 1 + LENGTH(#{service_ids}) - LENGTH(replace(#{service_ids}, ',', '')) )) </where> </select>
這裏須要說明的是若是寫成id in (#{service_ids})是取不出咱們所但願的集合的,由於#{service_ids}只是一個字符串,翻譯過來的語句例爲id in ('1,2,3')之類的語句,因此須要將它解析成id in (1,2,3),substring_index的做用能夠自行查詢。
最終在controller中查出來的結果以下
{ "code": 200, "data": [ { "address": { "distance": 11444.8137, "latitude": 256.2342133234, "longitude": 135.3454234, "name": "三潤汽修廠" }, "avgStar": 5, "cityName": "廣州", "id": 1, "name": "三潤汽修廠", "serviceList": [ { "details": "sdfadfsdfdadsdf", "id": 1, "name": "人工洗車", "price": { "normalPrice": 50, "secKillPrice": 45 }, "topUrls": "http://123.456.789" }, { "details": "ddsadfasdehgfjh", "id": 2, "name": "換輪胎", "price": { "normalPrice": 300, "secKillPrice": 250 }, "topUrls": "http://123.456.789" }, { "details": "<html><body><img src='http://123.234.123.12'></body></html>", "id": 2455928998547424253, "name": "大保養", "price": { "normalPrice": 50, "secKillPrice": 45 }, "topUrls": "http://123.234.123.12,http://234.123.343.21" } ] }, { "address": { "distance": 18577.1862, "latitude": 348.23423234, "longitude": 168.2344234, "name": "馳加京海店" }, "avgStar": null, "cityName": "廣州", "id": 2, "name": "馳加京海店", "serviceList": [ { "details": "sdfadfsdfdadsdf", "id": 1, "name": "人工洗車", "price": { "normalPrice": 50, "secKillPrice": 45 }, "topUrls": "http://123.456.789" }, { "details": "ddsadfasdehgfjh", "id": 2, "name": "換輪胎", "price": { "normalPrice": 300, "secKillPrice": 250 }, "topUrls": "http://123.456.789" }, { "details": "<html><body><img src='http://123.234.123.12'></body></html>", "id": 2456268364314575869, "name": "小保養", "price": { "normalPrice": 100, "secKillPrice": 88 }, "topUrls": "http://123.234.123.12,http://234.123.343.21" } ] } ], "msg": "操做成功" }