概要
Nablarchには、MySQL用のDialectがない。
このようなケースにおいてMySQL用のDialectを設定する方法を整理する
やることのまとめ
JDBCドライバの登録
ダイアレクトを追加
実装リファレンスの整理
javadoc
dialect側
postgres(nablarch-core-jdbc)
mysql(hibarnate)
アプリケーション側
その他:大文字小文字関連の取り扱い
collation(照合順序)
決めなければならないこと
※前提:DefaultDialectと同一実装の場合は、オーバーライド不要
No | 項目 | 影響を受けるメソッド | Oracleの場合 | MySQLの場合 |
---|---|---|---|---|
1 | シーケンスオブジェクトの次の値を取得するSQL文 | buildSequenceGeneratorSql(java.lang.String sequenceName) | オーバーライド(NEXTVAL) | オーバーライド(?)、ただし、TiDBの場合NEXTVALでよい |
2 | レコード数取得用のSQL文 | convertCountSql(java.lang.String sql) | デフォルト | デフォルト |
3 | SQLIDからレコード数取得用のSQL文 | convertCountSql(java.lang.String sqlId, java.lang.Object condition, StatementFactory statementFactory) | デフォルト | デフォルト |
4 | SQL文をページング用のSQL文に変換するSQL文 | convertPaginationSql(java.lang.String sql, SelectOption selectOption) | オーバーライド(ROWNUM) | オーバーライド(LIMIT,OFFSET) |
5 | ping用SQL文 | getPingSql() | select 1 from dual |
select 1 |
6 | ResultSetから値を取得するための変換クラス | getResultSetConvertor() | オーバーライド | (実地テストで確認) |
7 | 一意制約違反を表す例外のエラーコード | isDuplicateException(java.sql.SQLException sqlException) | 1 | 1062 |
8 | Query Timeアウト時に発生する例外のエラーコード | isTransactionTimeoutError(java.sql.SQLException sqlException) | 1013 | 3024(TiDBも同様) |
9 | IDENTITY(オートインクリメントカラム)が使用できるか | supportsIdentity() | true | true |
10 | batch insert時にIDENTITY(オートインクリメントカラム)が使用できるか | supportsIdentityWithBatchInsert() | true | true |
11 | SQL文でのオフセット指定が使用できるか | supportsOffset() | true | true |
12 | シーケンスオブジェクトが使用できるか | supportsSequence() | true | false(TiDBはtrue) |
オーバーライドが必要そうな機能のチェックポイント
buildSequenceGeneratorSql
- デフォルト実装は
UnsupportedOperationException
- よってシーケンスオブジェクトが使用可能な場合、オーバーライド必須。
-
NEXTVAL
を使用できる場合は、NEXTVALを使用する。-
NEXTVAL
を使用できない場合、代用実装とする。
-
convertCountSql&convertCountSql
- デフォルト実装は
SELECT COUNT(*) COUNT_ FROM ('引数のSQL') SUB_
- デフォルト実装で事足りるため、基本的にはオーバーライド不要。全ての既存Dialectはオーバーライドをしていない。
- 単にCOUNT文が宣言できれば良い
convertPaginationSql
- デフォルト実装はSQL文を変換せずに返すので、ページングされない
- よって可能な限りオーバーライドすべき。
- offsetとlimitを使用できる場合、offsetとlimitを使用するSQL文に変換
- offsetとlimitを使用できない場合、ROWNUMなどで代用する。
getResultSetConvertor
- デフォルト実装はSQL文を変換せずに返す。
- 利用する型に関して、利用に支障がないならばオーバーライドは不要。
- 主に、ResultSet#getObject(int)を使用した場合にアプリケーションで処理する際に不都合なデータ型が返却される場合に必要となる。詳細は下記参照。
lower_case_table_names(識別子の大文字と小文字の区別)
lower_case_table_names=1 を全システムで使用してください。
これの主な欠点は、SHOW TABLES または SHOW DATABASES を使用したときに、
元の大文字または小文字で名前が表示されないことです。
Unix 上では lower_case_table_names=0 を、Windows 上では lower_case_table_names=2 を使用してください。
これでデータベース名とテーブル名の大文字と小文字の区別が保持されます。
この欠点は、ユーザーのステートメントが、Windows 上で正しい大文字または小文字でデータベース名およびテーブル名を常に参照していることを確認する必要があることです。
大文字と小文字が区別される Unix にステートメントを転送する場合、大文字と小文字が正しくなければこのステートメントは機能しません。
エラーリファレンス
一意制約違反(ERROR 1062)
クエリタイムアウト(ERROR 3024)
MYSQLには、シーケンスオブジェクトのサポ-トがない
hibarnate-mysql
補足:TiDB,MariaDBの場合はシーケンスオブジェクトを使用できる
TiDBのタイムアウトSQLは、以前は差異があったが現在は同じ
TiDBのベース実装は、基本的にMysqlベースでよい(参考:Hibarnate)
TiDBは、NEXTVALが使える