Skip to content

Dialect

複数のDBを対象とするアプリケーションを作成する場合、DB毎のSQL文法の差異を吸収するため アプリケーションで対象DBを判定し実行するSQLファイルを切り替える、といった対応が必要になります。 uroboroSQLでは、こういったDB毎のSQL文法の差異に対応するため、Dialectという仕組みを提供しています。
Dialectは接続したDBから取得できる情報を元に自動で判別される為、通常は変更する必要はありません。

現在、標準で以下のDBに対するDialectが提供されています。

DB名Dialect
H2 DBH2Dialect
Microsoft SQL ServerMsSqlDialect
MySQLMySqlDialect
Oracle10g以下Oracle10Dialect
Oracle11gOracle11Dialect
Oracle12c以上Oracle12Dialect
PostgresqlPostgresqlDialect
その他DefaultDialect

WARNING

該当するDBが見つからない場合はDefaultDialectが適用されます

カスタムDialectの登録

標準でサポートしている上記のDB以外に接続し、DefaultDialectと違う動作をさせたい場合は、対象のDBに対するDialectクラスを作成してuroboroSQLに登録する必要があります。

Dialectの登録には、Javaの java.util.ServiceLoaderを利用します。

最初に対象のDB(ここではSQLiteとする)に対するDialectクラスを作成します。

java
package foo.bar.dialect;

public class SqliteDialect extends AbstractDialect {
  /**
   * コンストラクタ
   */
  public SqliteDialect() {
    super();
  }

  @Override
  public String getDatabaseName() {
    return "SQLite";  // 対象DBの製品名を特定するための文字列を返す
  }

  // supportsXXXメソッド、isXXXメソッド、getXXXメソッドを必要に応じて実装
}

Dialectインタフェースで提供すべきメソッドは以下になります。

メソッド名戻り値説明
supportsBulkInsert()booleanBULK INSERTをサポートするかどうか
supportsLimitClause()booleanLIMIT句をサポートするかどうか
supportsOptimizerHints() 0.18.0+booleanオプティマイザーヒントをサポートするかどうか
supportsNullValuesOrdering()booleanSELECT句のORDER BYでNULL値の順序を指定できるか(NULLS FIRST/LAST)
supportsIdentity()booleanデータベースのIDカラムを使用したID自動採番をサポートしているか
supportsSequence()booleanデータベースのシーケンスを使用したID自動採番をサポートしているか
supportsForUpdate()boolean明示的な行ロックをサポートしているか
supportsForUpdateNoWait()boolean明示的な行ロック(待機なし)をサポートしているか
supportsForUpdateWait()boolean明示的な行ロック(待機あり)をサポートしているか
isRemoveTerminator()boolean実行するSQLに記述されている終端文字(;)を削除するかどうか
isRollbackToSavepointBeforeRetry()booleanリトライする前に設定したSavepointまでロールバックするかどうか
getSequenceNextValSql(String sequenceName)Stringシーケンスを取得するためのSQL文を取得する
getLimitClause(long limit, long offset)StringLIMIT句(とOFFSET句)を取得する
escapeLikePattern(CharSequence pattern)StringLIKE演算子のパターン文字列をエスケープする
getJavaType(JDBCType jdbcType, String jdbcTypeName)JavaType引数で渡ってきたJavaTypeを変換したJavaTypeを取得する。(DB固有のJava型変換を行う場合に実装)
getJavaType(int jdbcType, String jdbcTypeName)JavaType引数で渡ってきたJavaTypeを変換したJavaTypeを取得する。(DB固有のJava型変換を行う場合に実装)
getDatabaseName()Stringデータベースを判別するための文字列を取得する
getDatabaseType()Stringデータベースの種別を表す名前を取得する
getEscapeChar()charLIKE句で指定するエスケープキャラクタを取得する
addForUpdateClause(StringBuilder sql, ForUpdateType forUpdateType, int waitSeconds)StringBuilderFOR UPDATE句の文字列をSQLに追加する
addOptimizerHints(StringBuilder sql, List<String> hints) 0.18.0+StringBuilder引数で渡したSQLにオプティマイザーヒントを付与する
getModLiteral(final String dividend, final String divisor) 0.17.0+StringBuilder乗除を行うためのSQL文字列を取得する
getPessimisticLockingErrorCodes() 0.18.2+Set<String>悲観ロックのErrorCode もしくは SqlStateを取得する

Dialectインタフェースのデフォルト実装やAbstractDialectクラスを参考に、上記のメソッドのうち変更が必要なメソッドの実装を行ってください。

次にuroboroSQLを利用するアプリケーションのクラスパス上に以下のファイル名のファイルを作成します。

txt
META-INF
  └─services
      └─jp.co.future.uroborosql.dialect.Dialect

最後に作成したjp.co.future.uroborosql.dialect.Dialectファイルの中に作成したDialectのクラス名(FQDN名)を記述します。

md
foo.bar.dialect.SqliteDialect

アプリケーションでjp.co.future.uroborosql.dialect.DialectServiceLoader経由で読み込まれれば登録したSqliteDialectが利用可能になります。