[Hibernate求助]如何构造自己的映射类型?

03-07-10 yadan
我在数据库中存储的字段是TINYINT类型,想映射成java类中的Boolean(或者boolean)对象。我看了hibernate文档的4.2.4. Custom value types节,并自己写了扩展了UserType类,如下:

/**
* 从java对象Boolean到sql中的TINYINT的映射
*/
public class BooleanMappingType implements UserType
{
   private static final int [] TYPE = {Types.TINYINT}; 
   
   public int[] sqlTypes()
   {
       return TYPE;
   }
   
   public Class returnedClass()
   {
       return Boolean.class;
   }
   
   public boolean equals(Object x, Object y) throws net.sf.hibernate.HibernateException
   {
       if( x.equals(y) ) return true;
       if( x == y)  return true;        
       return false;        
   }
   
   public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws net.sf.hibernate.HibernateException, java.sql.SQLException
   {
       Byte b = (Byte)Hibernate.BYTE.nullSafeGet(rs, names[0]);
       if( b == null)
           return Boolean.FALSE;
       if(b.intValue() != 0)
           return Boolean.TRUE;
       return Boolean.FALSE;
   }
   
   public void nullSafeSet(PreparedStatement psmt, Object value, int index) throws net.sf.hibernate.HibernateException, java.sql.SQLException
   {
       Boolean b = (value == null) ? Boolean.FALSE : (Boolean)value;
       Hibernate.BYTE.nullSafeSet(psmt, b, index);
   }
   
   public Object deepCopy(Object x) throws net.sf.hibernate.HibernateException
   {
       if(x.equals(Boolean.TRUE))
           return new Boolean(true);
       if(x.equals(Boolean.FALSE))
           return new Boolean(false);
       return null;
   }
   
   public boolean isMutable()
   {
       return true;
   }
}
<p>

还没有测试,因为有一点疑问,这个类中,并没有什么方法表明数据库中存储的TINYINT值怎么转换成对应的Boolean对象,我自然是想数据库中存储1时转换成TRUE,存储0时转换成FALSE。但在这个类中并没有什么方法申明啊。不知道如何解决这个问题。

另外,如果想把TINYINT列映射成java的原始类型boolean,又该如何解决。

想了很久,一直没有弄出来,请大家帮忙看看,谢谢!

yadan
2003-07-10 12:27
如果guty、robbin 、Jevang这些高人能回答就好了~

robbin
2003-07-10 13:44
不知道你用的是哪个数据库?

有些数据库里面本来就没有boolean型的字段,在这样的数据库里面往往就是用整数类型的0表示false,1表示true,比如Oracle数据库里面,如果在某数值字段里面填0,然后PreparedStatement取出来 getBoolean(1,fieldName),就是当做boolean取的,取出来就是false。

这种转换应该是由JDBC来完成的,和Hibernate无关。不过Hibernate也可以做,请看hibernate.properties里面有一行:

hibernate.query.substitutions true 1, false 0, yes 'Y', no 'N'

你自己写程序应该不用去管它了。

robbin
2003-07-10 14:00
说的再明确一点:

很多数据库都没有boolean字段类型,往往用整数类型替代,1就代表true,0就代表false。这种把Java中的true/false值 转换为数据库中1/0是由厂商提供的JDBC驱动类库来完成的,该过程对程序员是透明的。你指管把true/false往数据库里面插,实际上插入的就是1/0。

当然Hibernate也可以完成这样的转换,需要你在Hibernate配置文件里面定义,默认的hibernate.properties已经定义好了该转换规则。

总之像你那种情况,你就直接在Java里面当做boolean来运算就对了,什么多余的工作都不需要做。

yadan
2003-07-10 14:35
robbin你好,谢谢你的回答!我用的是mysql。

上面那个问题可以那样解决。但是如果我把自定义映射的类型再扩展一下,不局限于boolean的映射,而扩展到一个字段和任意一个java对象的映射。

例如User表,有一个字段"CREATE_TIME"类型是VARCHAR(15),对应User类的属性createTime的类型是java.util.Date。数据库中存储的是Date转换成长整形再补零到15位长度的字符串(参考jive的时间字段处理)。就是说,每次从数据库到类字段都需要用一个Util类进行转换。这样的情况如何处理?我看hibernate的文档是扩展CompositeUserType或者UserType接口,但不知道是这个接口如何调用我的Util转化方法。而且,这样作对象的比较是否需要重载。(当然,把数据库字段类型改为DATETIME就很容易解决这个问题了,但我想了解清楚这种hibernate自定义映射转换的方法)

或者说,这样的转化是在User类的getter,setter方法中作?

猜你喜欢
5Go 1 2 3 4 ... 5 下一页