Spring Data JDBC – Generieren von Primärschlüsseln mit Sequenzen / Sudo Null IT News

Standardmäßig erwartet Spring Data JDBC, dass Entitätsprimärschlüssel auf der Datenbankseite generiert werden. Im Artikel Einführung in Spring Data JDBC (Introduction to Spring Data JDBC) Wir haben die Spaltenoption Auto-Increment verwendet, und in diesem Artikel werden wir uns eine andere Möglichkeit ansehen – die Verwendung von Sequenzen (sequence).

Spring Data JDBC kann natürlich auch damit umgehen, aber Sie müssen etwas mehr Code schreiben: Holen Sie sich den nächsten Sequenzwert aus der Datenbank und setzen Sie den Primärschlüssel, bevor Sie die Entität in der Datenbank speichern. Dies kann durch Implementieren von BeforeConvertCallback erfolgen.

Implementierung von BeforeConvertCallback

Möglicherweise sind Sie bereits mit dem Callback-Mechanismus in anderen Spring Data-Modulen vertraut. Die Entity Callback API wurde in Spring Data Commons 2.2 eingeführt und ist die offiziell empfohlene Möglichkeit, Entitäten vor oder nach bestimmten Lebenszyklusereignissen zu ändern. In Spring Data JDBC können Sie diesen Mechanismus verwenden, um beim Speichern einer neuen Entität einen Sequenzwert abzurufen.

Verwenden wir diesen Ansatz, um den Primärschlüsselwert automatisch abzurufen, bevor das ChessGame-Aggregat gespeichert wird.

public class ChessGame { @Id private Long id; private StreicherWeiß; privater StreicherSchwarz; Private List Züge = neue ArrayList<>(); …}

Das folgende Beispiel speichert ohne zusätzliche Konfiguration das ChessGame-Aggregat und wartet darauf, dass der Primärschlüssel auf der Datenbankseite generiert wird. Wie bereits erwähnt, erfolgt dies normalerweise mit einer Autoinkrement-Spalte.

ChessGame game = new ChessGame(); game.setPlayerWhite(“Thorben Janssen”); game.setPlayerBlack(“Ein starker Spieler”); ChessMove move1white = new ChessMove(); move1white.setMoveNumber(1); move1white.setColor (MoveColor.WHITE); move1white.setMove(“e4”); game.getMoves().add(move1white); ChessMove move1Black = new ChessMove(); move1Black.setMoveNumber(1); move1Black.setColor (MoveColor.SCHWARZ); move1Black.setMove(“e5”); game.getMoves().add(move1Black); gameRepo.save (Spiel);

Diese Schlüsselgenerierungsoption passt nicht zu uns, also schreiben wir unseren eigenen BeforeConvertCallback. Dieser Callback wird ausgeführt, bevor das ChessGame in der Datenbank gespeichert wird.

Die Implementierung des Callbacks ist recht einfach. Sie müssen die BeforeConvertCallback-Schnittstelle implementieren und mit Ihrem Entitätstyp parametrisieren.

@Component öffentliche Klasse GetSequenceValueCallback implementiert BeforeConvertCallback { Private Logger log = LogManager.getLogger(GetSequenceValueCallback.class); privates Finale JdbcTemplate jdbcTemplate; public GetSequenceValueCallback(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public ChessGame onBeforeConvert(ChessGame game) { if (game.getId() == null) { log.info(“Nächsten Wert aus einer Datenbanksequenz abrufen und als Primärschlüssel verwenden”); Long id = jdbcTemplate.query(“SELECT nextval(‘chessgame_seq’)”, rs -> { if (rs.next()) { return rs.getLong(1); } else { throw new SQLException(“Wert kann nicht abgerufen werden aus der Sequenz chessgame_seq.”); } }); game.setId(id); } Rückspiel; } }

Die Schnittstellenimplementierung muss einen Konstruktor definieren, der ein JdbcTemplate akzeptiert. Wir können das empfangene JdbcTemplate in der Implementierung der onBeforeConvert-Methode verwenden.

Spring Data JDBC führt BeforeConvertCallback sowohl für INSERT- als auch für UPDATE-Vorgänge aus. Daher sollten Sie in der onBeforeConvert-Methode den Primärschlüssel auf null prüfen. Im Fall von null weisen wir dem Primärschlüssel einen neuen Wert zu. Der Wert des Schlüssels wird durch Ausführen einer SQL-Abfrage über JdbcTemplate abgerufen.

Das ist alles dazu. Wenn Sie das obige Beispiel erneut ausführen, sehen Sie die Meldungen von GetSequenceValueCallback und die SQL-Anweisung zum Abrufen des Sequenzwerts im Protokoll.

16:00:22.891 INFO 6728 – – [ main] ctjmodel.GetSequenceValueCallback : Ruft den nächsten Wert aus einer Datenbanksequenz ab und verwendet ihn als Primärschlüssel 16:00:22.892 DEBUG 6728 – – [ main] osjdbc.core.JdbcTemplate : SQL-Abfrage wird ausgeführt [SELECT nextval(‘chessgame_seq’)]
16:00:22.946 DEBUG 6728 – – [ main] osjdbc.core.JdbcTemplate : Vorbereitetes SQL-Update wird ausgeführt 16:00:22.947 DEBUG 6728 – – [ main] osjdbc.core.JdbcTemplate : Ausführen einer vorbereiteten SQL-Anweisung [INSERT INTO “chess_game” (“id”, “player_black”, “player_white”) VALUES (?, ?, ?)]
16:00:22.969 DEBUG 6728 – – [ main] osjdbc.core.JdbcTemplate : SQL-Update ausführen und generierte Schlüssel zurückgeben 16:00:22.970 DEBUG 6728 – – [ main] osjdbc.core.JdbcTemplate : Ausführen einer vorbereiteten SQL-Anweisung [INSERT INTO “chess_move” (“chess_game”, “chess_game_key”, “color”, “move”, “move_number”) VALUES (?, ?, ?, ?, ?)]
16:00:22.979 DEBUG 6728 – – [ main] osjdbc.core.JdbcTemplate : SQL-Update ausführen und generierte Schlüssel zurückgeben 16:00:22.980 DEBUG 6728 – – [ main] osjdbc.core.JdbcTemplate : Ausführen einer vorbereiteten SQL-Anweisung [INSERT INTO “chess_move” (“chess_game”, “chess_game_key”, “color”, “move”, “move_number”) VALUES (?, ?, ?, ?, ?)]

Schlussfolgerungen

Spring Data JDBC erwartet standardmäßig, dass der Primärschlüssel auf der Datenbankseite generiert wird. Häufig wird dafür eine Auto-Increment-Spalte verwendet.

In diesem Artikel haben wir uns angesehen, wie Sie unseren eigenen Primärschlüsselwertgenerator erstellen, indem Sie BeforeConvertCallback implementieren. Spring Data JDBC ruft es automatisch auf, wenn Sie ein Aggregat speichern und aktualisieren, daher müssen Sie prüfen, ob ein neuer Primärschlüsselwert generiert werden muss. Sie können den nächsten Sequenzwert aus der Datenbank abrufen, indem Sie eine SQL-Abfrage mit JdbcTemplate ausführen.

Wir laden alle zu einer offenen Lektion “Garbage Collector in Java” ein, in der wir Folgendes besprechen werden:
– Java-Speichermodell;
– 3 Stufen und 2 Generationen der Garbage Collection;
– Karriere und Tod von Objekten.
Anmeldung zum Unterricht.

Similar Posts

Leave a Reply

Your email address will not be published.