iBATIS3(mybatis) で、ORDER BY 句の動的SQL
<foreach> で、ソートキーのフィールド名、ソートタイプ(ASC,DESC) を展開させる。
SQLを書く XML では、 以下のように記述
<select id="select" parameterType="パラメータクラス" resultType="SELECT結果クラス">
SELECT * FROM item
WHERE price > #{price}}
<if test="sizeList > 0">
<foreach collection="orderList" item="orderby" open="ORDER BY" close="" separator=",">
${orderby.field} ${orderby.type}
</foreach>
</if>
</select>
parameterType で指定するクラスは、price という WHERE 句 price > #{price} を
処理するためのプロパティ、
<foreache> の collection が指定する java.util.Collection 型のプロパティ
orderList を持たなければならない、さらに、Collection 要素は、
<foreache> の item の展開が示すように、field と、type 、すなわち、
OREDER BY 句を形成させる単語2個で構成できるものがCollectionの要素である。
上記XMLでは、<if test="sizeList > 0"> を処理するために Collection サイズを
認識させるプロパティ(int sizeList)も必要になる
ここで考えたのだか、普遍的なのは、Collection<E> をparameterTypeで指定するクラスが
持つことでEを如何に定義するかだ。
import java.io.Serializable;
/**
* OREDER BY 句にするフィールド名とORDER方法、ASC / DESC
*/
public class SortKey implements Serializable{
public String field;
public String type;
public SortKey(String field,String type){
this.field = field;
this.type = type;
}
}
----------------------------------------------------
タイプセーフのため、列挙を用意して
public enum OrderBy{
ASC,DESC;
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* ORDER BY 句のためのパラーメータ抽象クラス
*/
public abstract class AbstractOrderByConditon{
public Collection<SortKey> orderList;
// orderListの空チェックで if 文で必要なため。
Integer sizeList;
public AbstractOrderByConditon(){
this.orderList = new ArrayList<SortKey>();
}
public AbstractOrderByConditon(List<SortKey> orderList){
this.orderList = new ArrayList<SortKey>(orderList);
}
public void addOrderBy(String field,OrderBy type){
this.orderList.add(new SortKey(field,type.name()));
this.sizeList = this.orderList.size();
}
}
------------------------------------------------------
AbstractOrderByConditon 継承してparameterType のクラスを用意
public class ItemCondition extends AbstractOrderByConditon{
public int price;
}
SQL実行するところ、、、、
SqlSessionFactory sqlsessionFactory;
// sqlsessionFactory を生成
SqlSession session = this.sqlsessionFactory.openSession();
ItemCondition conditon = new ItemCondition();
conditon.addOrderBy("name",OrderBy.DESC);
conditon.addOrderBy("price",OrderBy.ASC);
conditon.price = 100;
List<Item> list = session.selectList("select",conditon);