Recevez les mises à jour gratuites du blog par Email : »» Garanti sans spam indésirable ««

MySQL : Récupérer l’auto-increment lors d’une insertion avec Spring DAO

de Mimie le 15 février 2010

Rubrique : Programmation

Besoin

Cet article est plus une astuce qu’autre chose, il montre le code à mettre en place pour récupérer l’identifiant « auto-increment » de votre table une fois l’objet inséré en base de données.


Sous Oracle Database avec les séquences, cela est plus simple, il suffit de récupérer l’attribut « nextval » de votre séquence avant l’insertion ou l’attribut « currval » après l’insertion : select votre_sequence.nextval from dual.

Sous MySQL, aucun moyen direct de récupérer cette valeur une fois la donnée insérée ou avant l’insertion, en tout cas pas à ma connaissance.

La solution présentée utilise Spring DAO et fonctionne avec les séquences et les auto-increment.

Avant

Voici la méthode update() de la classe JdbcTemplate que j’utilisais et qui ne me permettait pas d’obtenir la nouvelle valeur technique incrémentée :

public class CardDaoImpl extends JdbcDaoSupport implements CardDao {
public void insertCard(CardBatch card) throws DataAccessException {
String QUERY_INSERT_CARD =
"INSERT INTO MTG_CARD (WIZARD_ID, IMAGE, NAME, MANA_COST) " +
"VALUES (?, ?, ?, ?)";
getJdbcTemplate().update(
QUERY_INSERT_CARD,
new Object[] {
card.getWizardId(), card.getImageBytes(), card.getName(), card.getManaCost()
},
new int[] {
Types.INTEGER, Types.BLOB, Types.VARCHAR, Types.VARCHAR
}
);
}
}

Après

Voici à présent la bonne méthode update() qu’il faut utiliser en lui ajoutant un attribut de type KeyHolder qui permet de stocker la clé générée par l’insertion de l’objet en base.

A noter l’utilisation impérative de la classe NamedParameterJdbcDaoSupport qui permet l’utilisation de cette nouvelle méthode update() qui n’existe pas dans la classe JdbcDaoSupport :

public class CardDaoImpl extends NamedParameterJdbcDaoSupport implements CardDao {
@Override
public void insertCard(CardBatch card) throws DataAccessException {
String QUERY_INSERT_CARD =
"INSERT INTO MTG_CARD (WIZARD_ID, IMAGE, NAME, MANA_COST,) " +
"VALUES (:wizardId, :imageBytes, :name, :manaCost)";
// this method because we need to retrieve technical id (sequence or increment automatic)
SqlParameterSource fileParameters = new BeanPropertySqlParameterSource(card);
KeyHolder keyHolder = new GeneratedKeyHolder();
getNamedParameterJdbcTemplate().update(QUERY_INSERT_CARD, fileParameters, keyHolder);
card.setId(keyHolder.getKey().intValue());
}
}

Cet article a été écrit par :

– qui a déjà rédigé 123 posts sur Des Geeks et des lettres.

Passionné d'informatique et développeur JavaEE de métier, je me consacre principalement à écrire des billets sur les sujets du Web et de la programmation Web. Ce blog est un espace qui me permet de partager mes découvertes avec vous et me sert accessoirement de pense bête !

Contacter l'auteur

Jetez aussi un oeil sur :

{ 5 commentaires… à vous de vous exprimer ! }

1 Greg février 16, 2010 à 9 h 30 min

Article diggué :)

Répondre

2 logisim mai 18, 2010 à 9 h 40 min

La requête MySQL pour récupérer l’auto incrément : SELECT LAST_INSERT_ID();
Mais cette solution est bien meilleure !

Répondre

3 Mimie mai 18, 2010 à 9 h 48 min

Merci logisim pour la requête, mais l’idée était justement de ne pas avoir à effectuer une nouvelle requête en base. Au plaisir de te relire.

Répondre

4 logisim mai 18, 2010 à 9 h 51 min

C’était en réponse à la phrase « Sous MySQL, aucun moyen direct de récupérer cette valeur une fois la donnée insérée ou avant l’insertion, en tout cas pas à ma connaissance. », alors qu’il y avait la requête Oracle correspondante juste au-dessus…
Ça peut quand même être bien pratique à partir d’un langage qui ne gère pas ces mécanismes… si les transactions sont bien gérées !

Répondre

5 Mimie mai 18, 2010 à 10 h 07 min

Tu as tout à fait raison, c’est un bon moyen sous MySQL de récupérer cet identifiant que je ne connaissais pas :)

Répondre

Laissez un Commentaire

Article précédent:

Article suivant: