Hibernate框架映射Oracle中long类型字段

本文介绍了在使用Hibernate框架时如何处理Oracle数据库中的LONG类型字段。由于Oracle的LONG类型与Java的long不同,直接映射会导致问题。解决方法是自定义UserType,通过流进行读写操作。提供了一个CustomLong类的实现示例,以及对应的hbm.xml配置和hibernate.cfg.xml的设置,以避免映射问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 stub

               returnnull;

        }

 

        //深度拷贝,强制返回字符串

        publicObject deepCopy(Object value) throws HibernateException {

               //TODO Auto-generated method stub

               if(null == value)

                       return"";

               else

                       returnnew String((String) value);

        }

 

        //反序列化

        publicSerializable disassemble(Object arg0) throws HibernateException {

               //TODO Auto-generated method stub

               returnnull;

        }

 

        //判断是否相等

        publicboolean equals(Object x, Object y) throws HibernateException {

               //TODO Auto-generated method stub

               return(x == y) || (x != null && y != null && (x.equals(y)));

        }

 

        //获取哈希码

        public inthashCode(Object arg0) throws HibernateException {

               //TODO Auto-generated method stub

               return0;

        }

 

        // 是否可变

        publicboolean isMutable() {

               //TODO Auto-generated method stub

               returnfalse;

        }

 

        //获取字段值

        publicObject nullSafeGet(ResultSet rs, String[] name, Object obj)

                       throwsHibernateException, SQLException {

               //TODO Auto-generated method stub

               char[]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 stub

               Strings = (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 stub

               returnnull;

        }

 

        public ClassreturnedClass() {//返回java类型

               //TODO Auto-generated method stub

               returnjava.lang.String.class;

        }

 

        public int[]sqlTypes() {//返回sql属性类型

               //TODO Auto-generated method stub

               returnnew 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的朋友们有帮助。
       

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值