iBATIS 複雑なプロパティ(列挙型)
エンティティに複雑なプロパティを使用する場合。
例えば、列挙型。
テーブルにマッピングされる、データが列挙型である場合の
iBATISの定義の仕方。
まあ、列挙型でなくても、Hnadlerを登録すれば、ほぼ自由なことができる。
今回は、iBATIS Wikiにある例をチョット変更してみた。
How do I use a Custom Type Handler with complex property (Type Safe Enumeration)
Reportというテーブルをマッピングする。
このテーブルは、frequencyというType Safe Enumerationなプロパティを含む。
テーブル定義:
CREATE TABLE REPORT (ID VARCHAR(5),
NAME VARCHAR(25),
DESCRIPTION VARCHAR(1000),
FREQUENCY NUMERIC(1)
)
Reportエンティティを作成する
package ibatis.domain;import ibatis.domain.enum.FrequencyEnum;
public class Report {
String id;
String name;
String description;
FrequencyEnum frequency;
public final String getDescription() {
return description;
}
public final FrequencyEnum getFrequency() {
return frequency;
}
public final String getId() {
return id;
}
public final String getName() {
return name;
}
public final void setDescription(String description) {
this.description = description;
}
public final void setFrequency(FrequencyEnum frequency) {
this.frequency = frequency;
}
public final void setId(String id) {
this.id = id;
}
public final void setName(String name) {
this.name = name;
}
}
FrequencyEnumという列挙型を作る
Wikiのサンプルと違うところは、Commons LangのValuedEnumを使っているところ。
package ibatis.domain.enum;import org.apache.commons.lang.enum.Enum;
import org.apache.commons.lang.enum.ValuedEnum;
public class FrequencyEnum extends ValuedEnum {
/**
* @param name
* @param value
*/
private FrequencyEnum(String name, int value) {
super(name, value);
}
private static final int FC_DAILY = 1;
private static final int FC_WEEKLY = 2;
private static final int FC_MONTHLY = 3;
private static final int FC_QUARTERLY = 4;
private static final String FN_DAILY = "Daily";
private static final String FN_WEEKLY = "Weekly";
private static final String FN_MONTHLY = "Monthly";
private static final String FN_QUARTERLY = "Quarterly";
public static final FrequencyEnum NULL =
new FrequencyEnum(null, 99999);
public static final FrequencyEnum DAILY =
new FrequencyEnum(FN_DAILY, FC_DAILY);
public static final FrequencyEnum WEEKLY =
new FrequencyEnum(FN_WEEKLY, FC_WEEKLY);
public static final FrequencyEnum MONTHLY =
new FrequencyEnum(FN_MONTHLY, FC_MONTHLY);
public static final FrequencyEnum QUARTERLY =
new FrequencyEnum(FN_QUARTERLY, FC_QUARTERLY);
public static Enum getEnum(int value) {
return (FrequencyEnum)getEnum(FrequencyEnum.class, value);
}
}
FrequencyEnumのハンドラーを作る
package ibatis.domain.enum;import com.ibatis.sqlmap.client.extensions.ParameterSetter;
import com.ibatis.sqlmap.client.extensions.ResultGetter;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;
public class FrequencyEnumHandler implements TypeHandlerCallback {
/* PreparedStatementにデータをバインドするときに使われる */
public void setParameter(ParameterSetter setter, Object parameter)
throws SQLException {
if(parameter == null){
setter.setNull(Types.INTEGER);
} else {
FrequencyEnum frequency = (FrequencyEnum)parameter;
setter.setInt(frequency.getValue());
}
}
/* ResultSetから取り出すときに使われる */
public Object getResult(ResultGetter getter) throws SQLException {
int value = getter.getInt();
if(getter.wasNull()){
/* 値がNullの場合や、想定外の値の場合Nullに
なってしまうのが嫌ですが・・・ */
return null;
}
return FrequencyEnum.getEnum(value);
}
/* nullValueで指定した物を、置き換えるときに使われる(StringからのCast用) */
public Object valueOf(String s) {
return s;
}
}
SqlMapConfigにハンドラーを登録する
<sqlMapConfig>
<typeHandler javaType="ibatis.domain.enum.FrequencyEnum"
callback="ibatis.domain.enum.FrequencyEnumHandler"/>
</sqlMapConfig>
<properties/>, <settings/>, <typeAlias/>,
<typeHandler/>, <transactionManager/>, <sqlMap/>
の順番で書かないとエラーになるので注意。