6.8.8.1 バインド変数の使用

バインド変数を使用する理由は2つあります。

  • 問合せインジェクションから保護します。
  • 問合せの再コンパイルを必要とせずに同じバインド変数を複数回設定できるため、問合せの実行が高速化されます。

プリペアド文を作成するには、次の2つの方法のいずれかを使用します。

  • PgxGraph.preparePgql(String query) : PgxPreparedStatement
  • PgxSession.preparePgql(String query) : PgxPreparedStatement

これらのメソッドから返されるPgxPreparedStatement (package oracle.pgx.api)には、バインド変数を指定されたデータ型の値にバインドするためのsetterメソッドがあります。

次のケースについて検討します。
PreparedStatement stmnt = g.preparePgql(
  "SELECT v.id, v.dob " +
  "FROM MATCH (v) " +
  "WHERE v.firstName = ? AND v.lastName = ?");
stmnt.setString(1, "Camille");
stmnt.setString(2, "Mullins");
ResultSet rs = stmnt.executeQuery();

問合せ内の各バインド変数は、PgxPreparedStatementの次のセッターのいずれかを使用して値に設定する必要があります。

  • setBoolean(int parameterIndex, boolean x)
  • setDouble(int parameterIndex, double x)
  • setFloat(int parameterIndex, float x)
  • setInt(int parameterIndex, int x)
  • setLong(int parameterIndex, long x)
  • setDate(int parameterIndex, LocalDate x)
  • setTime(int parameterIndex, LocalTime x)
  • setTimestamp(int parameterIndex, LocalDateTime x)
  • setTimeWithTimezone(int parameterIndex, OffsetTime x)
  • setTimestampWithTimezone(int parameterIndex, OffsetDateTime x)
  • setArray(int parameterIndex, List<?> x)

すべてのバインド変数が設定されると、文は次の方法で実行できます。

  • PgxPreparedStatement.executeQuery()
    • SELECT問合せの場合のみ
    • ResultSetを返します
  • PgxPreparedStatement.execute()
    • あらゆるタイプの文の場合
    • 結果の形式を示すブール値を返します。SELECT問合せの場合はtrue、それ以外の場合はfalseです。
    • SELECTの場合、ResultSetには後でPgxPreparedStatement.getResultSet()を使用してアクセスできます。

PGQLでは、配列リテラルを含む任意のデータ型のリテラルのかわりにバインド変数を使用できます。文字列配列のインスタンスにバインド変数が設定されている問合せの例は次のとおりです。

List<String> countryNames = new ArrayList<String>();
countryNames.add("Scotland");
countryNames.add("Tanzania");
countryNames.add("Serbia");

PreparedStatement stmnt = g.preparePgql(
  "SELECT n.name, n.population " +
  "FROM MATCH (c:Country) " +
  "WHERE c.name IN ?");

ResultSet rs = stmnt.executeQuery();

最後に、プリペアド文が不要になった場合は、PgxPreparedStatement.close()を介してクローズされ、リソースが解放されます。