# Dialect
複数のDBを対象とするアプリケーションを作成する場合、DB毎のSQL文法の差異を吸収するため
アプリケーションで対象DBを判定し実行するSQLファイルを切り替える、といった対応が必要になります。
uroboroSQLでは、こういったDB毎のSQL文法の差異に対応するため、Dialect
という仕組みを提供しています。
Dialect
は接続したDBから取得できる情報を元に自動で判別される為、通常は変更する必要はありません。
現在、標準で以下のDBに対するDialectが提供されています。
DB名 | Dialect |
---|---|
H2 DB | H2Dialect (opens new window) |
Microsoft SQL Server | MsSqlDialect (opens new window) |
MySQL | MySqlDialect (opens new window) |
Oracle10g以下 | Oracle10Dialect (opens new window) |
Oracle11g | Oracle11Dialect (opens new window) |
Oracle12c以上 | Oracle12Dialect (opens new window) |
Postgresql | PostgresqlDialect (opens new window) |
その他 | DefaultDialect (opens new window) |
WARNING
該当するDBが見つからない場合はDefaultDialect
が適用されます
# カスタムDialectの登録
標準でサポートしている上記のDB以外に接続し、DefaultDialect
と違う動作をさせたい場合は、対象のDBに対するDialect
クラスを作成してuroboroSQLに登録する必要があります。
Dialect
の登録には、Javaの java.util.ServiceLoader (opens new window)を利用します。
最初に対象のDB(ここではSQLiteとする)に対するDialect
クラスを作成します。
package foo.bar.dialect;
public class SqliteDialect extends AbstractDialect {
/**
* コンストラクタ
*/
public SqliteDialect() {
super();
}
@Override
public String getDatabaseName() {
return "SQLite"; // 対象DBの製品名を特定するための文字列を返す
}
// supportsXXXメソッド、isXXXメソッド、getXXXメソッドを必要に応じて実装
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Dialect
インタフェースで提供すべきメソッドは以下になります。
メソッド名 | 戻り値 | 説明 |
---|---|---|
supportsBulkInsert() | boolean | BULK INSERT をサポートするかどうか |
supportsLimitClause() | boolean | LIMIT 句をサポートするかどうか |
supportsOptimizerHints() 0.18.0+ | boolean | オプティマイザーヒントをサポートするかどうか |
supportsNullValuesOrdering() | boolean | SELECT 句の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) | String | LIMIT 句(とOFFSET 句)を取得する |
escapeLikePattern(CharSequence pattern) | String | LIKE 演算子のパターン文字列をエスケープする |
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() | char | LIKE 句で指定するエスケープキャラクタを取得する |
addForUpdateClause(StringBuilder sql, ForUpdateType forUpdateType, int waitSeconds) | StringBuilder | FOR 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を利用するアプリケーションのクラスパス上に以下のファイル名のファイルを作成します。
META-INF
└─services
└─jp.co.future.uroborosql.dialect.Dialect
2
3
最後に作成したjp.co.future.uroborosql.dialect.Dialect
ファイルの中に作成したDialect
のクラス名(FQDN名)を記述します。
foo.bar.dialect.SqliteDialect
アプリケーションでjp.co.future.uroborosql.dialect.Dialect
がServiceLoader
経由で読み込まれれば登録したSqliteDialect
が利用可能になります。
← EntityHandler 高度な操作 →