Java 中, java.lang.String 可用于表示长字符串(长度超过 255 ),字节数组 byte[] 可以用于存放图片户或文件二进制数据。此外,在 JDBC API 中还提供了 java.sql.CLOB java.sql.BLOB 类型,他们分别表示标准 SQL 中的 CLOB (字符大对象)和 BLOB (二进制大对象)类型。表 2.4 列出了 Java 大对象, Hibernate 映射类型以及标准 SQL 的对应关系。
2.4
 
 
 
 
映射类型
Java 类型
标准 SQL 类型
binary
byte[]
VARBINARY( 或者 BLOB)
text
java.lang.String
CLOB
serilizable
实现 java.io.Serializable 的任何一个 Java
VARBINARY( 或者 BLOB)
clob
java.sql.CLOB
CLOB
blob
java.sql.BLOB
BLOB
注意:不允许用表 2.4 中列出的数据类型来定义持久化类的 OID
2 )、 BLOB,CLOB 数据的处理(以 Oracle 数据库为例):
  假设我们有如下表
 
T_User 
id     number   <pk>
name varchar2(50)
age    number
image    BLOB
resume   CLOB          
  对应的映射文件如下:
<hibernate-mapping>
 <class name=”com.neusoft.hibernate.db.entity.TUser” table=”T_User”>
<id name=”id” column=”id” type=”java.lang.Integer”>
 <generator class=”native”/>
</id>
<property name=”name” type=”java.lang.String” column=”name”/>
<property name=”age” type=”java.lang.Integer” column=”age”/>
<property name=”image” type=”java.sql.Blob” column=”image”/>
<property name=”resume” type=”java.sql.Clob” column=”resume”/>
 </class>
</hibernate-mapping>
实体类如下:
public class Tuser implements Serializable{
 private Integer id;
 private String name;
 private Integer age;
 private Blob image;
 private Clob resume;
 …getter/setter…..
}
BLOB CLOB 这种大对象一般都是采用流机制作为数据读取方式,所以这种读取方式在 Oracle 这种自视为数据库中贵族的数据库中对这种操作就会有诸多的限制,有时候会叫人觉得不太友好(这是典型的店大欺客)
限制一: Oracle JDBC 不允许流操作以批量方式执行,如果发生这种错误一般会抛出
ERROR JDBCExceptionReport:streams type cannot be used in batching. 出现这种情况一般都需要将 hibernate.cfg.xml 中的 hibernate.jdbc.batch_size 设定为 0 即可消除,但是这就会影响其他的更新,插入,删除操作的性能,因此必须在一个数据库事务中对 Clob,Blob 进行操作,也只有在一个数据库事务中 Clob,Blob 对象才会有效。
限制二: Oalce Blob/Clob 具有独特的访问方式,这种类型字段拥有一个游标 (cursor) JDBC 必须通过游标对 Blob/Clob 进行操作,在 Blob/Clob 创建之前我门无法获得其游标句炳,这就意味着必须首先创建一个空 Blob/Clob 字段,在丛空 Blob/Clob 获取游标,然后写入我们期望的数据。
 
首先看一下采用传统 JDBC 进行操作的代码:
//…. 获取 Connection 连接
conn.setAtuoCommit(false);
// 插入 Blob/Clob 空值字段
PrepareStatement prestmt=conn.prepareStatement(“insert into T_USER(name,age,id,image,resume) values(?,?,?,?,?)”);
prestmt.setString(1,”zx”);
prestmt.setInt(2,26);
prestmt.setInt(3,5);
// 通过 oracle.sql.BLOB/CLOB.empty_lob() 方法构造空 Blob/Clob 对象
prestmt.setBlob(4,oracle.sql.BLOB.empty_lob());
prestmt.setClob(5,oracle.sql.CLOB.empty_lob());
prestmt.executeUpdate();
prestmt.close();
// 再次从数据库中获得 Blob/Clob 句炳
prestmt=conn.prepareStatement(“select image,resume from T_USER where id=? for update ”);
prestmt.setInt(1,5);
ResultSet rset=prestmt.executeQuery();
rset.next();
oracle.sql.BLOB imgBlob=(oracle.sql.BLOB)rset.getBlob();
oracle.sql.CLOB resClob=(oracle.sql.CLOB)rset.getClob();
// 将二进制数据写入 Blob
FlieInputStream fin=new FileInputStream(“c://image.jpg”);
OutputStream out=imgBlob.getBinaryOutputStream();
byte[] buf=new byte[fin.available()];
int len;
while((len=fin.read(buf))!=-1){
 out.write(buf,0,len);
}
fin.close();
out.close();
// 将字符串写入 Clob
resClob.putString(1,”This is my clob”);
// 将更新写回数据库
prestmt=conn.prepareStatement(“update T_USER set image=?,resume=? where id=? ”);
prestmt.setBlob(1,imgBlob);
prestmt.setClob(2,resClob);
prestmt.setInt(3,5);
prestmt.executeUpdate();
prestmt.close();
conn.commit();
conn.close();
 
 
以上是传统的采用 JDBC 方式处理,注意他将连接的自动提交属性设置为 false 然后将所有的操作并入一个事务中,然后进行提交,这是处理 Oracle Blob/Clob 字段的一般机制,所以 Hibernate 的处理就应该模仿 JDBC 的处理方式,因为从某种角度来讲 Hibernate 是对 JDBC 的封装因为它的底层访问机制仍然是基于 JDBC 的。
 
Hibernate 的处理:
TUser user=new TUser();
user.setAge(new Integer(26));
user.setName(“zx”);
// 创建空 Blob/Clob 对象
user.setImage(Hibernate.createBlob(new byte[1]));
user.setResume(Hibernate.createClob(“ “));// 注意这里的参数是一个空格
Transaction tx=session.beginTransaction();
session.save(user);
// 调用 flush 方法,强制 Hibernate 立即执行 insert sql
session.flush();
// 通过 refresh 方法,强制 Hibernate 执行 select for update
session.refresh(user,LockMode.UPGRADE);
// Blob 写入实际内容
oracle.sql.BLOB blob=(oracle.sql.BLOB)user.getImger();
OutputStream out=blob.getBinaryOutputStream();
FileInputStream fin=new FileInputStream(“c://image.jpg”);
byte[] buf=new byte[fin.available()];
int len;
while((len=fin.read())!=-1){
 out.write(buf,0,len);
}
fin.close();
out.close();
// Clob 中写入数据
oracle.sql.CLOB clob=user.getResume();
java.io.Writer writer=clob.getCharacterOutputStream();
writer.write(“This is my resume!”);
writer.close();
session.saveOrUpdate(user);
session.commit();
tx.commit();
 
在实际应用中,对于 Clob 字段可以简单的将其映射为 String 类型,不过在 Oracle Thin Driver Clob 字段支持上有欠缺,当 Clob 内容超过 4000 字节时将无法读取,而 Oracle OCI Driver( 需要在本地安装客户端组件 ) 则可以完成大容量 Clob 字段操作。
 
对于上面的代码相信作为成熟的工程师来说都闻到一些 bad smell, 如果 Blob/Clob 字段普遍存在的话,那么我们的持久层逻辑可能遍布这种复杂的逻辑,不过不要着急在我即将讲解的客户自定义类中我们将会看到一个解决方案,通过自定义类型我们可以对数据类型的通用性进行抽象,对于 Blob/Clob 字段我们可以定义一种类型并以这种类型作为 Blob/Clob 字段的映射类型。(好了等到下一篇再说吧!)

Java大对象类型的Hibernate映射相关推荐

  1. Java 时间和日期类型的 Hibernate 映射

    以下情况下必须显式指定 Hibernate 映射类型 一个 Java 类型可能对应多个 Hibernate 映射类型. 例如: 如果持久化类的属性为 java.util.Date 类型, 对应的 Hi ...

  2. oracle对大对象类型操作:blob,clob,nclob,bfile

    在oracle中,有4个大对象(lobs)类型可用,分别是blob,clob,bfile,nclob.下面是对lob数据类型的简单介绍.blob:二进制lob,为二进制数据,最长可达4GB,存贮在数据 ...

  3. Java大对象lob_JavaEE JDBC 读写LOB大对象

    JDBC 读写LOB大对象 @author ixenos LOB 除了数字.字符串和日期之外,许多数据库还可以存储大对象,例如图片或其他数据, 在SQL中,二进制大对象称为BLOB,字符型大对象称为C ...

  4. postgresql java类型_JAVA存取PostgreSQL大对象类型oid

    //VM配置:256M-512M //通过lo_import('文件路径')函数向oid字段插入二进制文件,通过(不会内存溢出). /** * * @author Liu Yuanyuan */ pr ...

  5. Mybatis返回类型和Java常见对象类型

    点滴记录 项目开发中经常用到的: 1.resultMap 使用这个返回需要实体类和数据库字段关系映射如下面的:BaseResultMap <?xml version="1.0" ...

  6. Hibernate - Java 类型, Hibernate 映射类型及 SQL 类型之间的对应关系

    [1]常见的映射关系表 常见的映射对应关系如下表所示: Hibernate映射类型 Java类型 标准SQL类型 字节大小 integer/int java.lang.Integer/int INTE ...

  7. Spring 让 LOB 数据操作变得简单易行,LOB 代表大对象数据,包括 BLOB 和 CLOB 两种类型

    http://www.ibm.com/developerworks/cn/java/j-lo-spring-lob/index.html 本文讲解了在 Spring 中处理 LOB 数据的原理和方法, ...

  8. Java中的对象类型像引用还是指针,谁是谁非?

    Java中的对象类型像引用还是指针,谁是谁非? 作者:海枫 地址:http://blog.csdn.net/linyt 作为一名程序员,我们应该对新知识和新技术刨根问底,而不应泛泛而谈.我未曾接触到J ...

  9. java类对象转化成字符串_String类型字符串(xml格式)转换成java对象类型

    使用到的包: 1. 2. 将字符串类型的字符串转换成的Java的对象时,需要先将字符的格式转换成JSON格式的字符串(所以用到了json.jar包),在使用JSON格式的字符串转换成的Java的对象类 ...

最新文章

  1. visual studio 代码提示插件_程序员请收好:10个非常实用的 VS Code 插件
  2. SQL编程:模糊表关联不求人 --- concat + like就能行
  3. mysql extended_explain之三:MYSQL EXPLAIN语句的extended 选项学习体会,分析诊断工具之二...
  4. 【测试】ABAP直连外部数据库
  5. 阿里1682亿背后的协同研发云——云效正式商业化
  6. Oracle创建 表空间 用户 给用户授权命令
  7. java 字符串模糊匹配_Java实现伪查询(全匹配+模糊匹配)
  8. 动态代理3之代理工厂实现
  9. 深入理解css优先级
  10. c语言文件压缩与解压缩实验报告,哈弗曼树的文件压缩和解压实验报告(C语言).doc...
  11. Hadoop JAVA 开发说明
  12. 在论坛中出现的比较难的sql问题:5(row_number函数 分页、随机返回数据)
  13. 2021-2025年中国乙酰丙酸乙酯行业市场供需与战略研究报告
  14. 关于insert语句的插入问题
  15. 用正则表达式生成文章的目录大纲
  16. 深度学习--激活函数之sigmoid激活函数
  17. Java 编程技巧之样板代码
  18. 扇形图形用html,css如何画扇形?
  19. win10计算机添加右键菜单,win10清理鼠标右键菜单提升电脑速度的方法
  20. python中括号的作用_浅析python 中大括号中括号小括号的区分

热门文章

  1. 数据可视化--实验五:高维非空间数据可视化
  2. css3实现小图标向下引导小箭头动态效果
  3. 人脸识别篇---人脸对齐
  4. Java中数组的定义和使用
  5. gtsam Overview
  6. 怎么选择合适的机柜?网络机柜服务器机柜
  7. win10如何查看显卡配置
  8. 线性规划-概念与公式总结
  9. 基于单片机波形发生器PCB原理图报告设计资料-基于单片机比赛计时计分电路仿真设计-基于单片机报警器与旋转灯设计-基于单片机八路数据电压采集报警控制系统-基于单片机病房呼叫系统控制系统设计【毕设课设资】
  10. 联想小新使用Alt+insert快捷键