24

使っています

  1. mySQLDBへのJDBC接続を確立するためのjdbcTemplate
  2. SQLインジェクション攻撃から自分自身を可能な限り保護するためのプリペアドステートメント
  3. ダースの異なる列のいずれかでデータを並べ替えるユーザーからの要求を受け入れる必要がある
  4. 次のステートメント

    jdbcTemplate.query("SELECT * FROM TABLE1 ORDER BY ? ?", colName, sortOrder);
    

もちろん、これは機能しません。変数バインディングは、クエリ内の式のパラメータ値だけで列名を指定することは想定されていないためです。

それで...人々はこの問題をどのように解決していますか?Javaコードで並べ替えを行うだけでも簡単な解決策のように思えますが、列を並べ替えるための変数文字列と、並べ替え順序を示す変数を取得しているので、これは醜い数のコンパレータ条件です。カバー。これは、それを解決するための一般的なパターンの一般的な問題であるはずです...

4

3 に答える 3

24

プレースホルダー?はパラメーター値にのみ使用でき、列および並べ替え順序の方向には使用できません。したがって、ここで指摘されているようにこれを行う標準的な方法は、 String#format()などを使用して、列名と順序値をクエリに追加することです。

もう1つのオプションは、Spring Data JPAを使用することです。この場合、データベースをソートするために必要なすべての情報を含むことができる、Sort型のインスタンスを引数としてメソッドに指定できます。

于 2012-09-14T19:02:36.927 に答える
2

列名と順序をSQLクエリに連結しますが、

  1. このコンテキストで列名と順序が有効であることを確認します。
  2. SQLインジェクション攻撃の試みに対抗するためにそれらをサニタイズします。

これは、結果をアプリケーションレイヤーにフェッチして、ここで並べ替えるよりも効率的だと思います。

于 2012-09-14T18:48:33.533 に答える
2

私の提案は、キーと列のマッピングです。それは安全な解決策です。

最初に、可能な限り簡単な方法でマップを開始します。便宜上、get(Obiect key)メソッドをオーバーロードして、失敗した場合にデフォルトの列( "fullName")を返しました。これにより、SqlExeptionから保護されます。

    static Map<String,String> sortCol;
{
    sortCol = new HashMap<String, String>(){
        {//Enter all data for mapping
            put("name","fullName");
            put("rok","year");
            put("rate","likes");
            put("count-rate","countRate");

        }
        /**
         * 
         * @param key for column name
         * @return column name otherwise default "fullName"
         */
        @Override
        public String get(Object key) {
            String col =super.get(key);
            return null==col?"fullName":col;
        }
    };
}

簡単な使用例を次に示します。

String sqlQuery= "Select \"fullName\",year,likes,count-rate, country ..."+
 "from  blaBla..."+
 "where blaBla..."+
 "order by "+sortCol.get("keySort") "\n"; // keySort can have the value name, count-rate etc .. 

ちなみに、RESTやSOAPなどのユーザーインターフェイスの列の実際の名前は絶対に公開しないでください...攻撃者にとって、これは大きな助けになります。

于 2018-07-31T19:27:30.630 に答える