ibatisには、SQLマッピング設定ファイルにて、以下の2つの値指定ができます。
- #を使用した値指定
- $を使用した値指定
上記の2つの違いは、#は実行時にエスケープや文字列の場合は' 'で囲んでくれるなどの処理をおこなってくれますが
$の方は、指定された値をそのまま出力します。
たとえば、java.lang.String型の値value1があったとして、
hoge_column = #value1#
と指定した場合、実行時には、
hoge_column = 'value1の値'
のように、展開してくれますが、
hoge_column = $value1$
と指定した場合は、
hoge_column = value1の値
とそのまま展開されます。
$指定は、主にテーブルを動的に与えたり、order byを動的に変えたりするのに
使用したります。取得カラム名を動的に変更したりする場合にも使えたりします。
今回は、order by を動的に変更するサンプルを作成してみます。
[ddl]
--vim:set ts=4 sw=4 et ws is nowrap ft=sql: -- -- SAMPLE010_TEST_TABLEのDDL -- create table sample010_test_table( id int auto_increment ,value1 varchar(100) ,value2 varchar(100) ,value3 varchar(100) ,primary key(id) ); -- -- サンプルデータ -- insert into SAMPLE010_TEST_TABLE (value1, value2, value3) values ('value1-001', 'value2-011', 'value3-348'); insert into SAMPLE010_TEST_TABLE (value1, value2, value3) values ('value1-002', 'value2-032', 'value3-489'); insert into SAMPLE010_TEST_TABLE (value1, value2, value3) values ('value1-003', 'value2-034', 'value3-098'); insert into SAMPLE010_TEST_TABLE (value1, value2, value3) values ('value1-004', 'value2-048', 'value3-934'); insert into SAMPLE010_TEST_TABLE (value1, value2, value3) values ('value1-005', 'value2-002', 'value3-485');
[データクラス]
// vim:set ts=4 sw=4 et ws is nowrap ft=java: package gsf.samples.ibatis.sample010; import java.io.*; import org.apache.commons.lang.builder.*; public class Sample010TestTable implements Serializable{ /** ID */ private Integer id; /** VALUE1 */ private String value1; /** VALUE2 */ private String value2; /** VALUE3 */ private String value3; /** * コンストラクタ.<br/> * */ public Sample010TestTable(){ // nop; } /** * Get id. * * @return id as Integer. */ public Integer getId(){ return this.id; } /** * Set id. * * @param id the value to set. */ protected void setId(Integer id){ this.id = id; } /** * Get value1. * * @return value1 as String. */ public String getValue1(){ return this.value1; } /** * Set value1. * * @param value1 the value to set. */ public void setValue1(String value1){ this.value1 = value1; } /** * Get value2. * * @return value2 as String. */ public String getValue2(){ return this.value2; } /** * Set value2. * * @param value2 the value to set. */ public void setValue2(String value2){ this.value2 = value2; } /** * Get value3. * * @return value3 as String. */ public String getValue3(){ return this.value3; } /** * Set value3. * * @param value3 the value to set. */ public void setValue3(String value3){ this.value3 = value3; } @Override public String toString(){ return new ReflectionToStringBuilder(this).toString(); } }
<?xml version="1.0" encoding="Windows-31J"?> <!-- vim:set ts=4 sw=4 et ws is nowrap ft=xml: --> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap namespace="Dollar"> <typeAlias alias="Sample010TestTable" type="gsf.samples.ibatis.sample010.Sample010TestTable"/> <select id="findSample010TestTableOrderBy" parameterClass="java.lang.String" resultClass="Sample010TestTable"> select id ,value1 ,value2 ,value3 from SAMPLE010_TEST_TABLE order by $value$ </select> </sqlMap>
[動作確認クラス]
// vim:set ts=4 sw=4 et ws is nowrap ft=java: package gsf.samples.ibatis.sample010; import java.util.*; import java.sql.*; import gsf.interfaces.sqlmap.*; import gsf.utils.sqlmap.*; import com.ibatis.sqlmap.client.*; public class IBatisSample010{ private static class DollarSampleExecutor implements SqlMapClientExecutor{ private String orderByTarget; public DollarSampleExecutor(String orderByTarget){ this.orderByTarget = orderByTarget; } public Object execute(SqlMapClient sqlMap) throws SQLException{ return sqlMap.queryForList("findSample010TestTableOrderBy", this.orderByTarget); } } public static void main(String[] args){ List<Sample010TestTable> result1 = (List<Sample010TestTable>) SqlMapUtils.executeNoTransaction(new DollarSampleExecutor("value1")); List<Sample010TestTable> result2 = (List<Sample010TestTable>) SqlMapUtils.executeNoTransaction(new DollarSampleExecutor("value2")); List<Sample010TestTable> result3 = (List<Sample010TestTable>) SqlMapUtils.executeNoTransaction(new DollarSampleExecutor("value3")); System.out.println("======== value1でorder by ========"); printResult(result1); System.out.println("\n======== value2でorder by ========"); printResult(result2); System.out.println("\n======== value3でorder by ========"); printResult(result3); } private static void printResult(List<Sample010TestTable> result){ for(Sample010TestTable aRow : result){ System.out.println(aRow); } } }
実行すると、指定した値でOrder Byが行われている事が確認できます。
このサンプルの場合、$指定ではなく、#指定をすると展開された場合に、
order by 'value1'
とかなってしまい、うまくいきません。
データのパラメータではなく、実行するSQLの一部を動的に変更したい場合は、
$指定をします。
ちなみに、iBatisのドキュメントやwikiにも記述がありますが、
$指定の場合は、そのままデータが展開されますので、SQLインジェクションなどの
アタックを許さないように、処理元でしっかりとコントロールする必要があります。
ちなみに、サンプルの動作結果は、以下のとおりです。
exec: [java] ======== value1でorder by ======== [java] gsf.samples.ibatis.sample010.Sample010TestTable@1006d75[id=1,value1=value1-001,value2=value2-011,value3=value3-348] [java] gsf.samples.ibatis.sample010.Sample010TestTable@18dfef8[id=2,value1=value1-002,value2=value2-032,value3=value3-489] [java] gsf.samples.ibatis.sample010.Sample010TestTable@15e83f9[id=3,value1=value1-003,value2=value2-034,value3=value3-098] [java] gsf.samples.ibatis.sample010.Sample010TestTable@bb7465[id=4,value1=value1-004,value2=value2-048,value3=value3-934] [java] gsf.samples.ibatis.sample010.Sample010TestTable@d6c16c[id=5,value1=value1-005,value2=value2-002,value3=value3-485] [java] ======== value2でorder by ======== [java] gsf.samples.ibatis.sample010.Sample010TestTable@134bed0[id=5,value1=value1-005,value2=value2-002,value3=value3-485] [java] gsf.samples.ibatis.sample010.Sample010TestTable@1db4f6f[id=1,value1=value1-001,value2=value2-011,value3=value3-348] [java] gsf.samples.ibatis.sample010.Sample010TestTable@13c1b02[id=2,value1=value1-002,value2=value2-032,value3=value3-489] [java] gsf.samples.ibatis.sample010.Sample010TestTable@11121f6[id=3,value1=value1-003,value2=value2-034,value3=value3-098] [java] gsf.samples.ibatis.sample010.Sample010TestTable@1ccce3c[id=4,value1=value1-004,value2=value2-048,value3=value3-934] [java] ======== value3でorder by ======== [java] gsf.samples.ibatis.sample010.Sample010TestTable@f7f540[id=3,value1=value1-003,value2=value2-034,value3=value3-098] [java] gsf.samples.ibatis.sample010.Sample010TestTable@10655dd[id=1,value1=value1-001,value2=value2-011,value3=value3-348] [java] gsf.samples.ibatis.sample010.Sample010TestTable@ef5502[id=5,value1=value1-005,value2=value2-002,value3=value3-485] [java] gsf.samples.ibatis.sample010.Sample010TestTable@b61fd1[id=2,value1=value1-002,value2=value2-032,value3=value3-489] [java] gsf.samples.ibatis.sample010.Sample010TestTable@e2dae9[id=4,value1=value1-004,value2=value2-048,value3=value3-934]