在Mybatis的collection標籤中獲取以,分隔的id字符串

有的時候咱們把一個表的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": "操做成功" }

相關文章
相關標籤/搜索