开发者

How to use a parameterized class as resultClass in iBATIS

开发者 https://www.devze.com 2023-04-09 03:40 出处:网络
We have the following class public class TemporalData<T> { private T data; private String opCode; private Date updateTime;

We have the following class

public class TemporalData<T> {
    private T data;
    private String opCode;
    private Date updateTime;
    // getters, setters
}

public class Employee {
    private String name;
    private int age;
    private Date dob;
    // getters, setters
}

And say, we've an employee_log table with all fields of employee and couple of additional columns (opCode, updateTime)

Assume this is a pattern for all log tables where we have few additional columns (in this case opCode, updateTime), we would like to ha开发者_运维技巧ve one single class that can cater to all Temporal data and hence the parameterized class.

Now, if we have to fetch employees whose attributes changed in a given duration and would like to have objects of type TemporalData returned by the DAO layer, can anyone explain how to implement an ibatis TypeHandler to handle this case? How should the type handler be configured in sqlmap xml files?


Got to know a much better and simpler solution from one of my colleagues.

<resultMap class="Employee" id="employee">
    <result property="name" column="name"/>
    <result property="age" column="age"/>
    <result property="bidPrice" column="bid_price"/>
    <result property="dob" column="dob"/>
</resultMap>

<resultMap class="Temporal" id="temporalEmployee">
    <result property="data" resultMap="employee"/>
    <result property="opCode" column="opCode" javaType="String"/>
    <result property="updateTime" column="updateTime" javaType="java.util.Date"/>
</resultMap>

The above approach would work well without any additional components.


After a lot of digging through ibatis classes in multiple packages , the following approach worked for me. (couldn't find any documentation regarding this approach nor any content in the only book available for ibatis - ibatis in action)

Step 1: Add a custom ResultObjectFactory. Classdoc of ResultObjectFactory interface explains what it is and how it behaves.

public class TemporalDataResultObjectFactory implements ResultObjectFactory {

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.ibatis.sqlmap.engine.mapping.result.ResultObjectFactory#createInstance
     * (java.lang.String, java.lang.Class)
     */
    @Override
    public Object createInstance(String statementId,
            @SuppressWarnings("rawtypes") Class clazz)
            throws InstantiationException, IllegalAccessException {

        if (!statementId.startsWith("_td_")) {
            return null;
        }

        TemporalData<Object> temporalResult = new TemporalData<Object>();
        Object dataObject = clazz.newInstance();
        temporalResult.setData(dataObject);

        return temporalResult;
    }
    /*
     * (non-Javadoc)
     * 
     * @see
     * com.ibatis.sqlmap.engine.mapping.result.ResultObjectFactory#setProperty
     * (java.lang.String, java.lang.String)
     */
    @Override
    public void setProperty(String arg0, String arg1) {
        // TODO Auto-generated method stub

    }

}

Step 2: Add the above ResultObjectFactory to sql-map-config

<resultObjectFactory type="TemporalDataResultObjectFactory" />

Step 3: Prefix all your ibatis statement Ids whose result is temporal data with 'td'.

example:

<select id="_td_getTemporalEmployees" resultMap="temporalEmployee">
    SELECT  name, age, opCode, updateTime
    FROM    employee 
    WHERE   updateTime BETWEEN #startTime# AND #endTime#
</select>

Step 4: Define the result map with the actual class (eg: if you want the result to be TemporalData, then set the class to 'Employee'), but with properties as per the temporalData class.

example:

<resultMap class="Employee" id="temporalEmployee">
    <result property="data.name" column="name" javaType="String"/>
    <result property="data.age" column="age"  javaType="long"/>
    <result property="data.bidPrice" column="bid_price"  javaType="int"/>
    <result property="data.dob" column="dob" javaType="java.util.Date"/>
    <result property="opCode" column="opCode" javaType="String"/>
    <result property="updateTime" column="updateTime" javaType="java.util.Date"/>
</resultMap>

Step 5: Make sure that all properties in resultMap defined above has javaType appropriately set (Otherwise, ibatis throws exceptions during validations complaining about unavailable setters)

0

精彩评论

暂无评论...
验证码 换一张
取 消