MyBatis Batch Insert/Update For Oracle

后端 未结 3 1113
日久生厌
日久生厌 2020-11-29 00:40

I\'ve recently started learning to use myBatis.I am now facing such a scenario, I need to constantly fetch a new list of Objects through WebService, then for this list, I ne

相关标签:
3条回答
  • 2020-11-29 01:24

    In my case also there is same scenario. I used for loop to check whether this record exists in databse or not and then according to that I added this object in to two arraylist for insert or update. And then used batch for insert and update after for loop for that to list.

    here is ex. for update according to different where condition

    1] this is for update

    <foreach collection="attendingUsrList" item="model"  separator=";">
        UPDATE parties SET attending_user_count = #{model.attending_count}
        WHERE  fb_party_id = #{model.eid}  
    </foreach>
    

    2] this is for insert

    <insert id="insertAccountabilityUsers" parameterType="AccountabilityUsersModel" useGeneratedKeys="false">
        INSERT INTO accountability_users 
            (
                accountability_user_id, accountability_id, to_username,
                record_status, created_by, created_at, updated_by, updated_at
            ) 
        VALUES
        <foreach collection="usersList" item="model" separator=","> 
            (           
                #{model.accountabilityUserId}, #{model.accountabilityId}, #{model.toUsername}, 
                'A', #{model.createdBy}, #{model.createdAt}, #{model.updatedBy}, #{model.updatedAt}     
            )
        </foreach>
    </insert>
    

    In dao method declare as

    void insertAccountabilityUsers(@Param("usersList") List<AccountabilityUsersModel> usersList);
    

    Update

    Here is my batch session code

    public static synchronized SqlSession getSqlBatchSession() {
        ConnectionBuilderAction connection = new ConnectionBuilderAction();
        sf = connection.getConnection();
        SqlSession session = sf.openSession(ExecutorType.BATCH);
        return session;
    }
    
    SqlSession session = ConnectionBuilderAction.getSqlSession(); 
    

    Actually I already given full example here for this question

    0 讨论(0)
  • 2020-11-29 01:35

    In oracle if you want to execute multiple statements at one time you have to enclose your statements in "begin" and "end" block. So try to add attributes to foreach as below. This will definitely work.

    
    <foreach collection="customerList" item="object" open="begin" close=";end;" separator=";">
        UPDATE customer SET isActive = #{object.isactive}
        WHERE  customerId= #{object.customerId}
    </foreach>
    
    0 讨论(0)
  • 2020-11-29 01:38

    The accepted answer is not the recommended way of handling batch operations. It does not show true batch statements since the batch executor mode should be used when opening a session. See this post in which a code contributor recommended that the proper way to batch update (or insert) is to open a session in batch mode and repeatedly call update (or insert) for a single record.

    Here's what works for me:

    public void updateRecords(final List<GisObject> objectsToUpdate) {
        final SqlSession sqlSession = MyBatisUtils.getSqlSessionFactory().openSession(ExecutorType.BATCH);
        try {
            final GisObjectMapper mapper = sqlSession.getMapper(GisObjectMapper.class);
            for (final GisObject gisObject : objectsToUpdate) {
                mapper.updateRecord(gisObject);
            }
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }
    

    Do not use foreach in your update/insert and ensure that it only updates/inserts a single record. I was running into unsolvable oracle errors by doing it according to the accepted answer (invalid character, statement not ended, etc.). As the linked post indicates, the update (or insert) shown in the accepted answer is actually just a giant sql statement.

    0 讨论(0)
提交回复
热议问题