22 Stimmen

Wie man ids auf Inserts mit mybatis in mysql mit Anmerkungen zurückgeben

  • Siehe diese verwandte Frage für Postgres. Aus irgendeinem Grund funktioniert die Lösung bei mir nicht - der Rückgabewert der Insert-Anweisung ist immer "1".
  • Siehe diese andere Frage für eine XML-basierte Lösung . Ich möchte dasselbe ohne XML tun - einen Datensatz einfügen und die neue, automatisch generierte ID des gerade eingefügten Datensatzes finden.

Ich habe keine passende Bemerkung gefunden zu <selectkey> (siehe diese offene Frage ) Wie kann ich vorgehen?

Die Untersuchung des mybatis-Codes zeigt, dass INSERT ist implementiert über UPDATE und gibt immer die Anzahl der eingefügten Zeilen zurück! Also ... es sei denn, ich bin völlig etwas fehlt hier, gibt es keine Möglichkeit, dies mit der aktuellen (3.0.3) Implementierung zu tun.

36voto

Manur Punkte 8197

Tatsächlich ist es möglich, mit dem @Options Anmerkung (vorausgesetzt, Sie verwenden auto_increment oder etwas Ähnliches in Ihrer Datenbank) :

@Insert("insert into table3 (id, name) values(null, #{name})") 
@Options(useGeneratedKeys=true, keyProperty="idName")
int insertTable3(SomeBean myBean); 

Beachten Sie, dass die keyProperty="idName" Teil ist nicht erforderlich, wenn die Schlüsseleigenschaft in SomeBean "id" heißt. Es gibt auch eine keyColumn Attribut verfügbar, für die seltenen Fälle, in denen MyBatis die Primärschlüsselspalte nicht selbst finden kann. Bitte beachten Sie auch, dass durch die Verwendung von @Options Sie überlassen Ihre Methode einigen Standardparametern; es ist wichtig, das Dokument zu konsultieren (unten verlinkt -- Seite 60 in der aktuellen Version)!

(Alte Antwort) Die (recht neue) @SelectKey kann für komplexere Schlüsselabfragen (Sequenzen, identity()-Funktion...) verwendet werden. Hier ist, was die MyBatis 3 Benutzerhandbuch (pdf) bietet als Beispiele:

Dieses Beispiel zeigt die Verwendung der @SelectKey-Anmerkung, um einen Wert aus einer Sequenz abzurufen, bevor eine einfügen:

@Insert("insert into table3 (id, name) values(#{nameId}, #{name})") 
@SelectKey(statement="call next value for TestSequence", keyProperty="nameId", before=true, resultType=int.class) 
int insertTable3(Name name); 

Dieses Beispiel zeigt die Verwendung der @SelectKey-Anmerkung, um einen Identitätswert nach einer Einfügung abzurufen:

@Insert("insert into table2 (name) values(#{name})")
@SelectKey(statement="call identity()", keyProperty="nameId", before=false, resultType=int.class)
int insertTable2(Name name);

17voto

Daniel Novak Punkte 2680

Le site <insert> , <update> und <delete> Anweisungen geben die Anzahl der betroffenen Zeilen zurück, wie es bei Datenbank-APIs üblich ist.

Wenn eine neue ID für die eingefügte Zeile generiert wird, wird sie in dem Objekt, das Sie als Parameter übergeben haben, wiedergegeben. Wenn Sie also zum Beispiel mapper.insert(someObject) in Ihrer kommentierten Einfügemethode aufrufen, können Sie nach dem Einfügen someObject.getId (oder ähnlich) aufrufen, um die ID abzurufen.

Mit den Optionen von <insert> können Sie einstellen, wie (durch Angabe einer SQL-Anweisung) und wann (vor oder nach der eigentlichen Einfügung) die ID erzeugt oder abgerufen wird und wo im Objekt sie abgelegt wird.

Es kann aufschlussreich sein, die MyBatis-Generator um Klassen aus einem Datenbankschema zu generieren, und sehen Sie sich an, wie Einfügungen und Aktualisierungen gehandhabt werden. Der Generator erzeugt insbesondere "Beispielklassen", die als temporäre Container zur Weitergabe von Daten verwendet werden.

3voto

edwinkun Punkte 54

Können Sie Ihre generierten IDs über Speichermethoden abrufen, z.B. eine Bean mit den Eigenschaften ID und Name,

bean.setName("xxx");
mapper.save(bean);
// here is your id
logger.debug(bean.getID);

0voto

lance-java Punkte 23423

Die meisten Antworten, die ich online für die Rückgabe von generierten Schlüsseln gefunden habe, haben mir nicht gefallen, weil

  1. Alle Lösungen, die ich gefunden habe, riefen einen "Setter" für das eingehende Objekt auf
  2. Keine der Lösungen gab die generierte Spalte aus der Methode

Ich habe die folgende Lösung gefunden, die die Punkte 1 und 2 berücksichtigt

  1. Übergibt zwei Parameter an mybatis "in" & "out" (mybatis verändert "in" nicht, sondern ruft einen Setter auf "out" auf)
  2. Erfordert eine zusätzliche Standardmethode auf der Schnittstelle, um den Wert zurückzugeben

    public interface MyMapper { /**

    • this method is used by the mybatis mapper
    • I don't call this method directly in my application code
      */ @Insert("INSERT INTO MY_TABLE (FOO) VALUES ({#in.foo})") @Options(useGeneratedKeys=true, keyColumn="ID", keyProperty = "out.value") void insert(@Param("in") MyTable in, @Param("out") LongReference out);

      /**

      • this "default method" is called in my application code and returns the generated id. */ default long insert(MyTable tableBean) { LongReference idReference = new LongReference(); insert(tableBean, idReference); return idReference.getValue(); } }

Dies erfordert eine zusätzliche Klasse, die für ähnliche Methoden in Zukunft wiederverwendet werden kann

public class LongReference {
    private Long value;

    // getter & setter
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X