2010-05-20 4 views
2

J'utilise Spring HibernateTemplate et j'ai besoin d'insérer des centaines d'enregistrements dans une base de données mysql toutes les secondes.Insertions Mysql multivaleurs utilisant HibernateTemplate

Vous ne savez pas quelle est la manière la plus performante de le faire, mais j'essaie de voir comment les insertions multi-mysql utilisent hibernate.

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

Mais je reçois cette erreur: « ne pouvait pas exécuter la requête de manipulation en vrac natif ». S'il vous plaît vérifier votre requête .....

Toute idée de je peux utiliser un insert mysql multi-valeur en utilisant Hibernate? ou ma requête est-elle incorrecte?

D'autres façons d'améliorer les performances? J'ai essayé la méthode saveOrUpdateAll(), et ce n'était pas assez bon!

+0

Avez-vous trouvé une solution pour cela? –

+1

Je suis sûr que votre code réel ne fait pas cela, mais utilise plutôt des instructions préparées, sinon vous allez souffler le cache de requête hors de l'eau ... et vous vous laissez ouvert à l'injection sql partout. cf Petites Tables Bobby. (http://xkcd.com/327/) – time4tea

+0

+1 pour la référence Bobby Tables –

Répondre

1

De section 14.1 de docs Hibernate:

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

Alors, vous auriez besoin de pouvoir passer dans la collection de tuples que vous essayez de persister, les construire comme des objets persistants, puis enregistrez, bouffées de chaleur à un intervalle désiré. Si ce n'est pas suffisant, je suggère Hibernate est une solution minable pour ce que vous essayez de faire.

0

J'ai tendance à n'utiliser Hibernate que pour les opérations sur un seul objet.

Pour les quantités de données de taille moyenne, comme dans les rapports, j'aime Spring JdbcTemplate. Pour les encarts de très grande taille, je génère un fichier d'entrée avec des valeurs séparées par des tabulations (après avoir filtré les onglets hors données) et j'utilise le programme de shell fourni par la base de données, tel que mysqlimport de MySql. Les deux étapes peuvent être exécutées par différentes machines pour s'adapter à un grand volume de données importées.

+0

Pourquoi utiliser shell? –

+0

L'exécution de mysqlimport était la méthode la plus rapide pour trouver les données dans la base de données. Le temps nécessaire à la préparation du fichier d'entrée a été passé sur une autre machine. Cette solution a donc été améliorée pour plusieurs tâches d'importation. – ebelisle

-1

HibernateTemplate a une méthode bulkUpdate qui devrait fonctionner pour cette

+0

Ceci utilise HQL, Langali l'essaie via SQL. S'il vous plaît lire la documentation. –

+0

Varun a raison. En outre, HQL (JPAQL) ne prend pas en charge INSERT. –

0

Nous utilisons iBatis pour obtenir DML haute performance sur mySQL. C'est mieux que JDBC depuis un autre niveau d'abstraction. iBatis a une opération par lots, qui comprend également des insertions.

Il suffit de créer une autre interface DAO spécifique pour ce cas, et de l'implémenter en utilisant iBatis (FooSQLMap qui imbrique FooDAO). Vous pouvez appeler le nouveau FooDAO à partir de votre service, ce qui le rend invisible pour votre appelant.

0

Je suis d'accord avec Matthew Flynn. Il n'y a pas grand intérêt à utiliser Hibernate si vous allez tout simplement aller directement à JDBC. Si vos objets sont mappés en tant qu'entités, vous pouvez simplement les conserver en utilisant session.save() par lots, vidant et effaçant la session de temps en temps pour ne pas manquer de mémoire.

Questions connexes