您的位置:首页 > 数据库 > Oracle

iBATIS + Oracle Clob(Blob)存取时的一些问题的经验总结

2011-10-28 11:10 676 查看
iBATIS作为一个易于易用的orm(sql mapping)工具,已经广泛应用在国内的大量的项目中,成熟的iBATIS2已经为社区服务了三年之久,在iBATIS2.3.0中已经废弃了其自带的DAO的框架,转而推荐Spring 提供的ibatis support dao框架,从而得到所有依赖注入,bean管理和template以及声明式事务带来的好处。

本文就在使用过程中Spring DAO + iBATIS + Oracle Clob(Blob)存取时的一些问题的经验总结。


一、开发、测试环境描述

SUN JDK1.4.2

eclipse3.2.1

tomcat 5.0.28

spring-2.0.5.jar

ibatis-2.3.0.677.jar

ojdbc14-10.2.0.3.jar(thin)

commons-dbcp链接池


二、布署环境描述

IBM WebSphere 6.0.2.17


三、数据库描述

Oracle 10.2.0.2.0

采用thin模式连接


四、使用iBATIS自带的clobTypeHanle

读取:将clob字段对应的domain属性配置为String,不需做任何配置

insert,update,时不时出现问题,后采用变态方法,将clob字段移到insert语句的最后,将clob字段移到update的最前位置,问题解决,采用的内联的parametermap

select mmt_seq.nextval as id from dualselectKey>

insert into mmt_news_main(

id,

title,

info_source,

mod_index,

craft_index,

p_index,

p_name,

lang_type,

title_short,

title_deck,

brief,

add_date,

content

)values(

#id#,

#title#,

#info_source#,

#mod_index#,

#craft_index#,

#p_index#,

#p_name#,

#lang_type#,

#title_short#,

#title_deck#,

#brief#,

sysdate,

#content,javaType=java.lang.String,jdbcType=CLOB#

)

]]>

update mmt_news_main set

content=#content,javaType=java.lang.String,jdbcType=CLOB#,

mod_index=#mod_index#,

craft_index=#craft_index#,

p_index=#p_index#,

p_name=#p_name#,

lang_type=#lang_type#,

title=#title#,

info_source=#info_source#,

title_short=#title_short#,

title_deck=#title_deck#,

brief=#brief#

where id=#id#

]]>

但没有测试过多个clob字段的情况,不存在4000字符的问题。

注意,在插入语句中clob字段的java类型为java.io.StringReader


五、使用spring自带的OracleLobHandler

看了一下spring的源码中的注释

位置:org.springframework.jdbc.support.lob.OracleLobHandler

/**

* LobHandler implementation for Oracle databases. Uses proprietary API to

* create
oracle.sql.BLOB
and
oracle.sql.CLOB


* instances, as necessary when working with Oracle's JDBC driver.

* Note that this LobHandler requires Oracle JDBC driver 9i or higher!

*

*

While most databases are able to work with DefaultLobHandler, Oracle just

* accepts Blob/Clob instances created via its own proprietary BLOB/CLOB API,

* and additionally doesn't accept large streams for PreparedStatement's

* corresponding setter methods. Therefore, you need to use a strategy like

* this LobHandler implementation.

*

*

Needs to work on a native JDBC Connection, to be able to cast it to

*
oracle.jdbc.OracleConnection
. If you pass in Connections from

* a connection pool (the usual case in a J2EE environment), you need to set

* an appropriate NativeJdbcExtractor to allow for automatical retrieval of

* the underlying native JDBC Connection. LobHandler and NativeJdbcExtractor

* are separate concerns, therefore they are represented by separate strategy

* interfaces.

*

*

Coded via reflection to avoid dependencies on Oracle classes.

* Even reads in Oracle constants via reflection because of different Oracle

* drivers (classes12, ojdbc14) having different constant values! As this

* LobHandler initializes Oracle classes on instantiation, do not define this

* as eager-initializing singleton if you do not want to depend on the Oracle

* JAR being in the class path: use "lazy-init=true" to avoid this issue.

*

* @author Juergen Hoeller

* @since 04.12.2003

* @see #setNativeJdbcExtractor

* @see oracle.sql.BLOB

* @see oracle.sql.CLOB

*/

大体的意思是:oracle使用私有的API产生oracle.sql.BLOB和oracle.sql.CLOB实例,oracle只接受其自己API产生的实例,并且在PreparedStatement中不支持大的数据流。

此实现类需要一个原生的可以被转换成oracle.jdbc.OracleConnection的链接,所以在使用连接池的时候,就需要一个原生JDBC的转换器。

原来如此,马上配置, 快速搞定,在测试,生产环境中都没有问题,sqlMap也不需要注意clob字段的位置,以下是配置:

1、sqlMapConfig

xml 代码

<!--sp-->xml version="1.0" encoding="UTF-8"?>

<!--CTYPE sqlMapConfig </sp-->

PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<settings cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true"

useStatementNamespaces="false" statementCachingEnabled="true" classInfoCacheEnabled="true" />

<typeHandler jdbcType="BLOB" javaType="[B"

callback="org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler" />

<typeHandler jdbcType="CLOB" javaType="java.lang.String"

callback="org.springframework.orm.ibatis.support.ClobStringTypeHandler" />

<sqlMap resource="com/xx/ssi/dao/ibatis/maps/SysModule.xml" />

sqlMapConfig>

2、spring配置(部分)

xml 代码

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/dsmmt" />

<!-- Transaction manager for a single JDBC DataSource -->

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource" />

bean>

<!-- Transaction manager that delegates to JTA (for a transactional JNDI DataSource) -->

<!-- </span> </li> <li class=""><span><span class="comments"> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" /> </span> </span></li> <li
class="alt"><span><span class="comments">-->

<bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"

lazy-init="true" />

<!-- <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.WebSphereNativeJdbcExtractor" lazy-init="true" />-->

<!-- 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>

<!-- SqlMap setup for iBATIS Database Layer -->

<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

<property name="configLocation" value="classpath:com/ahtec/ssi/config/ibatis/sql-map-config.xml" />

<property name="dataSource" ref="dataSource" />

<property name="lobHandler">

<ref local="oracleLobHandler" />

property>

bean>

在发布环境中,要将nativeJdbcExtractor 换成 org.springframework.jdbc.support.nativejdbc.WebSphereNativeJdbcExtractor

留意log4j日志,此时的clob字段的java类型为oracle.sql.Clob

Spring内置提供的NativeJdbcExtractor转换器有:

C3P0NativeJdbcExtractor

CommonsDbcpNativeJdbcExtractor

JBossNativeJdbcExtractor

NativeJdbcExtractor

NativeJdbcExtractorAdapter

SimpleNativeJdbcExtractor

WebLogicNativeJdbcExtractor

WebSphereNativeJdbcExtractor

XAPoolNativeJdbcExtractor

基本上够用了。

位于org\springframework\jdbc\support\nativejdbc下


六、最后也总结一下:

ibatis 2.0.9 + (最新的是iBATIS-2.3.0.667)

oracle 10g driver + (最新的是ojdbc14-10.2.0.3.jar)

使用spring 提供的dao框架,按如上配置,不同的链接池采用不同的NativeJdbcExtractor

不需要写显式的parameterMap(我测试了也没有成功),简洁好用的inline-parameterMap应该是首选,配合abator等自动化工具,ibatis照样能达到快速开发。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐