昨日、同僚にH2のJDBC URLに「;MODE=MySQL」のようにオプションを付けることでH2の挙動をMySQL風、PostgreSQL風、Oracle風などのように切り替えることができるということを教えてもらいました。H2のドキュメントでは以下のあたりに書かれています。
http://www.h2database.com/html/features.html#compatibility
「な、なんだってー!!」ということで実際どのように切り替わるのかソースを見てみました。
org.h2.engine.Modeで以下のような感じで定義されています。
mode = new Mode("MySQL"); mode.convertInsertNullToZero = true; mode.indexDefinitionInCreateTable = true; mode.lowerCaseIdentifiers = true; mode.onDuplicateKeyUpdate = true; add(mode); mode = new Mode("Oracle"); mode.aliasColumnName = true; mode.convertOnlyToSmallerScale = true; mode.uniqueIndexSingleNullExceptAllColumnsAreNull = true; mode.treatEmptyStringsAsNull = true; add(mode); mode = new Mode("PostgreSQL"); mode.aliasColumnName = true; mode.nullConcatIsNull = true; mode.supportOffsetFetch = true; mode.systemColumns = true; mode.logIsLogBase10 = true; mode.serialColumnIsNotPK = true; add(mode);
ここで指定しているプロパティを元にSQLの構文や関数の挙動など、H2内の様々な動作を切り替えているようです。
もちろん完全に該当のDBの動作を再現することはできませんが、どっちみちO/Rマッパーを使用していればネイティブSQLが必要になるようなケース以外ではDBに依存したクエリが投げられるケースは少ないのではないかと思います。ユニットテストに使用する程度であればこれで十分というケースもあるのではないでしょうか。