【深入Hibernate】——根据业务自定义Clob数据类型

来源:互联网 发布:abstract php 编辑:程序博客网 时间:2024/06/06 13:20

  引言

 

  最近项目涉及到大文本字段Clob,它是大文本中多字节存储数据类型,还有一个与它类似的是Blob,Blob是大文

本单字节存储数据类型。看《深入浅出Hibernate》里看到Clob可以进行自定义数据类型,很受用,所以这里将代码

留存下来备用。


  代码


 

public class StringClobType implements UserType {    private static final String ORACLE_DRIVER_NAME="Oracle JDBC driver";    private static final int ORACLE_DRIVER_MAJOR_VERSION=9;    private static final int ORACLE_DRIVER_MINOR_VERSION=0;    @Override    public int[] sqlTypes() {        return new int[]{Types.CLOB};    }    @Override    public Class returnedClass() {        return String.class;    }    @Override    public boolean equals(Object x, Object y) throws HibernateException {        return !org.apache.commons.lang3.ObjectUtils.notEqual(x,y);    }    @Override    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {        Clob clob = rs.getClob(names[0]);        return (        clob == null?null:clob.getSubString(1,(int)clob.length()));    }    @Override    public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {        DatabaseMetaData dbMetaData = st.getConnection().getMetaData();        if(value == null){            st.setNull(index,sqlTypes()[0]);        }else if (ORACLE_DRIVER_NAME.equals(dbMetaData.getDriverName())){            if(dbMetaData.getDriverMajorVersion() >= ORACLE_DRIVER_MAJOR_VERSION &&               dbMetaData.getDriverMinorVersion() >= ORACLE_DRIVER_MINOR_VERSION){                try{                    Class oracleClobClass = Class.forName("oracle.sql.CLOB");                    Class partypes[] = new Class[3];                    partypes[0] = Connection.class;                    partypes[1] = Boolean.TYPE;                    partypes[2] = Integer.TYPE;                    Method createTemporaryMethod = oracleClobClass.getDeclaredMethod("createTemporary",partypes);                    Field durationSessionField = oracleClobClass.getField("DURATION_SESSION");                    Object arglist[] = new Object[3];                    Connection conn = st.getConnection().getMetaData().getConnection();                    Class oracleConnectionClass=Class.forName("oracle.jdbc.OracleConnection");                    if(!oracleClobClass.isAssignableFrom(conn.getClass())){                        throw new HibernateException("Must be a oracle.jdbc.OracleConnection",conn.getClass().getName());                    }                    arglist[0] = conn;                    arglist[1] = Boolean.TYPE;                    arglist[2] = durationSessionField.get(null);                    Object tempClob = createTemporaryMethod.invoke(null,arglist);                    partypes = new Class[1];                    partypes[0] = Integer.TYPE;                    Method openMethod = oracleClobClass.getDeclaredMethod("open",partypes);                    Field modeReadWriteField = oracleClobClass.getField("MODE_READWRITE");                    arglist = new Object[1];                    arglist[0] = modeReadWriteField.get(null);                    openMethod.invoke(tempClob,arglist);                    Method getCharacterOutputStreamMethod = oracleClobClass.getDeclaredMethod("getCharacterOutputStream",null);                    Writer tempClobWriter = (Writer) getCharacterOutputStreamMethod.invoke(tempClob,null);                    tempClobWriter.write((String)value);                    tempClobWriter.flush();                    tempClobWriter.close();                    Method closeMethod = oracleClobClass.getDeclaredMethod("close",null);                    closeMethod.invoke(tempClob,null);                    st.setClob(index,(Clob)tempClob);                } catch (ClassNotFoundException e) {                    throw new HibernateException("Unable to find a required class.\n" + e.getMessage());                } catch (NoSuchMethodException e) {                    throw new HibernateException("Unable to find a required method.\n" + e.getMessage());                } catch (NoSuchFieldException e) {                    throw new HibernateException("Unable to find a required field.\n" + e.getMessage());                } catch (IllegalAccessException e) {                    throw new HibernateException("Unable to find a required method or field.\n" + e.getMessage());                } catch (InvocationTargetException e) {                    throw new HibernateException(e.getMessage());                } catch (IOException e) {                    throw new HibernateException(e.getMessage());                }            }else {                throw new HibernateException("No CLOBS support. Use drivver version"                        + ORACLE_DRIVER_MAJOR_VERSION                        + ",minor"                        + ORACLE_DRIVER_MINOR_VERSION);            }        } else {            String str = (String) value;            StringReader r = new StringReader(str);            st.setCharacterStream(index,r,str.length());        }    }    @Override    public Object deepCopy(Object value) throws HibernateException {        if(value == null) return null;        return new String((String)value);    }    @Override    public boolean isMutable() {        return false;    }}


原创粉丝点击