You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ibatis.apache.org by ib...@incubator.apache.org on 2005/01/06 17:33:03 UTC
[Apache iBATIS Wiki] New: How do I use a Custom Type Handler with complex property (Type Safe Enumeration)
Date: 2005-01-06T08:33:03
Editor: NathanMaves
Wiki: Apache iBATIS Wiki
Page: How do I use a Custom Type Handler with complex property (Type Safe Enumeration)
URL: http://wiki.apache.org/ibatis/How do I use a Custom Type Handler with complex property (Type Safe Enumeration)
no comment
New Page:
##language:en
Here is an example of how to set up a custom type handler with a complex property. This example is for a Type Safe Enumeration.
In the example below there is a class Report that represents a report that a company might produce. This class has a complex property "frequency" that is represented by a Type Safe Enumeration.
Here is the report table
{{{
REPORT {
id varchar2(5),
name varchar2(25),
description varchar2(1000),
frequency number(1)
}
}}}
As you see the frequency is stored as a number, but in the class Report is is a Frequency object. There are two question that I ran into. First, how do you cleanly map the number stored in the database with the instance of a Frequency? Second, how can iBatis and custom type handlers help?
To answer the first let me show you the code for the Frequency class.
{{{
/*
* Frequency.java
*
* Created on December 27, 2004, 11:00 AM
*/
package reporting.viewer.domain;
/**
*
* @author nmaves
*/
public class Frequency {
/**
* Holds value of property value.
*/
private int value;
/** Creates a new instance of Frequency */
private Frequency(int value, String name) {
this.value = value;
this.name = name;
}
/**
* Getter for property value.
* @return Value of property value.
*/
public int getValue() {
return this.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 Frequency DAILY = new Frequency(FC_DAILY, FN_DAILY);
public static final Frequency WEEKLY = new Frequency(FC_WEEKLY, FN_WEEKLY);
public static final Frequency MONTHLY = new Frequency(FC_MONTHLY, FN_MONTHLY);
public static final Frequency QUARTERLY = new Frequency(FC_QUARTERLY, FN_QUARTERLY);
/**
* Holds value of property name.
*/
private String name;
/**
* Holds value of property format.
*/
private String format;
public static Frequency get(int value) {
switch (value) {
case FC_DAILY: return DAILY;
case FC_WEEKLY: return WEEKLY;
case FC_MONTHLY: return MONTHLY;
case FC_QUARTERLY: return QUARTERLY;
default: return null;
}
}
public String toString() {
return this.name;
}
/**
* Getter for property name.
* @return Value of property name.
*/
public String getName() {
return this.name;
}
}
}}}
As you see the {{{ get(int value) }}} method allows for the mapping of the number stored in the database to an instance of this class. I am sure there is a better way of pulling these initial value from a properties file but this is only an example.
For the second part you will need a way to allow iBatis to make the conversion. This is where the custom type handler comes into play.
Below is my FrequencyTypeHandler.java
{{{
package reporting.viewer.dao.ibatis;
import java.sql.*;
import com.ibatis.sqlmap.client.extensions.*;
import reporting.viewer.domain.Frequency;
public class FrequencyTypeHandler implements TypeHandlerCallback {
public Object getResult(ResultGetter getter) throws SQLException {
if (getter.wasNull())
return null;
return Frequency.get(getter.getInt());
}
public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {
if (parameter == null) {
setter.setNull(Types.INTEGER);
} else {
Frequency frequency = (Frequency) parameter;
setter.setInt(frequency.getValue());
}
}
public Object valueOf(String s){
return s;
}
}
}}}
You are almost there! All you need left to do is tell iBatis to map instances of Frequency object to this handler.
I added the following line into my SqlMapConfig file.
{{{ <typeHandler javaType="reporting.viewer.domain.Frequency" callback="reporting.viewer.dao.ibatis.FrequencyTypeHandler"/> }}}
Make sure that you add it before the transaction manager section.
That is it. No need to change any of your other sqlmap entries. Here is an example of a select and insert that use this handler.
{{{
<resultMap class="Report" id="ReportResult">
<result column="id" property="id" />
<result column="name" property="name" />
<result column="description" property="description" />
<result column="frequency" property="frequency"/>
</resultMap>
<select id="getReportById" parameterClass="string" resultMap="ReportResult">
SELECT
*
FROM
REPORT
WHERE
id = #value#
</select>
<insert id="insertReport" parameterClass="Report">
INSERT INTO
REPORT (
id,
name,
frequency,
description
)
values (
#id#,
#name#,
#frequency#,
#description#
)
</insert>
}}}
Notice that there is nothing special that need to be done for the frequency columns.
Hope this helps,
Nathan Maves
Nathan.Maves@sun.com