MyBatis批量插入數據到MySql數據庫

由於項目需要生成數萬條數據持久化到數據庫當中,然後就在程序中封裝了一個List集合對象,需要把該集合中的實體插入到數據庫中,應該要比循環對象一個一個插入的效果更好吧,這個肯定不是最優的方法,但應該可以能減少和數據庫連接吧,由於才疏學淺,有什麼更好的辦法進行大量數據插入到數據庫中,一定要賜教啊!

具體看代碼吧:

Controller層代碼:

 /**
     * 新增和修改的數據進行保存
     * @param festivalbeforeJson
     * @return
     */
    @RequestMapping(value="/save", produces = MediaType.APPLICATION_JSON_VALUE)
    public Map<String, Object> save() {
        Map<String, Object> modelMap = new HashMap<>();

        List<StorageFestivalbeforeCheck> data = new ArrayList<StorageFestivalbeforeCheck>();
        //向數據庫插入120000條記錄
        for (int i=1; i<=120000; i++) {
           data.add(getFestivalbefore(i));
        }
        System.out.println("查看List集合存放了多少條記錄。。。。。。。。"+data.size());

        long beginTime = System.currentTimeMillis();
        System.out.println("。。。。。。。。。。。開始插入。。。。。。。。。。。。。");
        int a = 3000;//每次提3000條
        int loop = (int) Math.ceil(data.size() / (double) a);

        List<StorageFestivalbeforeCheck> tempList = new ArrayList<StorageFestivalbeforeCheck>(a);
        int start, stop;
        for (int i = 0; i < loop; i++) {
           tempList.clear();
            start = i * a;
            stop = Math.min(i * a + a - 1, data.size() - 1);
            System.out.println("range:" + start + " - " + stop);
            for (int j = start; j <= stop; j++) {
               tempList.add(data.get(j));
            }

            festivalbeforeCheckService.saveList(tempList);
            System.out.println("已經插入" + (stop + 1) + " 條");
        }
        modelMap.put("status", "success");


        long endTime = System.currentTimeMillis();
        System.out.println("。。。。。。。。。。插入完成,耗時 " + (endTime - beginTime) + " 毫秒!。。。。。。。。。");



        return modelMap;
    }

 或者使用下面的更加簡便的方法:

 @RequestMapping(value="/save", produces = MediaType.APPLICATION_JSON_VALUE)
    public Map<String, Object> save() {
        Map<String, Object> modelMap = new HashMap<>();
        int pageCount = 0;
List<StorageFestivalbeforeCheck> data = new ArrayList<StorageFestivalbeforeCheck>();
        //向數據庫插入120000條記錄
        for (int i=1; i<=120000; i++) {
           data.add(getFestivalbefore(i));
        }
        List<List<StorageFestivalbeforeCheck>> allOrdersList = Lists.partition(data , 3000);
        for (List<StorageFestivalbeforeCheck> tempOrderList : allOrdersList) {
            if(CollectionUtils.isNotEmpty(tempOrderList)){
                festivalbeforeCheckService.saveList(tempOrderList);
                pageCount++;
                if(tempOrderList.size() == 3000){
                    logger.info("已經插入條數:{}", pageCount * 3000);
                }else{
                    logger.info("已經插入條數:{}", ((pageCount-1) * 3000 + tempOrderList.size()) );
                }
            }
        }
         return modelMap;
    }
 //設置保存的記錄
    public StorageFestivalbeforeCheck getFestivalbefore(int i) {
         StorageFestivalbeforeCheck festivalbeforeCheck = new StorageFestivalbeforeCheck();
         festivalbeforeCheck.setHouseId(i);
         festivalbeforeCheck.setOrgId(11);
         festivalbeforeCheck.setCheckDate(new Date());
         festivalbeforeCheck.setCheckPerson("孫悟空");
         festivalbeforeCheck.setCheckRecord(1);
         festivalbeforeCheck.setImplementCase(0);
         festivalbeforeCheck.setDutyArrangement(1);
         festivalbeforeCheck.setOperationArrangement(1);
         festivalbeforeCheck.setLeadSystem(0);
         festivalbeforeCheck.setSafetyEducation(1);
         festivalbeforeCheck.setCleaningDrain(1);
         festivalbeforeCheck.setEmergencyFacilities(0);
         festivalbeforeCheck.setEmergencyPlan(1);
         festivalbeforeCheck.setProblem("發現有漏水情況"+i);
         festivalbeforeCheck.setOpinion("必須趕緊完善"+i);
         return festivalbeforeCheck;
    }

xxxMapper.xml: 

  <insert id="saveList" parameterType="java.util.List">
     insert into storage_festivalbefore_check (
        id, house_id, org_id,
        check_date, check_person, check_record,
        implement_case, duty_arrangement, operation_arrangement,
        lead_system, safety_education, cleaning_drain,
        emergency_facilities, emergency_plan, problem,
        opinion
     )
     VALUES
       <foreach collection="list" item="item" index= "index" separator =",">
         (
           #{item.id,jdbcType=INTEGER}, #{item.houseId,jdbcType=INTEGER}, #{item.orgId,jdbcType=INTEGER},
           #{item.checkDate,jdbcType=TIMESTAMP}, #{item.checkPerson,jdbcType=VARCHAR}, #{item.checkRecord,jdbcType=INTEGER},
           #{item.implementCase,jdbcType=INTEGER}, #{item.dutyArrangement,jdbcType=INTEGER}, #{item.operationArrangement,jdbcType=INTEGER},
           #{item.leadSystem,jdbcType=INTEGER}, #{item.safetyEducation,jdbcType=INTEGER}, #{item.cleaningDrain,jdbcType=INTEGER},
           #{item.emergencyFacilities,jdbcType=INTEGER}, #{item.emergencyPlan,jdbcType=INTEGER}, #{item.problem,jdbcType=VARCHAR},
           #{item.opinion,jdbcType=VARCHAR}
         )
       </foreach>
  </insert>

xxxMapper.java(部分)

void saveList(List<StorageFestivalbeforeCheck> festivalbeforeList);

下面是Mybatis中關於foreach的介紹(從網上查看並根據自己的理解整理的):

foreach的主要用在構建in條件中,它可以在SQL語句中進行迭代一個集合。

foreach元素的屬性主要有 item,index,collection,open,separator,close。

item表示集合中每一個元素進行迭代時的別名,index指定一個名字,用於表示在迭代過程中,每次迭代到的位置,open表示該語句以什麼開始,separator表示在每次進行迭代之間以什麼符號作爲分隔 符,close表示以什麼結束,在使用foreach的時候最關鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,但是在不同情況 下,該屬性的值是不一樣的,主要有一下3種情況:

1.如果傳入的是單參數且參數類型是一個List的時候並且List中保存時實體類對象,collection屬性值爲list,如上面的代碼案例;如果List中存放的是Integer這種的封裝類型,則collection屬性值就是你定義的屬性參數名稱,比如:

List<StorageFestivalbeforeCheck> selectIds(@Param("Ids") List<Integer> Ids);

 <select id="selectIds" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from storage_festivalbefore_check
        <where>
            id in
            <foreach collection="Ids" item="item" open="(" separator="," close=")">
                #{item}
            </foreach>
        </where>
        ORDER BY create_time DESC
    </select>

2.如果傳入的是單參數且參數類型是一個array數組的時候,collection的屬性值爲array

3.如果傳入的參數是多個的時候,我們就需要把它們封裝成一個Map了,當然單參數也可以封裝成map

使用批量插入執行的SQL語句應該等價於:

insert into storage_festivalbefore_check
 ( id, house_id, org_id, check_date, check_person, check_record, implement_case, duty_arrangement, operation_arrangement, lead_system, safety_education, cleaning_drain, emergency_facilities, emergency_plan, problem, opinion )
VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
,( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
,( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 
, ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章