How do I use a Custom Type Handler with complex property or Type Safe Enumeration
Here is an example of how to set up a custom type handler with a complex property. This example uses the enum features of Java 1.5 but could be used with a Type Safe Enumeration in anything below 1.5.
Lets start by defining the database table
SHAPE { name varchar2(25), color number(100) }
As you see the color is stored as a number, but in the class Shape is is a Color 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 Color? Second, how can iBatis and custom type handlers help?
To answer the first let me show you the code for the Shape class.
/* * Shape.java * * Created on September 23, 2005 */ package domain; /** * * @author nmaves */ public class Shape { public enum Color { BLUE(1, "0000FF"), RED(2, "FF0000"), GREEN(3, "00FF00"); private int id; private String rgb; private Type(int id, String name) { this(id, name, "no mime type"); } private Type(int id, String rgb) { this.id = id; this. rgb = rgb; } public int getId() { return this.id; } public String getRGB() { return this.name; } public static Type getInstance(int i) { for(Color color : Color.values()) { if(color.id == i) { return type; } } throw new IllegalArgumentException("No such Color"); } } private String name; private Color color; /** Creates a new instance of Frequency */ private Shape(String name, Color color) { this.color = color; this.name = name; } public String toString() { return this.name; } public void setName(String name) { this.name = name; } public void setColor(Color color) { this.color = color; } public String getName() { return this.name; } public Color getColor() { return this.color; } }
As you see the getInstance(int i) 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 ColorTypeHandler.java
package dao.ibatis; import com.ibatis.sqlmap.client.extensions.ParameterSetter; import com.ibatis.sqlmap.client.extensions.ResultGetter; import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback; import java.sql.SQLException; import java.sql.Types; import Shape.Color; public class ColorTypeHandler implements TypeHandlerCallback { public Object getResult(ResultGetter getter) throws SQLException { int value = getter.getInt(); if (getter.wasNull()) { return null; } Color color = Color.getInstance(value); return color; } public void setParameter(ParameterSetter setter, Object parameter) throws SQLException { if (parameter == null) { setter.setNull(Types.INTEGER); } else { Color color = (Color) parameter; setter.setInt(color.getId()); } } 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="domain.Shape$Color" callback="dao.ibatis.ColorTypeHandler"/>
![]() |
Useful Information Notice the $ in the class name. This is how Java 1.5 denotes enums. If this were a type safe enum you would just use standard notation. |
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="Shape" id="ShapeResult"> <result column="name" property="name" /> <result column="color" property="color" /> </resultMap> <select id="getShapeByName" parameterClass="string" resultMap="ShapeResult"> SELECT * FROM SHAPE WHERE name = #value# </select> <insert id="insertReport" parameterClass="Report"> INSERT INTO SHAPE ( name, color ) values ( #name#, #color#, ) </insert>
Notice that there is nothing special that need to be done for the color columns.
posted on 2008-07-22 23:18 MingIsMe 閱讀(109) 評論(0) 編輯 收藏 所屬分類: iBatis學習