SqlUpdate

SqlUpdateを使用すると、SQL INSERTSQL UPDATESQL DELETEを実行できます。

 

例: 簡易更新
String sql = "update audit_log set description = description where id = ?";

int row = DB.sqlUpdate(sql)
  .setParameter(1, 42)
  .execute();

 

例: getGeneratedKeysを使用した挿入
String sql = "insert into e_person_online (email, online_status, when_updated) " +
             "values (:email, :online, current_time)";

SqlUpdate sqlUpdate = DB.sqlUpdate(sql)
  .setGetGeneratedKeys(true)
  .setParameter("email", email)
  .setParameter("online", false);

sqlUpdate.execute();

Object key = sqlUpdate.getGeneratedKey();

 

コレクションのバインド

値のコレクション/配列をIN句にバインドするには、?1、?2、?3などのようなインデックス付きの位置パラメータまたは:ids、:namesなどのような名前付きパラメータを使用する必要があります。

// using ?1 index positioned parameter

String sql = "delete from customer where ref_id in (?1)";

int rows = DB.sqlUpdate(sql)
  .setParameter(asList(9991, 9992, 9993))
  .execute();
delete from customer where ref_id in (?,?,?)
// using :ids named parameter

String sql = "delete from customer where ref_id in (:ids)";

int rows = DB.sqlUpdate(sql)
  .setParameter("ids", asList(9991, 9992, 9993))
  .execute();
delete from customer where ref_id in (?,?,?)

 

例: 複数のリストのバインド
String sql = "delete from customer where ref_id in (:ids) and name in (:names)";

int rows = DB.sqlUpdate(sql)
    .setParameter("ids", asList(9991, 9992, 9993))
    .setParameter("names", asList("rob", "jim"))
    .execute();
delete from customer where ref_id in (?,?,?) and name in (?,?)

CTE - 共通テーブル式

共通テーブル式を使用してバルク更新を実行したい場合、これはSqlUpdateを使用する方法が最も簡単です。

CTEの例
String sql = """
WITH t AS (
    SELECT s.id AS _id
    FROM store_price s
    JOIN promotion_vw p ...
    WHERE ...
)
UPDATE store_price
SET promotion_price = null, price = active_price, price_reason = ?,
    version = version+1, when_modified = current_timestamp
FROM t
WHERE id = t._id
"""

int rows = DB.sqlUpdate(sql)
  .setParameter(1, "Expired promotions")
  .execute();

AddBatchとExecuteBatch

addBatch()executeBatch()を使用して、JDBCバッチを明示的に使用します。

String sql = "insert into audit_log (id, description, modified_description) values (?,?,?)";
SqlUpdate insert = DB.sqlUpdate(sql);

try (Transaction txn = DB.beginTransaction()) {

  insert.setNextParameter(10000);
  insert.setNextParameter("hello");
  insert.setNextParameter("foo");
  insert.addBatch();

  insert.setNextParameter(10001);
  insert.setNextParameter("goodbye");
  insert.setNextParameter("bar");
  insert.addBatch();

  insert.setNextParameter(10002);
  insert.setNextParameter("chow");
  insert.setNextParameter("baz");
  insert.addBatch();

  int[] rows = insert.executeBatch();

  txn.commit();
}

Upsert

データベース固有のUpsert SQLを実行できます。

Upsert - Postgres

String sql =
  "insert into e_person_online (email, online_status, when_updated) values (?, ?, now()) " +
  "on conflict (email) do update set when_updated=now(), online_status = ?";

String email = "foo@one.com";

Object key = DB.sqlUpdate(sql)
  .setGetGeneratedKeys(true)
  .setParameter(1, email)
  .setParameter(2, true)
  .setParameter(3, true)
  .executeGetKey();

 

Upsert - MySql

String email = "bar@one.com";

String sql =
  "insert into e_person_online (email, online_status, when_updated) values (?, ?, current_time) " +
  "on duplicate key update when_updated=current_time, online_status = ?";

Object key = DB.sqlUpdate(sql)
  .setGetGeneratedKeys(true)
  .setParameter(1, email)
  .setParameter(2, true)
  .setParameter(3, true)
  .executeGetKey();

L2キャッシュ

L2キャッシュが使用されている場合、Ebeanは自動的にどのようなテーブルの変更が実行されるか判断し、これをL2キャッシュの適切な部分が無効にされるように使用します。

これをオフにするにはsetAutoTableMod(false)を使用します。