有UserType的代码
参考:
http://blog.csdn.net/zhanngle/article/details/4188423
http://blog.csdn.net/daryl715/article/details/1927502
在Oracle中执行以下sql
create table A (
id char(5)
);
insert into A values('11');
String sql="select * from A where id=?";
pstm=conn.prepareStatement(sql);
pstm.setString(1,"11");
rs=pstm.executeQuery();
System.out.println(rs.next());
String sql="select * from A where trim(id)=?";
是不是查出来了,哈!,可是能不能不用trim()就能查出来呢?
String sql="select * from A where id=?";
pstm=conn.prepareStatement(sql);
((OraclePreparedStatement)pstm).setFixedCHAR(1, "11");
rs=ps.executeQuery();
System.out.println(rs.next());
执行看看,查询成功!
这是为什么呢,由于我英文水平不好,所以请打开以下链接看看!
http://forums.oracle.com/forums/thread.jspa;jsessionid=8d92200630de527b2f61c7ef4d3296318c855aa88fe1.e34Tb34Lb34PbO0Lb3eTahiPbNyTe0?messageID=504702
对于hibernate查询oracle char类型可谓是遇到大麻烦了,因为hibernate内部使用的是PrepareStatement,在查询oracle char类型时会出现上述的问题,我的解决方案是定义一个UserType,该UserType对字段值自动补齐空格,以下是我的主键示例:
@Id
@GeneratedValue(generator = "id")
@GenericGenerator(name = "id", strategy = "uuid")
@Type(parameters = {}, type = "test.OracleCharType")
private String id;
test.OracleCharType就是我自定义的UserType类,它实现了当我们传进来的id值少于5位时,自动加空格,使id值满足5位.
这样,当我们使用以下语句获取对象,便能获取到了.
session.get(A.class,"11")
它底层的查询语句会转换成
select * from A where id='11 ';
怎么样,明白了不.你可能会说为什么使用加空格而不使用trim()函数截取的方式,那是因为hibernate的UserType只能对字段值做手脚(如:'11'变成了'11 ').
这种方案只需要定义一个UserType,然后在hbm文件里配制一下就可使用了.
当然这只是其中一种解决方案,如果你不嫌麻烦的话,可以将查询都改成hql+trim()的方式查询,那么工作量会加很多.
也可以为每个po对象加一个
附:
基于hibernate 4.1.9 的UserType 实现类 OracleCharType
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;
public class OracleCharType implements UserType{
private int length = 32;
@Override
public int[] sqlTypes() {
return new int[]{Types.CHAR};
}
@Override
public Class returnedClass() {
return String.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y)
return true;
if (x == null || y == null)
return false;
if (x instanceof String && y instanceof String)
return x.equals(y);
return false;
}
@Override
public int hashCode(Object x) throws HibernateException {
if (x instanceof Character) {
return ((Character)x).hashCode();
}
return 0;
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
return rs.getString(names[0]);
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
throws HibernateException, SQLException {
StringBuffer v = new StringBuffer((String) value);
if (v.length() < length) {
int count = length - v.length();
for (int i = 0; i < count; i++) {
v.append(" ");
}
}
st.setString(index, v.toString());
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return null;
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return null;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return null;
}
}