Here is an example of how to use the Custom Type Handler (CTH)
feature of iBatis with large objects (LOB) such as BLOB's (Binary) and
CLOB's (Character). As of release 2.0.9 the iBatis framework has the
default CLOB and BLOB type handlers included. The example below was
done for Oracle but should work for any database with a well written
JDBC driver. Make sure that you do not use the thin driver supplied
from Oracle. You need to use the latest ojbc14.jar.
The example below was not the intended way to use CTH's but it works great for me!
First lets take a look at the table.
Report.sql
REPORT {
id varchar2(5),
name varchar2(25),
description varchar2(1000),
data BLOB
}
Next we continue by creating a plain old java object (POJO) to represent this table.
Report.java
/*
* Report.java
*
* Created on March 23, 2005, 11:00 AM
*/
package
reporting.viewer.domain;
/**
*
* @author Nathan Maves
*/
public
class Report {
/**
* Holds value of property id.
*/
private
String
id;
/**
* Holds value of property name.
*/
private
String
name;
/**
* Holds value of property description.
*/
private
String
id;
/**
* Holds value of property data.
*/
private
byte
[] data;
//Standard accessors and mutators
public
byte
[] getData() {
return
this
.data;
}
public
void setData(byte
[] data) {
this
.data = data;
}
}
Now that the easy stuff is completed let connect both the database and the POJO together using iBatis.
Report.xml
<typeAlias alias="Report"
type="reporting.viewer.domain.Report"
/>
<resultMap class="Report"
id="ReportResult"
>
<result column="id"
property="id"
/>
<result column="name"
property="name"
/>
<result column="description"
property="description"
/>
<result column="data"
property="data"
jdbcType="BLOB"
/>
</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,
description,
data
)
values (
#id#,
#name#,
#description#,
#data#
)
</insert>
<update id="updateReport"
parameterClass="Report"
>
UPDATE REPORT set
name = #name#,
description = #description#,
data = #data#
WHERE
id = #id#
</update>
As you can see there is nothing special that you need to do.
When working with a CLOB the only that the you need to change is the
property in your bean. Just change byte[] to java.lang.String.
Data size bigger than max size for this type: ????
Some
of the older jdbc drivers for Oracle have trouble with Strings that are
larger then 4k. The first step to correct this issue it to get a jdbc
driver from Oracle that is newer then 10g Release 2. This driver will
work with both 9i and 10g databases. If you are stuck with an older
driver you can try to set a driver property. The property is
SetBigStringTryClob=true. If you are using the SimpleDataSource with
iBatis use the follow line in the config file.
<property name="Driver.SetBigStringTryClob" value="true"/>
Data size always 86 bytes?
If
you find that the length of your byte[] is always 86, check that you
have the jdbcType="BLOB" or jdbcType="CLOB" in your result map.
<!-- LobHandler for Oracle JDBC drivers -->
<!-- (refers to the NativeJdbcExtractor above to get access to native OracleConnections) -->
<bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler"
lazy-init="true">
<property name="nativeJdbcExtractor"><ref local="nativeJdbcExtractor"/></property>
</bean>
因为是在家,勿勿做了一个的CLOB读测试,等明天上班再全面测试好了。
自己定义了一个spring.ORM.ibatis.OracleClobTypeHandlerCallback,因为只测试读,就只实现了getResult方法
public class OracleClobTypeHandlerCallback implements TypeHandlerCallback {
public Object getResult(ResultGetter getter) throws SQLException {
if (logger.isDebugEnabled()) logger.debug(getClass().getName());
CLOB clob = (CLOB) getter.getClob();
if (clob == null || clob.length() == 0) {
if (logger.isDebugEnabled()) logger.debug("CLOB对象为空");
return "";
}
else
return clob.getSubString((long) 1, (int) clob.length());
}