2010-05-20 2 views
2

나는 Spring HibernateTemplate을 사용하고 매초 수백 개의 레코드를 mysql 데이터베이스에 삽입해야한다.HibernateTemplate을 사용한 다중 값 Mysql 삽입물

가장 성능이 좋은 방법은 무엇인지 모르겠지만 다중 값 mysql 삽입이 최대 절전 모드를 사용하는 방법을 확인하려고합니다.

String query = "insert into user(age, name, birth_date) values(24, 'Joe', '2010-05-19 14:33:14'), (25, 'Joe1', '2010-05-19 14:33:14')" 

getHibernateTemplate().execute(new HibernateCallback(){ 
public Object doInHibernate(Session session) throws HibernateException, SQLException { 
     return session.createSQLQuery(query).executeUpdate(); 
} 
}); 

는하지만이 오류 얻을 : '. 네이티브 대량 조작 쿼리를 실행할 수 없습니다' 을 질의를 확인하십시오 .....

최대 절전 모드를 사용하여 다중 값 mysql 삽입을 사용할 수 있다는 아이디어는 있습니까? 또는 내 쿼리가 올바르지 않습니까?

다른 어떤 방법으로 성능을 향상시킬 수 있습니까? saveOrUpdateAll() 메서드를 시도했지만 충분하지 않았습니다! 최대 절전 모드의 문서에서 section 14.1에서

+0

해결 방법을 찾으셨습니까? –

+1

저는 실제 코드가 그렇게하지 않지만 준비된 문장을 사용한다고 확신합니다. 그렇지 않으면 쿼리 캐시를 물 밖으로 날려 버릴 것입니다 ... 그리고 여러분은 SQL 인젝션을 마음껏 열어두고 있습니다. 작은 바비 테이블. (http://xkcd.com/327/) – time4tea

+0

+1 바비 테이블 참조 –

답변

1

: 그래서

Session session = sessionFactory.openSession(); 
Transaction tx = session.beginTransaction(); 
for (int i=0; i<100000; i++) { 
Customer customer = new Customer(.....); 
    session.save(customer); 

    if (i % 20 == 0) { //20, same as the JDBC batch size 

     //flush a batch of inserts and release memory: 

     session.flush(); 

     session.clear(); 
    } 
} 
tx.commit(); 
session.close(); 

, 당신은, 당신은 유지하려고하는 튜플의 수집 전달에 영구 객체로를 구성하고 저장 할 수 있어야 내리는 것 원하는 간격으로

이것이 적당하지 않다면, 나는 Hibernate가 당신이하려고하는 것에 대한 형편없는 해결책이라고 제안 할 것이다.

0

단일 개체 작업에만 Hibernate를 사용하는 경향이 있습니다.

중간 규모의 데이터 (예 : 보고서)에서 Spring JdbcTemplate을 좋아합니다.

매우 큰 배치 삽입물의 경우 탭 분리 값 (데이터 탭 제외)을 사용하여 입력 파일을 생성하고 데이터베이스가 일괄 입력을 제공하는 모든 쉘 프로그램 (예 : MySql의 mysqlimport)을 사용합니다. 이 두 단계는 대량의 가져온 데이터를 처리 할 수 ​​있도록 여러 컴퓨터에서 수행 할 수 있습니다.

+0

쉘을 사용해야하는 이유는 무엇입니까? –

+0

mysqlimport를 실행하는 것이 데이터를 데이터베이스로 가져 오는 가장 빠른 방법이었습니다. 입력 파일을 준비하는 데 걸리는 시간이 다른 컴퓨터에서 발생했기 때문에이 솔루션은 여러 가져 오기 작업에 맞게 확장되었습니다. – ebelisle

-1

HibernateTemplate에 우리는 MySQL을 통해 고성능 DML을 얻기 위해 iBatis를를 사용하는이

+0

이것은 HQL을 사용하고 있으며, Langali는 SQL을 통해이를 시도하고 있습니다. 설명서를 읽으십시오. –

+0

Varun이 맞습니다. 또한 HQL (JPAQL)은 INSERT를 지원하지 않습니다. –

0

을 위해 일해야 bulkUpdate 방법이있다. 그것은 다른 수준의 추상화 이후 JDBC보다 우수합니다. iBatis에는 배치가 포함되어 있으며 삽입 작업도 포함됩니다.

이 경우에만 다른 DAO 인터페이스를 지정하고 iBatis (FooDAO를 imlements하는 FooSQLMap)를 사용하여 구현해야합니다. 서비스에서 새 FooDAO로 전화를 걸면 서비스 발신자가 볼 수 없게됩니다.

0

나는 Matthew Flynn에 동의합니다. 어쨌든 JDBC로 곧바로 갈 것이라면 Hibernate를 사용하는 것이별로 중요하지 않다. 객체가 엔티티로 매핑 된 경우 일괄 처리로 session.save()를 사용하고 메모리를 모두 소모하지 않도록 세션을 너무 자주 비울 수 있습니다.