3

私は jooq を spring と統合し、データベース (MySQL) へのすべてのタイプのクエリに対して、spring の JDBC テンプレートを使用しています。ここでは jooq ライブラリを使用して、jdbc テンプレートに渡す SQL クエリを生成します。

クエリに制限やオフセットを追加するまで、クエリの残りの部分は正常に機能しますが。

次のようにクエリを生成しています。

create.select(Factory.field("table_name"))
      .from("tables t")
      .where("t.table_schema LIKE '" + schemaName + "'")
      .limit(10)
      .offset(2)
      .getSQL();

次のようにエラーが発生します。

org.springframework.jdbc.BadSqlGrammarException: StatementCallback; 悪い SQL 文法 [テーブル t から table_name を選択 (t.table_schema LIKE 'test') limit ? オフセット?]; ネストされた例外は com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException です: SQL 構文にエラーがあります。near '? を使用する正しい構文については、MySQL サーバーのバージョンに対応するマニュアルを確認してください。オフセット?' 1行目

limit および offset メソッドに渡された値がクエリに追加されないことは明らかです。

ドキュメントを検索しましたが、これを達成する他の方法は見つかりませんでした。

4

1 に答える 1

5

jOOQ は、バインド値を使用して SQL を生成します。jOOQ を使用して SQL のみをレンダリングし、Spring で実行しているため、基本的に次のオプションのいずれかがあります。

インライン化されたバインド値を明示的に使用します。

LIMIT .. OFFSETこのように、句のバインド変数をレンダリングしないように jOOQ に明示的に指示できます。

create.select(DSL.field("table_name"))
      .from("tables t")
      .where("t.table_schema LIKE '" + schemaName + "'")
      .limit(DSL.inline(10))
      .offset(DSL.inline(2))
      .getSQL();

jOOQ にすべてのバインド値をインライン化させます。

このように、バインド変数をまったくレンダリングしないように jOOQ に指示できます。

Settings settings = new Settings();
settings.setStatementType(StatementType.STATIC_STATEMENT);
DSLContext create = DSL.using(connection, dialect, settings);
// [...]

jOOQ のクエリからバインド値を抽出します。

このように、適切な場所で jOOQ にバインド変数をレンダリングさせ、正しい順序でそれらを抽出させることができます。

Query query =
create.select(DSL.field("table_name"))
      .from("tables t")
      .where("t.table_schema LIKE '" + schemaName + "'")
      .limit(DSL.inline(10))
      .offset(DSL.inline(2));

String sql = query.getSQL();
List<Object> bindValues = query.getBindValues();

バインド値に関する jOOQ の理解の詳細:

http://www.jooq.org/doc/latest/manual/sql-building/bind-values/

構文の整合性と SQL インジェクションに関する注意

クエリは多少エラーが発生しやすいことに注意してくださいschemaName。ユーザー入力に起因する場合は、チェックしてエスケープする必要があります。そのためのバインド値を次のように作成できます。

create.select(DSL.field("table_name"))
      .from("tables t")
      .where("t.table_schema LIKE ?", schemaName)
于 2012-12-04T12:43:37.550 に答える