1. 程式人生 > >foreach 實現 MyBatis 遍歷集合與批量操作資料

foreach 實現 MyBatis 遍歷集合與批量操作資料

一、寫在前面

MyBatis 動態 SQL 的一個常用的操作需求是對一個集合進行遍歷,通常是在構建 IN 條件語句的時候。foreach允許你指定一個集合,宣告可以在元素體內使用的集合項(item)和索引(index)變數。foreach 是動態 SQL 中一個非常強大的標籤。下面就來體驗一下foreach 標籤帶來的便捷之處,有關批量操作的實現,這裡以批量插入資料為例。

二、foreach遍歷傳遞進來的集合

有時候我們可能會有下面的需求,根據多個 id 查詢對應的資訊,這多個 id 的數量是不固定的。

SELECT * FROM t_employee 
    WHERE id IN (1
, 2, 3, ...)

這時候我們可以通過使用foreach標籤來遍歷集合中的引數,完成多個 id 之間的拼接。

mapper 介面:

    /** 根據傳入的 id 集合,查詢出對應的員工資訊,並使用集合儲存資訊 */
    List<Employee> getEmpsByConditions(@Param("list") List<Integer> idList);

SQL 對映檔案:

    <!-- 注意返回的資料型別是集合中儲存的資料型別 Employee-->
    <select id="getEmpsByConditions"
resultType="com.jas.mybatis.bean.Employee">
SELECT * FROM t_employee WHERE id IN <!-- collection:指定要遍歷的集合 item:取出當前集合中元素,賦給 item 中的值 separator:遍歷出的多個元素之間用什麼分隔符分隔開 open:遍歷集合前用什麼字元進行拼接 close:遍歷集合後用什麼字元進行拼接 在 foreach 標籤中還有一個屬性 index, 遍歷集合的時候 index 表示的是當前元素的索引,item 對應索引中的值 遍歷 map 的時候 index 表示的是當前 map 中的 key,item 是 key 對應的 value -->
<foreach collection="list" item="empId" separator="," open="(" close=")"> #{empId} </foreach> </select>

測試程式碼:

    // 用於返回 SqlSession  物件
    private SqlSession getSqlSession() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream is = Resources.getResourceAsStream(resource);

        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        return sqlSession;
    }

    @Test
    public void testList() throws IOException {
        SqlSession sqlSession = getSqlSession();

        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
        List<Employee> list = employeeMapper.getEmpsByConditions(Arrays.asList(1,2,15));

        for(Employee employee : list){
            System.out.println(employee);
        }

        sqlSession.close();
    }

執行結果:
這裡寫圖片描述

三、foreach批量插入資料

實現foreach批量插入資料有兩種方法,一種是隻傳送一條 SQL,插入的多條資料之間通過”,” 分隔開,另一種方式是每插入一條資料就傳送一條 SQL 語句,多個 SQL 語句之間用”;“分割。

3.1 一條 SQL 批量插入資料

mapper 介面:

    /** 返回值為 Integer 型別 */
    Integer addEmpsByList(@Param("list") List<Employee> list);

SQL 對映檔案:

    <insert id="addEmpsByList" parameterType="com.jas.mybatis.bean.Employee">
        INSERT INTO t_employee(username, gender, email) VALUES 
        <foreach collection="list" item="emp" separator=",">
            (#{emp.username}, #{emp.gender}, #{emp.email})
        </foreach>
    </insert>

測試程式碼:

    @Test
    public void testBatchAdd() throws IOException {
        SqlSession sqlSession = getSqlSession();
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
        List<Employee> List = new ArrayList<>();

        List.add(new Employee(null, "Jas", '1', "[email protected]"));
        List.add(new Employee(null, "Jason", '0', "[email protected]"));

        employeeMapper.addEmpsByList(List);
        sqlSession.commit();

        sqlSession.close();
    }

執行結果:
這裡寫圖片描述

3.2 執行多條 SQL 批量插入資料

修改對應的 SQL 對映檔案中的 SQL:

    <insert id="addEmpsByList" parameterType="com.jas.mybatis.bean.Employee">
        <!-- 
            每插入一條資料就執行一次 SQL,中間用";"分隔開 
        -->
        <foreach collection="list" item="emp" separator=";">
            INSERT INTO t_employee(username, gender, email) VALUES 
              (#{emp.username}, #{emp.gender}, #{emp.email})
        </foreach>
    </insert>

MySql 預設的情況下是不支援使用”;” 分隔開多條 SQL 進行執行的,需要設定一個連線屬性allowMultiQueries=true來支援。可以在連線資料庫的時候設定這個屬性。

jdbc.url=jdbc:mysql://localhost:3306/mybatis-study?allowMultiQueries=true

測試程式碼:

    @Test
    public void testBatchAdd() throws IOException {
        SqlSession sqlSession = getSqlSession();
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
        List<Employee> List = new ArrayList<>();

        List.add(new Employee(null, "Tom", '1', "[email protected]"));
        List.add(new Employee(null, "Tony", '0', "[email protected]"));

        employeeMapper.addEmpsByList(List);
        sqlSession.commit();
        sqlSession.close();
    }

執行結果:
這裡寫圖片描述

四、總結

這篇博文主要對 MyBati 動態 SQL 中的foreach進行了介紹與其使用場景的應用,MyBatis 還提供了其他的標籤來支援動態 SQL。比如:ifchoose (when, otherwise)trim (where, set),有關的詳細資訊可以到官方文件進行深入瞭解,希望這篇博文能夠為你提供一些幫助。

相關推薦

foreach 實現 MyBatis 集合批量操作資料

一、寫在前面 MyBatis 動態 SQL 的一個常用的操作需求是對一個集合進行遍歷,通常是在構建 IN 條件語句的時候。foreach允許你指定一個集合,宣告可以在元素體內使用的集合項(item)和索引(index)變數。foreach 是動態 SQL 中

for循環和foreach循環集合的效率比較

tro [] exceptio each循環 手冊 代碼 val str print 先上代碼 package com.test; import java.util.ArrayList; import java.util.LinkedList; import java.

foreach和Iterator集合的方法

package TestMap; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * Created by Adm

mybatis集合List和陣列Array

一、遍歷集合 1.不用註解 public void insertList(List<User> users); <insert id="insertList" parameterType="java.util.List" > insert int

如何實現集合的過程中刪除其中的元素

為了進行測試,下面是取自MatLab中的一段小程式,其中第2行是計算集合的長度,第三行是從後往前遍歷集合的MatLab專用語法,第5行是刪除第j個元素。 function res = testDel

mybatis中的三種 批量操作資料的方法

方法1: 使用for迴圈在java程式碼中insert (不推薦) 方法2: 使用在Mapper.xml當中使用 foreach迴圈的方式進行insert PersonDao.java檔案 publi

linkedlist中集合中的元素foreachIterator的用法

package sec03; import java.util.Iterator; import java.util.LinkedList; public class TestIterator { public static void main(String[] args) { &nbs

Mybatis foreach集合的key和value

以動態order by為例,即通過if和foreach標籤動態拼接order by的排序欄位 Mapper.xml <select id="dynamicOrder" resultType="com.p7.demo.model.Person"> select * f

Mybatis查詢 ——foreach

變量 path ued pan oid open 返回 int pre 第一步:   在xxxMapper接口中添加一個函數,返回一個list,這裏的參數是一個integer類型的集合 public List<Emp> findEmpByList(@Param

Java基礎 - Map接口的實現類 : HashedMap / LinkedHashMap /TreeMap 的構造/修改// 集合視圖方法/雙向叠代輸出

順序 所有 collect int oid 代碼 修改 getc entryset Map筆記: import java.util.*; /**一:Collection接口的 * Map接口: HashMap(主要實現類) : HashedMap / Li

List的三個子類比較集合的方式

  ArrayList底層結構為陣列,查詢快,增刪慢,執行緒不安全,效率高。 Vector底層結構為陣列,查詢快,增刪慢,執行緒安全,效率低。 LinkedList的底層資料結構為連結串列,查詢慢,增刪快,執行緒不安全,效率高 遍歷: 首先,我們要先建一個類, 通過

c forEach 集合中的元素屬性詳解,判斷是否是最後一個元素,

分享一下我老師大神的人工智慧教程吧。零基礎,通俗易懂!風趣幽默!http://www.captainbed.net/ 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

JS方法forEach對比

// 找出未配置的策略欄位 let policy = { “ips”: 0, “waf”: 0, “pvs”: 1 }; let filterArr = Object.keys(policy).filter((key) => { return policy

JSP頁面通過c:forEach標籤迴圈List集合

<c:forEach>標籤有如下屬性: 屬性 描述 是否必要 預設值 items 要被迴圈的資訊 否 無 begin 開始的元素(0=第一個元素,1=第二個元素) 否 0 end 最後一個元

Java8 程式設計規範入門之【forEach方法集合

在Java中我們需要處理Clloection的時候,通常需要建立一個Iterator例項來對集合進行迭代,在迭代中對每個或者某些元素進行業務邏輯的操作。如果迭代使用不當的話,則會丟擲ConcurrentModificationException異常。 舊API、新的forEach API進行遍歷列印集合中的

c:forEach 標籤中map集合

java 後臺map 集合封裝 List<RoleRight> list = rrmapper.selectByROID(String.valueOf(role)); Map<String, List<Right>> map = new H

深度優先DFS 廣度優先BFS(java實現

圖的遍歷方式有倆種: 深度優先遍歷(DFS) 廣度優先遍歷(BFS) (1)深度優先遍歷(利用棧和遞迴來實現) 思路:先以一個點為起點,這裡假如是點A,那麼就將A相鄰的點放入堆疊,然後在棧中再取出棧頂的頂點元素(假如是點B),再將B

HashSetTreeSetjava的集合框架

   物件儲存在HashSet之前,要先確保物件重寫equals()和hashCode()方法,這樣才能比較物件的值是否相等,以確保set中沒有儲存相等的物件。如果我們沒有重寫這兩個方法,將會使用這個方法的預設實現。 Set的遍歷 Set<String> se

Java基礎之你會在foreach集合時進行remove操作嗎?

當通過for迴圈遍歷集合時,一般禁止操作(add or remove)集合元素。雖然開發規範裡寫的非常清楚,但最近還是有人掉坑裡導致出了一個小BUG,那我們就一起看看這麼做到底會發生什麼? 小例子 程式碼示例 List<String>