歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> 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 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的朋友們有幫助。

Copyright © Linux教程網 All Rights Reserved