S-JIS[2023-10-27]

Iceaxe JDBCとの比較

TsurugiIceaxe(Javaライブラリー)とJDBCの比較。


概要

TsurugiのDBにJavaでアクセスするためのライブラリーであるIceaxeは、JDBCではない。
しかしSQLを実行するという目的は同じなので、APIは似ている点もある。
(ただし、IceaxeがJDBCに似ているとしたら、Iceaxeが内部で使っているTsubakuroがJDBCに似ているせいだと思う。IceaxeはTsubakuroをラップしているだけなので)


JDBCとの比較

機能 Iceaxe JDBC 備考
セッション/コネクション String endpoint = "tcp://〜";
var credential = new UsernamePasswordCredential("user", "password");
var connector = TsurugiConnector.of(endpoint, credential);
try (var session = connector.createSession()) {
  〜
}
String jdbcUrl = "jdbc:〜";
try (var connection = DriverManager.getConnection(jdbcUrl, "user", "password")) {
  〜
}
 
トランザクション var txOption = TgTxOption.ofOCC();
try (var transaction = session.createTransaction(txOption)) {
  〜
}
JDBCではconnectionがトランザクションを兼ねている。 Iceaxeでは、ひとつのsessionから複数のtransactionを生成できる。
var txOption = TgTxOption.ofOCC();
var setting = TgTmSetting.ofAlways(txOption);
var tm = session.createTransactionManager(setting);
tm.execute(transaction -> {
  〜
});
コミット transaction.commit(TgCommitType.DEFAULT); connection.commit();  
ロールバック transaction.rollback(); connection.rollback();  
更新系SQL var sql = "update test set bar = 999";
try (var statement = session.createStatement(sql)) {
  int count = transaction.executeAndGetCount(statement);
}
var sql = "update test set bar = 999";
try (var statement = connection.createStatement()) {
  int count = statement.executeUpdate(sql);
}
 
select文 var list = new ArrayList<TestEntity>();
var sql = "select * from test";
try (var ps = session.createQuery(sql)) {
  List<TsurugiResultEntity> resultList = transaction.executeAndGetList(ps);
  for (var result : resultList) {
    var entity = new TestEntity();
    entity.setFoo(result.getInt("foo"));
    entity.setBar(result.getLongOrNull("bar"));
    entity.setZzz(result.getStringOrNull("zzz"));
    list.add(entity);
  }
}
var list = new ArrayList<TestEntity>();
var sql = "select * from test";
try (var statement = connection.createStatement()) {
  try (var rs = statement.executeQuery(sql)) {
    var entity = new TestEntity();
    int i = 1;
    entity.setFoo(rs.getInt(i++));
    entity.setBar(rs.getLong(i++));
    entity.setZzz(rs.getString(i++));
    list.add(entity);
  }
}
 
List<TestEntity> list;
var sql = "select * from test";
var resultMapping = TgResultMapping.of(TestEntity::new)
  .addInt("foo", TestEntity::setFoo)
  .addLong("bar", TestEntity::setBar)
  .addString("zzz", TestEntity::setZzz);
try (var query = session.createQuery(sql, resultMapping)) {
  list = transaction.executeAndGetList(query);
}
プリペアードステートメント
(更新系SQL)
TestEntity entity = 〜;
var sql = "insert into test values(:foo, :bar, :zzz)";
var parameterMapping = TgParameterMapping.of(TestEntity.class)
  .addInt("foo", TestEntity::getFoo).
  .addLong("bar", TestEntity::getBar).
  .addString("zzz", TestEntity::getZzz);
try (var ps = session.createStatement(sql, parameterMapping) {
  int count = transaction.executeAndGetCount(ps, entity);
}
TestEntity entity = 〜;
var sql = "insert into test values(?, ?, ?)";
try (var ps = connection.prepareStatement(sql)) {
  int i = 1;
  ps.setInt(i++, entity.getFoo());
  ps.setLong(i++, entity.getBar());
  ps.setString(i++, entity.getZzz());
  int count = ps.executeUpdate();
}
 
プリペアードステートメント
(select文)
List<TestEntity> list;
var foo = TgBindVariable.ofInt("foo");
var sql = "select * from test where foo = " + foo;
var parameterMapping = TgParameterMapping.of(foo);
var resultMapping = TgResultMapping.of(TestEntity::new)
  .addInt("foo", TestEntity::setFoo)
  .addLong("bar", TestEntity::setBar)
  .addString("zzz", TestEntity::setZzz);
try (var ps = session.createQuery(sql, parameterMapping, resultMapping)) {
var parameter = TgBindParameters.of(foo.bind(123));
  list = transaction.executeAndGetList(ps, parameter);
}
var list = new ArrayList<TestEntity>();
var sql = "select * from test where foo = ?";
try (var ps = connection.prepareStatement(sql)) {
  ps.setInt(1, 123);
  try (var rs = ps.executeQuery()) {
    var entity = new TestEntity();
    int i = 1;
    entity.setFoo(rs.getInt(i++));
    entity.setBar(rs.getLong(i++));
    entity.setZzz(rs.getString(i++));
    list.add(entity);
  }
}
 
 

JDBCではConnectionがトランザクションを兼ねている(commit/rollbackを実行すると次のトランザクションが始まる)が、
IceaxeではSessionとTransactionは分かれている。
それにより、IceaxeではひとつのSessionから複数のTransactionを生成することが出来る。(ただし通信経路はSession毎にひとつなので、大量のTransactionを作ると通信が詰まって遅くなる可能性がある)

JDBCでは、Statementの場合はStatementを作ってから実行時にSQLを指定する・PreparedStatementの場合は作成時にSQLを指定するが、
IceaxeではsessionからTsurugiSql(JDBCのStatement/PreparedStatement相当のクラス)を作る際にSQLを指定し、transactionにTsurugiSqlを渡して実行する形になっている。

プリペアードステートメントのバインド変数(プレースホルダー)は、JDBCでは「?」を使うが、Iceaxeでは「:変数名」で表す。
JDBCではPreparedStatementに値をセットして実行するが、Iceaxeでは実行メソッドの引数として値を渡す。


Iceaxeへ戻る / Tsurugiへ戻る / 技術メモへ戻る
メールの送信先:ひしだま