IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  WebSphere  >

使用 WebSphere Studio 将 CMP 实体 Bean 字段映射到 CLOB 列

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

Wayne Beaton (wbeaton@ca.ibm.com), IBM Software Services for WebSphere, IBM 加拿大

2004 年 7 月 01 日

本文向您展示如何使用 WebSphere Application Server 转换器来解决把字符型大型对象列映射到 EJB 容器管理持久性实体 Bean 字段时会出的问题,以及进行其他的转换或变形,比如更改在数据库和 Java 之间传递的字符串值的格式。

引言

一位顾客最近向我提出了他们在把应用程序从 BEA WebLogic Server 移植到 IBM? WebSphere? Application Server V5.1 时遇到的一个问题。他们现有的数据库使用几个字符型大型对象(CLOB)类型列来表示一些字符串值,在他们将这些列映射到企业 Java? persistence,(CMP)实体 Bean 字段时遇到了一些奇怪的运行时错误。

SQL 中的 CLOB 数据类型用于表示大量的字符数据,特别适合那些过大或者不适合用 CHAR 或 VARCHAR 类型表示的数据。在将使用 CMP 的 EJB 实体 Bean 中的一个持久性字段映射到一个 CLOB 列时,WebSphere Application Server 将该字段串行读取和写入到列中。如果串行化是所需要的,就大功告成,但如果不是,则需要做一些工作了。





回页首


串行化问题

WebSphere Application Server 串行化一个持久性字段的内容,而不考虑该字段的类型。即使一个字符串值(它可以自然地适应 CLOB 列)被串行化——也就是说,将该字符串对象的对象字节表示保存在数据库中,而不仅仅保存该字符串的内容。当从列中将值读回到持久性字段时,串行化对象被反串行化。以下代码片断展示了 WebSphere Application Server V5.1 生成的将一个 java.lang.String 值储存到一个 CLOB 列的代码:

...
tempByteArrayOutputStream=new java.io.ByteArrayOutputStream();
try {
   java.io.ObjectOutputStream objStream
      =new java.io.ObjectOutputStream(tempByteArrayOutputStream);
   objStream.writeObject(concreteBean.getResume());
} catch(java.io.IOException x) {}
record.set(3,tempByteArrayOutputStream.toByteArray());
...

请注意, java.io.ObjectOutputStream 用于将字段的内容从字符串转换成一组字节。该代码将为字符串 hello 产生如下输出:

(byte[]) [-84, -19, 0, 5, 116, 0, 5, 104, 101, 108, 108, 111]

最后五个值是字符串中相应字符的 ASCII 值。添加的字节是串行化过程的构件。

如果正在使用一个新(空的)数据库,似乎一切都工作正常。除非明确地检查列的内容,否则可能永远无法了解到出现了多余的内容。只有在另一个应用程序(可能是用不同语言编写的应用程序)试图处理该列时,或者在试图读取遗留数据时,问题才会出现。如果使用一个现有(已填充数据)的表,那么在尝试读取该列时可能就会发现问题。

在 WebSphere Application Server 的防范措施中,将任意一个可串行化的 Java 对象储存到列中(EJB 2.0 规范,10.3.3 节, 相关的值对象部分提到这些内容)的行为是合理的。假设有一些任意的对象,这些对象没有被逐个字段地映射到您想要储存的表中。将这些对象以串行化形式储存是非常自然的事情。不幸的是,这太过于死板:所有的对象都以相同的方式储存,即使那些可以用更为自然的方式储存的字符串和字节值也不例外。





回页首


转换器

一切都未丢失。WebSphere Application Server 提供了一种在值的数据库表示方式和 Java 表示方式之间转换的机制。您可以使用 自定义转换器(custom converter)来提供对数据如何在数据库和一个实体 Bean 之间映射的更好粒度(finer-grained)的控制。WebSphere Studio Application Developer 让创建转换器变得简单,转换器将以您所期望的方式来处理字段和列。

创建转换器

以下列出了创建步骤:

  1. 高亮显示 EJB 项目。
  2. 选择 New => Other
  3. 选择 EJBConverterComposer
  4. 遵循如下步骤来创建如图 1 所示的转换器: 为 Fully qualified converter name字段提供一个完全的包和类名,并确保选取了 Generate a converter stub class复选框。
  5. 编辑生成的转换器存根。

图 1. EJB 转换器创建向导
图 1. EJB 转换器创建向导

转换器自身要求提供两个方法: dataFrom(Object)objectFrom(Object)

dataFrom(Object) 方法用于将 Java 对象转换成数据库表示。该方法的单个参数是来自持久性字段的值。此方法需要将该值转换成某种数据库能够储存的格式。对于 CLOB 列,返回的类型应该是 byte[] 值:

public Object dataFrom(Object anObject) {
if (anObject == null)
   return anObject;
String text = (String)anObject;
return text.getBytes("US-ASCII");
}

objectFrom(Object) 方法则相反——它通过作为单独参数提供的列值来创建一个对象。对于 CLOB 字段,该参数将是 byte[] 类型。转换器代码需要将字节类型的值转换到任何一种字段中表示的对象:

public Object objectFrom(Object value) {
   if (value == null) return value;
   byte[] bytes = (byte[])value;
   return new String(bytes, "US-ASCII");
}

在此示例中,将一个 java.lang.String 值转换成字节值,然后再转换回来。处理字符串时请注意,在对值进行编码和解码时使用了相同的字符集信息。如果使用不需要字符集参数的方法或构造器变量,Java 将对系统用缺省值替代。配置使用不同字符集的系统可能执行不同的转换。总之,明确地指定字符集是最安全的做法。

对于某些工作,可能会有其他种类的转换。例如,可能使用一个转换器以某种标准方式在数据库中表示图像(GIF、JPEG、PNG,等等)。

使用转换器

一旦创建了转换器,它在映射编辑器中立即可用。转换器是专用字段映射的属性,要应用转换器,请在映射编辑器的 Overview 部分选择适当的映射,并将 Transformation 属性设置为您的新转换器:


图 2. 在 Properties 视图中设置一个字段映射的转换

图 2. 在 Properties 视图中设置一个字段映射的转换

设置值后,保存映射并生成部署代码。如果需要,可以在转换器中设置断点,以便在调试模式逐步跟踪它的执行过程,这样做是有帮助的,这是因为实际的转换器通常将会比以上展示的示例更为复杂。

使用适当的转换器,能够生成非常不同的代码来处理字段。以下片断展示了生成的代码,它使用转换器将来自实体 Bean 字段的值储存到数据库列中。通过移除转换器类中的包名称,该代码片断得以压缩,但这就是转换器实际生成的内容。

...
record.set(3,StringToCLOBConverter.singleton().dataFrom(concreteBean.getResume()));
...

singleton() 方法是在创建转换器时由向导自动生成的。生成的代码调用方法,并可以完全控制数据在储存到数据库之前的转换方式。





回页首


结束语

如果需要使用 CLOB 字段(为无论何种原因),WebSphere Application Server 转换器将有助于完成工作。也可以使用转换器来进行其他种类的转换。可以将这些转换应用于所有类型的字段。例如,可以更改在数据库和 Java 之间传递的字符串值的格式。



关于作者

Wayne Beaton是位于 Ottowa 的 IBM 加拿大公司的一位 Software Services for WebSphere 方面的高级软件顾问。他的研究重点是将 WebSphere 的早期版本和竞争产品移植到 WebSphere Application Server 5.0。他与别人合著过两本关于移植主题的 IBM 红皮书。Wayne 还工作于 WebSphere 教育计划和通常的咨询。他喜欢利用余暇时间说服人们相信极限编程、重构和单元测试实际上是很有效的。您可以通过 wbeaton@ca.ibm.com与 Wayne 联系。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?







回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款