Я не видел ни одного упомянутого выше, поэтому я просто хотел бы добавить возможное решение, которое позволит избежать нескольких запросов. Versioning .
Обычно используется как простой способ проверить, не устарела ли обновляемая запись в сценарии оптимистическая блокировка , столбцы, помеченные @ Version , также можно использовать для проверки возможности записи является постоянным (присутствует в БД) или нет.
Все это может показаться сложным, но на самом деле это не так. Это сводится к тому, что в записи есть дополнительный столбец, значение которого меняется при каждом обновлении. Мы определяем дополнительную версию столбца в нашей базе данных следующим образом:
CREATE TABLE example
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
version INT, -- <== It really is that simple!
value VARCHAR(255)
);
И пометьте соответствующее поле в нашем классе Java с помощью @Version
следующим образом:
@Entity
public class Example {
@Id
@GeneratedValue
private Integer id;
@Version // <-- that's the trick!
private Integer version;
@Column(length=255)
private String value;
}
Аннотация @Version заставит JPA использовать этот столбец с оптимистической блокировкой, включив его в качестве условия в любые операторы обновления, например:
UPDATE example
SET value = 'Hello, World!'
WHERE id = 23
AND version = 2 -- <-- if version has changed, update won't happen
(JPA делает это автоматически, не нужно писать самостоятельно)
Затем он проверяет, была ли обновлена одна запись (как ожидалось) или нет (в этом случае объект устарел).
Мы должны убедиться, что никто не может установить поле версии, иначе это может испортить оптимистическую блокировку, но мы можем сделать геттер на version
, если захотим. Мы также можем использовать поле версии в методе isPersistent
, который проверит, находится ли запись в БД уже или нет, не выполняя запрос:
@Entity
public class Example {
// ...
/** Indicates whether this entity is present in the database. */
public boolean isPersistent() {
return version != null;
}
}
Наконец, мы можем использовать этот метод в нашем insertOrUpdate
методе:
public insertOrUpdate(Example example) {
if (example.isPersistent()) {
// record is already present in the db
// update it here
}
else {
// record is not present in the db
// insert it here
}
}