MyBatisのSelectステートメントにStringパラメーターを使用したい。私のmapper.xml:
<select id="selectAll" parameterType="String" resultMap="fastXMLResultMap">
SELECT CREATIONDATE, DOCUMENTID, TITEL, REGTITEL, INFORCEDATE, DOCTYPE
FROM #{databBaseTable}
</select>
そして、呼び出し関数:
public List<FastXMLObject> selectAll(String databBaseTable) {
SqlSession session = sqlSessionFactory.openSession();
System.out.println("Table: "+databBaseTable);
try {
List<FastXMLObject> list = session.selectList("FastXMLObject.selectAll",databBaseTable);
return list;
} finally {
session.close();
}
}
文字列dataBaseTableは、さまざまなテーブルから動的にデータを取得したいので、データベースのテーブルの名前です(誰がそう思ったでしょう)。
ただし、残念ながら、これは機能しません。エラー:ORA-00903:UngültigerTabellenname(無効なテーブル名)ですが、機能しません。 「databBaseTable」の値を出力すると、それはテーブルの正確な名前です。そして、テーブルの名前を変数なしでmapper.xmlに書き込むと、機能します。私は何を間違えますか?
'#'の代わりに_${dataBaseTable}
_を使用します。違いは、 '#'がPreparedStatementの置換に使用されることです。 「$」は直接文字列置換用です。
ただし、これを行うと、テーブル名をパラメータとしてselectList()
呼び出しに渡すことができなくなります。テーブル名をプロパティとして設定する必要があります。プロパティは、MyBatis config.xmlの_<properties>
_要素を使用して設定するか、Configuration.getVariables()
を使用してコードで直接設定できます。
MyBatis Docs の「StringSubstitution」セクションを参照してください。
わかりました。なぜこれが機能するのかはわかりませんが、問題を解決するために以下を使用しました。
<select id="selectAll" parameterType="String" resultMap="fastXMLResultMap">
SELECT CREATIONDATE, DOCUMENTID, TITEL, REGTITEL, INFORCEDATE, DOCTYPE
FROM ${value}
</select>
プロパティなどは設定していません。FROM #{databBaseTable}
からFROM ${value}
に変更しただけです。
私は誰かがこれがうまくいく理由を答えることができました。しかし今のところ、これは本当に私を助けました。
#{..}構文では、MyBatisはjdbc PreparedStatementオブジェクトを使用しますが、このオブジェクトではテーブル名をパラメーターとして指定できません。 #{..}を使用すると、sqlステートメントのパラメーターのみをパラメーター化できます。
$ {..}構文を使用すると、MyBatisは単純な古い文字列置換を行うため、必要なSQLのほとんどすべての部分を自由にパラメーター化できます。
注:ちなみに、#{..}を使用すると、SQLインジェクションからかなり安全になりますが、$ {..}を使用すると、このような攻撃への扉が開かれます。