java – 将一些布尔属性映射为枚举在Hibernate中设置
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 将一些布尔属性映射为枚举在Hibernate中设置,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6581字,纯文字阅读大概需要10分钟。
内容图文
![java – 将一些布尔属性映射为枚举在Hibernate中设置](/upload/InfoBanner/zyjiaocheng/824/e42c178bac2f4cc3a500f535795f1ebb.jpg)
我有一个实体,它在数据库中有一些BIT字段:
>可编辑
> needs_review
>活跃
这些字段使用Hibernate 3.6.9版本映射到其Java类中的布尔字段.这迫使我为每个想要获取的实体列表编写一个接口方法:
List<Entity> listEditables();
List<Entity> listReviewNeeded();
List<Entity> listActives();
或者编写一个通用的接口方法来实现它们的组合:
List<Entity> listEntities(boolean editables, boolean reviewNeeded, boolean actives);
第二个选择看起来更大,但是如果我将来添加另一个字段,则需要修改接口本身(以及与之耦合的每一行代码).
所以我决定将它表达为枚举集:
public enum EntityType{
EDITABLE, REVIEW_NEEDED, ACTIVE
}
//That way there's no need to change interface method's signature
List<Entity> listEntities(Set<EntityType> requiredTypes);
有意义的是,枚举匹配我想要实现的,实体类型本身应该有自己的Set< EntityType>:
public class Entity{
Set<EntityType> entityTypes;
}
然而,而不是我有映射的布尔值,逻辑上匹配该集合.然后我的问题是,有没有办法映射Set< EntityType>基于BIT字段的hibernate中的entityTypes还是我必须自己管理那些逻辑?
UPDATE
将它们映射为Set意味着可以使用in子句查询List,如果不是,则意味着在我的控制器和模型代码之间进行转换的额外步骤.
Set<EntityType> typesSet = Sets.newHashSet(EntityType.EDITABLE, EntityType.REVIEW_NEEDED);
//Obtains a list of every single entity which is EDITABLE or REVIEW_NEEDED
session.createCriteria(Entity.class).addRestriction(Restrictions.in("entityTypes",typeSet)).list();
解决方法:
我想我有一个解决方案.您感兴趣的是CompositeUserType.
举个例子,我可以使用我最近编写的InetAddress复合用户类型将128位IPv6地址/ IPv4Address对象映射到用户帐户实体内的两个64位长属性.
signupIp:InetAddress使用以下方法映射到两列(没有列数限制或相似):
@Columns(columns = {@Column(name = "ip_low", nullable = true), @Column(name = "ip_high", nullable = true)})
private InetAddress signupIp;
实现的有趣部分如下所示:
public class InetAddressUserType implements CompositeUserType {
@Override
public String[] getPropertyNames() {
return new String [] {"ipLow", "ipHigh"};
}
@Override
public Type[] getPropertyTypes() {
return new Type [] { LongType.INSTANCE, LongType.INSTANCE};
}
@Override
public Object getPropertyValue(Object component, int property) throws HibernateException {
if(component != null)
return toLong((InetAddress)component)[property];
else
return null;
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index,
SessionImplementor session) throws HibernateException, SQLException {
if(value != null) {
long [] longs = toLong((InetAddress)value);
st.setLong(index, longs[0]);
st.setLong(index + 1, longs[1]);
}
else {
st.setNull(index, LongType.INSTANCE.sqlType());
st.setNull(index + 1, LongType.INSTANCE.sqlType());
}
}
@Override
public void setPropertyValue(Object component, int property, Object value)
throws HibernateException {
throw new RuntimeException("This object is immutable");
}
@Override
public Class<?> returnedClass() {
return InetAddress.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return x != null ? x.equals(y) : null == y;
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names,
SessionImplementor session, Object owner)
throws HibernateException, SQLException {
Long ipLow = rs.getLong(names[0]);
if(!rs.wasNull()) {
Long ipHigh = rs.getLong(names[1]);
try {
return fromLong(new long [] {ipLow, ipHigh});
} catch (UnknownHostException e) {
throw new HibernateException("Failed to get InetAddress: ip = " + ipHigh + " + " + ipLow, e);
}
}
else
return null;
}
@Override
public Object deepCopy(Object value) throws HibernateException {
if(value != null)
try {
return InetAddress.getByAddress(((InetAddress)value).getAddress());
} catch (UnknownHostException e) {
throw new RuntimeException("Impossible Exception: " + e.getMessage(), e);
}
else
return null;
}
@Override
public boolean isMutable() {
return false;
}
...
}
请注意,我根据ipLow和ipHigh的值灵活地在Inet4Address和Inet6Address实例之间切换.复合标记为不可变,您需要检查Hibernate源代码中的文档和示例(构建复合用户类型).
以类似的方式,您可以映射有意义的位属性.您可以使用单个Restriction.eq查询这些位,引用您的EnumType.您可以使用equals方法检查属性对象.如果需要引用特殊的映射位,可以使用signupIp.ipLow中的点表示法来引用ipLow属性/列.
我猜这就是你要找的东西.
更新:
最后,它归结为定义您的属性的正确顺序. Hibernate将始终使用整数索引值来访问每个属性:
//immutable for simplicity
class Status {
private final boolean editable;
private final boolean needsReview;
private final boolean active;
//... constructor + isEditable etc..
}
在您的StatusCompositeType类中:
public String[] getPropertyNames() {
return new String [] {"editable", "needsReview", "active"};
}
public Type[] getPropertyTypes() {
return new Type [] { BooleanType.INSTANCE, LongType.INSTANCE};
}
public Object getPropertyValue(Object component, int property) throws HibernateException {
if(component != null) {
Status status = (Status)component;
switch(property) {
case 1: return status.isEditable();
case 2: return status.isReviewNeeded();
case 3: return status.isActive();
default: throw new IllegalArgumentException();
}
}
else
return null; //all columns can be set to null if you allow a entity to have a null status.
}
public void nullSafeSet(PreparedStatement st, Object value, int index,
SessionImplementor session) throws HibernateException, SQLException {
if(value != null) {
Status status = (Status)value;
st.setBoolean(index, status.isEditable());
st.setBoolean(index + 1, status.isReviewNeeded());
st.setBoolean(index + 2, status.isActive());
}
else {
st.setNull(index, BooleanType.INSTANCE.sqlType());
st.setNull(index + 1, BooleanType.INSTANCE.sqlType());
st.setNull(index + 2, BooleanType.INSTANCE.sqlType());
}
}
public Object nullSafeGet(ResultSet rs, String[] names,
SessionImplementor session, Object owner)
throws HibernateException, SQLException {
Boolean isEditable = rs.getBoolean(names[0]);
if(!rs.wasNull()) {
Boolean isReviewNeeded = rs.getBoolean(names[1]);
Boolean isActive = rs.getBoolean(names[2]);
return new Status(isEditable, isReviewNeeded, isActive);
}
else
return null;
}
剩下的就是直截了当.请记住为用户类型实现equals和hashcode,并在创建sessionFactory之前将类型添加到配置中.
完成所有操作后,您可以创建条件搜索并使用:
//search for any elements that have a status of editable, no reviewNeeded and is not active (true false false).
criteria.add(Restrictions.eq("status", new Status(true, false, false));
现在您的listEntities方法可能变为:listEntities(状态状态)或listEntities(布尔可编辑,布尔reviewNeeded,布尔isActive).
如果您需要其他信息,请检查Hibernate在其自己的源代码中提供的CompositeType和BasicType实现(查找CompositeType和BasicType的实现者).理解这些有助于使用和学习Hibernate的这种中级知识.
内容总结
以上是互联网集市为您收集整理的java – 将一些布尔属性映射为枚举在Hibernate中设置全部内容,希望文章能够帮你解决java – 将一些布尔属性映射为枚举在Hibernate中设置所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。