科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Spring让LOB数据操作变得简单易行

Spring让LOB数据操作变得简单易行

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文讲解了在 Spring 中处理 LOB 数据的原理和方法

作者:陈雄华 来源:Impress Watch中文站 2007年10月13日

关键字: Spring LOB 数据操作

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共5页)

本文讲解了在 Spring 中处理 LOB 数据的原理和方法,对于 Spring JDBC 以及 Spring 所集成的第三方 ORM 框架(包括 JPA、Hibernate 和 iBatis)如何处理 LOB 数据进行了阐述。
  概述

  LOB 代表大对象数据,包括 BLOB 和 CLOB 两种类型,前者用于存储大块的二进制数据,如图片数据,视频数据等,而后者用于存储长文本数据,如论坛的帖子内容,产品的详细描述等。值得注意的是:在不同的数据库中,大对象对应的字段类型是不尽相同的,如 DB2 对应 BLOB/CLOB,MySql 对应 BLOB/LONGTEXT,SqlServer 对应 IMAGE/TEXT。需要指出的是,有些数据库的大对象类型可以象简单类型一样访问,如 MySql 的 LONGTEXT 的操作方式和 VARCHAR 类型一样。在一般情况下, LOB 类型数据的访问方式不同于其它简单类型的数据,我们经常会以流的方式操作 LOB 类型的数据。此外,LOB 类型数据的访问不是线程安全的,需要为其单独分配相应的数据库资源,并在操作完成后释放资源。最后,Oracle 9i 非常有个性地采用非 JDBC 标准的 API 操作 LOB 数据。所有这些情况给编写操作 LOB 类型数据的程序带来挑战,Spring 在 org.springframework.jdbc.support.lob 包中为我们提供了相应的帮助类,以便我们轻松应对这头拦路虎。

  Spring 大大降低了我们处理 LOB 数据的难度。首先,Spring 提供了 NativeJdbcExtractor 接口,您可以在不同环境里选择相应的实现类从数据源中获取本地 JDBC 对象;其次,Spring 通过 LobCreator 接口取消了不同数据厂商操作 LOB 数据的差别,并提供了创建 LobCreator 的 LobHandler 接口,您只要根据底层数据库类型选择合适的 LobHandler 进行配置即可。

  本文将详细地讲述通过 Spring JDBC 插入和访问 LOB 数据的具体过程。不管是以块的方式还是以流的方式,您都可以通过 LobCreator 和 LobHandler 方便地访问 LOB 数据。对于 ORM 框架来说,JPA 拥有自身处理 LOB 数据的配置类型,Spring 为 Hibernate 和 iBatis 分别提供了 LOB 数据类型的配置类,您仅需要使用这些类进行简单的配置就可以像普通类型一样操作 LOB 类型数据。

  本地 JDBC 对象

  当您在 Web 应用服务器或 Spring 中配置数据源时,从数据源中返回的数据连接对象是本地 JDBC 对象(如 DB2Connection、OracleConnection)的代理类,这是因为数据源需要改变数据连接一些原有的行为以便对其进行控制:如调用 Connection#close() 方法时,将数据连接返回到连接池中而非将其真的关闭。

  在访问 LOB 数据时,根据数据库厂商的不同,可能需要使用被代理前的本地 JDBC 对象(如 DB2Connection 或 DB2ResultSet)特有的 API。为了从数据源中获取本地 JDBC 对象, Spring 定义了 org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor 接口并提供了相应的实现类。NativeJdbcExtractor 定义了从数据源中抽取本地 JDBC 对象的若干方法:

方法 说明
Connection getNativeConnection(Connection con) 获取本地 Connection 对象
Connection getNativeConnectionFromStatement(Statement stmt) 获取本地 Statement 对象
PreparedStatement getNativePreparedStatement(PreparedStatement ps) 获取本地 PreparedStatement 对象
ResultSet getNativeResultSet(ResultSet rs) 获取本地 ResultSet 对象
CallableStatement getNativeCallableStatement(CallableStatement cs) 获取本地 CallableStatement 对象

  有些简单的数据源仅对 Connection 对象进行代理,这时可以直接使用 SimpleNativeJdbcExtractor 实现类。但有些数据源(如 Jakarta Commons DBCP)会对所有的 JDBC 对象进行代理,这时,就需要根据具体的情况选择适合的抽取器实现类了。下表列出了不同数据源本地 JDBC 对象抽取器的实现类:

数据源类型 说明
WebSphere 4 及以上版本的数据源 org.springframework.jdbc.support.nativejdbc.WebSphereNativeJdbcExtractor
WebLogic 6.1+ 及以上版本的数据源 org.springframework.jdbc.support.nativejdbc.WebLogicNativeJdbcExtractor
JBoss 3.2.4 及以上版本的数据源 org.springframework.jdbc.support.nativejdbc.JBossNativeJdbcExtractor
C3P0 数据源 org.springframework.jdbc.support.nativejdbc.C3P0NativeJdbcExtractor
DBCP 数据源 org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor
ObjectWeb 的 XAPool 数据源 org.springframework.jdbc.support.nativejdbc.XAPoolNativeJdbcExtractor

  下面的代码演示了从 DBCP 数据源中获取 DB2 的本地数据库连接 DB2Connection 的方法:

  清单 1. 获取本地数据库连接

package com.baobaotao.dao.jdbc; 

import java.sql.Connection; 
import COM.ibm.db2.jdbc.net.DB2Connection; 
import org.springframework.jdbc.core.support.JdbcDaoSupport; 
import org.springframework.jdbc.datasource.DataSourceUtils; 

public class PostJdbcDao extends JdbcDaoSupport implements PostDao { 
  public void getNativeConn(){ 
    try { 
      Connection conn = DataSourceUtils.getConnection(getJdbcTemplate() 
          .getDataSource()); ① 使用 DataSourceUtils 从模板类中获取连接 
      ② 使用模板类的本地 JDBC 抽取器获取本地的 Connection 
      conn = getJdbcTemplate().getNativeJdbcExtractor().getNativeConnection(conn); 
      DB2Connection db2conn = (DB2Connection) conn; ③ 这时可以强制进行类型转换了 
      … 
    } catch (Exception e) { 
      e.printStackTrace(); 
    }     
  } 
}  

  在 ① 处我们通过 DataSourceUtils 获取当前线程绑定的数据连接,为了使用线程上下文相关的事务,通过 DataSourceUtils 从数据源中获取连接是正确的做法,如果直接通过 dateSource 获取连接,则将得到一个和当前线程上下文无关的数据连接实例。

  JdbcTemplate 可以在配置时注入一个本地 JDBC 对象抽取器,要使代码 清单 1 正确运行,我们必须进行如下配置:

  清单 2. 为 JdbcTemplate 装配本地 JDBC 对象抽取器

… 
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"  
 destroy-method="close"> 
    <property name="driverClassName" 
      value="${jdbc.driverClassName}" /> 
    <property name="url" value="${jdbc.url}" /> 
    <property name="username" value="${jdbc.username}" /> 
    <property name="password" value="${jdbc.password}" /> 
</bean>  
① 定义 DBCP 数据源的 JDBC 本地对象抽取器 
<bean id="nativeJdbcExtractor"  
class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor" 
lazy-init="true" />  
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 
    <property name="dataSource" ref="dataSource" /> 
    ② 设置抽取器 
    <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>  
</bean> 
<bean id="postDao" class="com.baobaotao.dao.jdbc.PostJdbcDao"> 
    <property name="jdbcTemplate" ref="jdbcTemplate" /> 
</bean> 

  在获取 DB2 的本地 Connection 实例后,我们就可以使用该对象的一些特有功能了,如使用 DB2Connection 的特殊 API 对 LOB 对象进行操作。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章