首页 / 操作系统 / Linux / Hibernate框架映射Oracle中long类型字段
首先谈谈关于Oracle中的long类型。百度一下可知道。long在Oracle中并非同Java当中的基本数据类型long,前者是字符串类型,后者则是长整形。对于像我这样的初学者肯定很容易误以为两者相同。在Oracle中:LONG 数据类型中存储的是可变长字符串,最大长度限制是2GB;对于超出一定长度的文本,基本只能用LONG类型来存储,数据字典中很多对象的定义就是用LONG来存储的(当然你也可以考虑使用像CLOB这种大字段处理这些文本);LONG类型主要用于不需要作字符串搜索的长串数据,如果要进行字符搜索就要用varchar2类型。当然,LONG也有限制:一个表中只能包含一个 LONG 类型的列;不能索引LONG类型列,等等。(以上对LONG的解析不完整,详细的可以再网上做了解)明显,使用Hibernate做ORM时,java提供的类型或者Hibernate提供的数据都没有完全匹配LONG的。看网上有很多朋友建议使用 String,Char[]等,String的最多在我的方法中使用到String类。但是如果直接使用String做ORM时,数据量很大在插入式就会 出现问题了。解决办法:做ORM时使用自定类型,对LONG的字段用流进行读写。package org.comsys.userType;import java.io.IOException;import java.io.Reader;import java.io.Serializable;import java.io.StringReader;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import org.hibernate.HibernateException;import org.hibernate.usertype.UserType;public class CustomLong implements UserType {publicCustomLong() {}//序列化publicObject assemble(Serializable ser, Object obj)throwsHibernateException {//TODO Auto-generated method stubreturnnull;}//深度拷贝,强制返回字符串publicObject deepCopy(Object value) throws HibernateException {//TODO Auto-generated method stubif(null == value)return"";elsereturnnew String((String) value);}//反序列化publicSerializable disassemble(Object arg0) throws HibernateException {//TODO Auto-generated method stubreturnnull;}//判断是否相等publicboolean equals(Object x, Object y) throws HibernateException {//TODO Auto-generated method stubreturn(x == y) || (x != null && y != null && (x.equals(y)));}//获取哈希码public inthashCode(Object arg0) throws HibernateException {//TODO Auto-generated method stubreturn0;}// 是否可变publicboolean isMutable() {//TODO Auto-generated method stubreturnfalse;}//获取字段值publicObject nullSafeGet(ResultSet rs, String[] name, Object obj)throwsHibernateException, SQLException {//TODO Auto-generated method stubchar[]content = new char[1024000];//第一字符数组保存流读出的内容char[]buffer = new char[1024];//存放每次读的内容intlen = 0;intoff = 0;intcontentLen=1024000;Readerreader = rs.getCharacterStream(name[0]);//ResultSet结果集中读字符流的方法//下面是基本的字符流的方法try {while(true){len= reader.read(buffer);if(len==-1)break;if(off+len> contentLen){//代表字段的内容超出了我们预定义的内容的大小,需要扩充char[]tmp = new char[contentLen+1024000];//定义扩充区System.arraycopy(content,0, tmp, 0, off);//将content拷贝到扩充区中,扩充content= tmp;contentLen= contentLen + 1024000;//长度扩充}System.arraycopy(buffer,0, content, off, len);//最后将每次读的都拷贝到content中off+=len;//记录读的位置长度}}catch (IOException e) {e.printStackTrace();}returnnew String(content,0,off);}public voidnullSafeSet(PreparedStatement pr, Object value, int index)throwsHibernateException, SQLException {//TODO Auto-generated method stubStrings = (String) value;System.out.println(s);if(null == s)s= "";Readerre = new StringReader(s);//将内容字符串用StringReader读入pr.setCharacterStream(index,re, s.length());//最后用PreparedStatement的方法设置字段内容}publicObject replace(Object arg0, Object arg1, Object arg2)throwsHibernateException {//TODO Auto-generated method stubreturnnull;}public ClassreturnedClass() {//返回java类型//TODO Auto-generated method stubreturnjava.lang.String.class;}public int[]sqlTypes() {//返回sql属性类型//TODO Auto-generated method stubreturnnew int[] { java.sql.Types.LONGVARCHAR };}}接下来是配置****.hbm.xml<!-- 字段 --><propertygenerated="never" lazy="false" name="longType"type="org.comsys.userType.CustomLong"><columnlength="0" name="LONG_TYPE"/></property>最后在hibernate.cfg.xml中加入配置<!-- 批处理为0 --><property name="jdbc.batch_size">0</property>否则会有以下错误实体类中对应字段的类型依然为String,这样就ok了,希望对正在尝试hibernate映射Oracle中LONG的朋友们有帮助。