programing

Oracle용 MyBatis 배치 삽입/업데이트

minimums 2023. 7. 7. 18:52
반응형

Oracle용 MyBatis 배치 삽입/업데이트

저는 최근에 바티스 사용법을 배우기 시작했습니다.저는 지금 이러한 시나리오에 직면해 있습니다. 웹 서비스를 통해 계속해서 개체의 새 목록을 가져와야 합니다. 그런 다음 이 목록을 위해서는 각 개체를 myBatis를 통해 Oracle DB 테이블에 삽입/업데이트해야 합니다.

까다로운 부분은 단순히 매번 일괄 삽입을 할 수 없다는 것입니다. 일부 개체가 DB에 이미 존재할 수 있기 때문입니다. 이러한 레코드의 경우 새 삽입 대신 해당 개체의 필드를 업데이트해야 합니다.

현재 제 솔루션은 Java를 사용하여 웹 서비스에서 개체 목록을 작성하고 각 개체를 루프하고, null이 아닌 경우(이미 DB에 있음) myBatis 선택을 수행한 다음, myBatis 업데이트를 수행하고, 그렇지 않은 경우 이 새 개체에 대해 myBatis 삽입을 수행합니다.

기능이 달성됩니다.하지만 Java를 사용하여 for 루프를 수행하고 하나씩 삽입/업데이트를 수행하면 많은 시스템 리소스가 소모되기 때문에 효율성이 매우 낮다고 기술 리드가 말합니다.그는 나에게 나의 Batis를 이용하여 batch insert를 할 것을 제안했습니다. 객체의 목록을 전달하는 것입니다.

myBatis의 배치 삽입은 간단하지만, 단순히 삽입하는 것이 아니기 때문에(업데이트해야 하는 기존 레코드의 경우) 배치 삽입은 적합하지 않다고 생각합니다.이를 위해 잠시 구글을 검색해 본 결과, Oracle의 경우 "insert" 대신 "merge"를 사용해야 할 것 같습니다.

내 Batis에서 병합을 위해 검색한 예제는 배치가 아닌 하나의 개체에 대한 것입니다.따라서 전문가들이 MyBatis(매퍼를 작성하는 올바른 방법)에서 배치 병합을 수행하는 방법에 대한 몇 가지 예를 제공할 수 있는지 알고 싶습니다.

승인된 답변은 배치 작업을 처리하는 권장 방법이 아닙니다.세션을 열 때 배치 실행기 모드를 사용해야 하므로 실제 배치 문을 표시하지 않습니다.배치 업데이트(또는 삽입)의 올바른 방법은 배치 모드에서 세션을 열고 단일 레코드에 대해 업데이트(또는 삽입)를 반복적으로 호출하는 것이라고 코드 기여자가 권장한 이 게시물을 참조하십시오.

다음과 같은 이점이 있습니다.

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();
    }
}

업데이트/삽입에서 각각을 사용하지 말고 단일 레코드만 업데이트/삽입하도록 하십시오.승인된 답변(잘못된 문자, 종료되지 않은 문장 등)에 따라 처리함으로써 해결할 수 없는 오라클 오류가 발생했습니다.링크된 게시물에서 알 수 있듯이 수락된 답변에 표시된 업데이트(또는 삽입)는 실제로는 거대한 SQL 문에 불과합니다.

나의 경우에도 같은 시나리오가 있습니다.데이터베이스에 이 레코드가 있는지 확인하기 위해 루프를 사용한 다음, 삽입 또는 업데이트를 위해 두 개의 배열 목록에 이 개체를 추가했습니다.그런 다음 배치를 사용하여 삽입하고 이후에 업데이트를 통해 목록을 표시합니다.

여기는 다른 곳의 조건에 따른 업데이트를 위한 ex.입니다.

이것은 업데이트를 위한 것입니다.

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

삽입용입니다.

<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 메서드 선언:

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

갱신하다

내 배치 세션 코드입니다.

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

SqlSession session = ConnectionBuilderAction.getSqlSession(); 

사실 저는 이미 이 질문에 대한 완전한 예를 여기에 제시했습니다.

오라클에서 여러 문을 한 번에 실행하려면 문을 "시작" 및 "끝" 블록으로 묶어야 합니다.따라서 아래와 같이 각각의 속성을 추가해 보십시오.이것은 분명히 효과가 있을 것입니다.


<foreach collection="customerList" item="object" open="begin" close=";end;" separator=";">
    UPDATE customer SET isActive = #{object.isactive}
    WHERE  customerId= #{object.customerId}
</foreach>

언급URL : https://stackoverflow.com/questions/23486547/mybatis-batch-insert-update-for-oracle

반응형