1. 程式人生 > >mybatis 標籤動態增刪改查

mybatis 標籤動態增刪改查

mybatis 《foreach》

有的時候在專案中需要查詢某個列表時,可能會在程式碼中進行巢狀迴圈再取值,其實mybatis提供了這麼一個標籤,可以在SQL中進行迴圈(是不是很酸爽)

先來了解一下foreach這個標籤有哪些元素:

  • item
    • 表示集合中每一個元素進行迭代時的別名
  • index
    • 指定一個名字,用於表示在迭代過程中,每次迭代到的位置
  • open
    • 表示該語句以什麼開始
  • separator
    • 表示在每次進行迭代之間以什麼符號作為分隔符
  • close
    • 表示以什麼結束
  • collection
    • 被迴圈的集合或者陣列

注意

在使用foreach的時候最關鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,但是在不同情況下,該屬性的值是不一樣的,主要有一下3種情況:

  1. 如果傳入的是單引數且引數型別是一個List的時候,collection屬性值為list

  2. 如果傳入的是單引數且引數型別是一個array陣列的時候,collection的屬性值為array

  3. 如果傳入的引數是多個的時候,我們就需要把它們封裝成一個Map或者Object。

實戰

話不多說,看程式碼,首先是mybatis的XML如何寫,拿動態建立表為例子,什麼是動態建立表,就是可以隨便生成表名,欄位是傳入進來的集合陣列,根據這個陣列內容來建立欄位

<update id="createTable" parameterType="java.util.HashMap">
        CREATE TABLE IF NOT EXISTS ed_temp_${tableName}(
        id VARCHAR(32) NOT NULL,
        log_id VARCHAR(32),
        state INT,
        message VARCHAR(255)
        <foreach
collection="list" item="column" open="," separator="VARCHAR(255)," close="VARCHAR(255), PRIMARY KEY (id)">
${column.name} </foreach> ) ENGINE = InnoDB DEFAULT CHARSET = utf8; </update>

這個<foreach>看出,我傳入的叫一個list的集合,別名叫column,從開始,因為上面message少個逗號,中間用VARCHAR(255),

做分隔符,已什麼為結束都定義好了。

看Mapper類

/**
     * 動態建立表
     */
    void createTable(HashMap<String , Object> map);

看實現

    /**
     * 建立表
     * @param templateId 模板id
     */
    private void createTable(String templateId){
        List<EdTemplateField> fields = edTemplateFieldMapper.findByTemplate(templateId);
        List<EdFieldColumns> columns = new ArrayList<>();
        HashMap<String,Object> map = new HashMap<>(16);
        map.put("tableName",templateId);
        for (EdTemplateField field : fields) {
            columns.add(edFieldColumnsMapper.findByField(field.getId()).get(0));
        }
        map.put("list",columns);
        edTemplateMapper.createTable(map);
    }

邏輯是這樣的,通過傳入的ID,去尋找所需要的值,再建立一個List和一個Map,將表名放進來,在將需要的陣列放進來,呼叫mapper的方法,最後就能成功建立一張動態表

往這個動態表裡插入資料的方式也用到了<foreach>,應該說不得不用,不然怎麼插入,又不知道表名又沒有實體類

XML

    <insert id="tableInsert" parameterType="java.util.HashMap">
        INSERT INTO ed_temp_${tableName}(
        id,log_id,state,message
        <foreach collection="columns" item="column" open="," separator="," >
            ${column.name}
        </foreach>
        )VALUES(
        <foreach collection="values" item="value" open="REPLACE(UUID(),'-','')," separator="," >
            #{value}
        </foreach>
        )
    </insert>

兩個<foreach>標籤,一個是欄位,剛剛那個動態建表的欄位,一個是值

mapper類

/**
     * 動態插入
     * @param map
     */
    void tableInsert(HashMap<String,Object> map);

實現方法

/**
     * 儲存資料到臨時表
     * @param templateId 模板id
     * @param list 資料集合
     * @param hearTitle 資料對應的欄位
     */
    private void tableInsert(String templateId,List<String> list,List<String> hearTitle){
         List<EdFieldColumns> columns = new ArrayList<>();
        HashMap<String,Object> map = new HashMap<>(16);
        map.put("tableName",templateId);
        for (String s : hearTitle) {
            columns.add(edFieldColumnsMapper.findByTemplateIdAndName(s,templateId));
        }
        map.put("columns",columns);
        map.put("values",list);
        edTemplateMapper.tableInsert(map);
    }

說明
其餘的類程式碼就不貼了,邏輯是這樣的,建立一個放欄位的集合和傳入的map,集合的值必須要和欄位對應的上,不然插錯欄位值那就很尷尬,所以必須要通過動態建立的欄位和值的順序是一樣的,比如第一個建立了name那插入的第一個就是name,這個意思,所以這裡是根據順序,先排好了欄位,放入map裡,再將要放入動態表的值放進來,進行mapper操作

有了建表以及插入,當然少不了刪除和更新

刪除表的xml

<update id="deleteTable" parameterType="java.lang.String">
    DROP TABLE ${tempTable}
</update>

<delete id="deleteTemporary">
        DELETE
        FROM
             ${tableName}
        WHERE
            id = #{id}
    </delete>

用於來刪除不需要的表,以及刪除資料

void deleteTable(@param(value = "tempTable") String tempTable);

void deleteTemporary(@Param("tableName") String tableName,
                         @Param("id") String id);

這是mapper介面的寫法,傳入要刪除的表名就可以

更新的XML

<update id="updateTemporary">
        UPDATE ${tableName}
        SET
        <foreach collection="dataMap" index="key" item="value"  separator="," >
            ${key} = #{value}
        </foreach>
        WHERE
            id = #{id}
    </update>

對應的mapper介面

 void updateTemporary(@Param("tableName") String tableName,
                         @Param("id") String id,
                         @Param("dataMap") HashMap dataMap);