はじめに:
私たちは、JDBCや他のフレームワークを使用して過去には、非常に痛みを伴うことが条件に応じて、SQL文をステッチされます。必要なスペースを忘れて、だけでなく、最後のコンマの列名のリストを保存するために注意を払っていないことを確認するための時間のスプライシング。しかし、現在では、我々は、動的SQLあなたが完全に痛みを取り除くことができ、この機能を使用しています。
通常、このような状況を改善するための強力なMyBatisの動的SQL言語を使用して、もちろん、パーティにはできません動的SQLを使用して、言語がマッピングされたSQL文のいずれにも使用することができます。
動的SQL要素と使用JSTLやMyBatisの以前のバージョンに類似の他の同様のXMLベースのテキストプロセッサ、多くの要素があるMyBatis3が大幅にそれらを強化し、理解する必要があり、今の仕事にそれらの要素を持つの半分以下があります、MyBatisのは、他の要素を排除するための強力なOGNLベースの表現を使用しています。
もし:
行うには、動的SQLいつもの事は条件付きで一部where句が含まれています。例えば:
<select id="findBlog"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select>
この文は、機能のオプションのテキスト検索の種類を提供します。あなたは「タイトル」を渡さない場合は、すべて返されます「ACTIVE」ステータスBLOGであり、逆に、この例では(「タイトル」、それが「タイトル」、コンテンツBLOG結果が返されるあいまいになります渡された場合には、注意深い読者は)パラメータ値がマスクであることに気づくであろう、またはワイルドカードを含んでいてもよいです。
複数の条件クエリ:
<select id="findBlog"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
それ以外の場合は、とき、選択します。
そして、Javaは、スイッチ...ケースに...同様に、MyBasitは、要素を選択します。
<select id="findBlog"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
一方が他方を満たすために行かないときに、2つしか満たすことができます。
ここで、セットをトリム:
最初の例では、使用する場合を例示したが、この使用は、欠陥を有する - 動的SQL WHERE句の外側が存在しなければなりません。
あなたは何を意味する、私たちは句が動的に生成された時間バックの多くを必要とするためではなく、事前にがある場合、これは例えば、問題となっています。
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
これらの条件ならば誰もが上の何が起こるかを一致させることはできませんか?結局、このSQLはそうなります。
SELECT * FROM BLOG WHERE
これは、クエリが失敗します。唯一の第二の条件と一致した場合は、このSQLは最終的に次のようになります。
SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’
このクエリは失敗します。この問題は、簡単に条件文で解決されていません。
この問題を解決する方法は2つあります。
1)簡単な方法は、1 = 1モードを使用することです選びます
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE 1 = 1
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
説明:唯一の真の層を追加することと等価である「1 = 1」は、常に出会い、あるため、動的SQLの生成は何ですどのような条件を決定します。
2)MyBatisのは、症例の90%において有用であろう簡単な処理を、有しています。
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
要素は、「WHERE」の値を持っている状況下で句を挿入しようとする前に、その場合にのみ、複数の条件を知っています。また、最終的にコンテンツがある場合は、「AND」または「OR」、始まる要素もそれらを削除する方法を知っている場所。
通常のルーチンの要素がないカードならば、私たちは私たちが望むカスタマイズするトリム要素をカスタマイズすることができます。例えば、どこの要素およびカスタムトリム同等の要素:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
…
</trim>
すなわち:
```sql
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</trim>
</select>
注:prefixOverrides特性は、(この実施形態ではスペースが必要であることに注意)パイプで区切られたテキスト列を無視します。
セットと呼ばれる動的な更新ステートメントのための同様のソリューション。他人を破棄しながら、動的に更新される列の必要性を備える要素を設定するために使用することができます。例えば:
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
where id=#{id}
</update>
ここでは、一連の要素を動的にSETキーワードを付加するだけでなく、条件文を使用した後に可能性が代入文の生成後にカンマを残しますので、余分なカンマを除去することができます。
あなたは興味の同等のトリム要素の外観をカスタマイズし、これはその本当の色でなければならないこととします。
<trim prefix="SET" suffixOverrides=",">
...
</trim>
私たちは別の付加価値の接頭ながら、サフィックスの値を無視することに注意してください。
foreachの:
別の一般的に使用される動的SQL操作に必要な通常は条件文に構築トラバースのセット、の必要性です。例えば:
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
foreachの要素には、コレクションを指定することができます非常に強力な機能であり、要素を宣言した項目とインデックス変数の本体で使用することができます。それはまた、あなたが文字列マッチング途中で区切り文字を閉鎖し、反復を置くことを指定することができます。それが誤って余分な区切りを追加しませんので、この要素は、スマートです。
注:あなたは、任意の反復オブジェクト(例えば、リスト、設定、等)及び任意の辞書であるか、foreachのパラメータセットへのオブジェクトの配列としてすることができます。反復オブジェクト又はアレイを使用する場合、インデックスは現在の反復数、項目値が取得される要素の繰り返しです。辞書(またはオブジェクトのMap.Entryのコレクション)を使用する場合、索引項目が値である、結合です。