您可以从此处下载工作示例。
在此示例中,我们仅考虑两个实体。 复仇者联盟和反派。 我们使用联接表在两者之间建立关系。 让我们看一下此示例中使用的域映射。
package com.avengers.domain;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
/**
* The domain class representing each member of the avengers
*
* @author Dinuka.Arseculeratne
*
*/
@Entity
@Table(name = "Avengers")
public class Avenger implements Serializable {
/**
* The primary key of the Avenger table
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "avenger_id")
private Long avengerId;
/**
* The name of the avenger member
*/
@Column(name = "avenger_name")
private String avengerName;
/**
* A flag which holds whether the avenger's powers are awesome
*/
@Type(type = "yes_no")
@Column(name = "is_awesome")
private boolean isAwesome;
/**
* The list of enemies the avenger has
*/
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "AVENGERS_AND_VILLAINS", joinColumns = { @JoinColumn(name = "avenger_id") }, inverseJoinColumns = { @JoinColumn(name = "villain_id") })
private List<Villain> enemyList = new ArrayList<Villain>();
public Long getAvengerId() {
return avengerId;
}
public void setAvengerId(Long avengerId) {
this.avengerId = avengerId;
}
public String getAvengerName() {
return avengerName;
}
public void setAvengerName(String avengerName) {
this.avengerName = avengerName;
}
public boolean isAwesome() {
return isAwesome;
}
public void setAwesome(boolean isAwesome) {
this.isAwesome = isAwesome;
}
public List<Villain> getEnemyList() {
return enemyList;
}
public void addEnemy(Villain enemy) {
enemyList.add(enemy);
}
@Override
public String toString() {
return "Avenger [avengerId=" + avengerId + ", avengerName="
+ avengerName + ", isAwesome=" + isAwesome + ", enemyList="
+ enemyList + "]";
}
}
此类映射一个复仇者。 为了使这个示例尽可能简短,我使用了最少的字段。 恶棍域如下所示;
package com.avengers.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
/**
* This class represents the Villain forces against the avengers
*
* @author Dinuka.Arseculeratne
*
*/
@Entity
@Table(name = "Villains")
public class Villain implements Serializable {
/**
* The primary key of the Enemy table
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "villain_id")
private Long villaiId;
/**
* The name of the enemy
*/
@Column(name = "villain_name")
private String villainName;
/**
* A flag which checks whether the villain is super awesome
*/
@Type(type = "yes_no")
@Column(name = "is_awesome")
private boolean isAwesome;
public Long getVillaidId() {
return villaiId;
}
public void setVillaidId(Long villaidId) {
this.villaiId = villaidId;
}
public String getVillainName() {
return villainName;
}
public void setVillainName(String villainName) {
this.villainName = villainName;
}
public boolean isAwesome() {
return isAwesome;
}
public void setAwesome(boolean isAwesome) {
this.isAwesome = isAwesome;
}
@Override
public String toString() {
return "Villain [villaiId=" + villaiId + ", villainName=" + villainName
+ ", isAwesome=" + isAwesome + "]";
}
}
好的,现在我们已经定义了域,让我们看看DetachedCriteria是如何进行数据检索的。 我在这里使用DetachedCriteria是因为复仇者联盟非常具体,并表示他们不希望与Hibernate会话发生任何关系,因此,我使用了DetachedCriteria,它不需要存在休眠会话。
我们的主要目标是找回小人所属的复仇者联盟。 请注意,这假设同一个小人不能是多个超级英雄的小人。 因此,我继续在下面给出根据传递的反派名称检索复仇者的方法。
public Avenger retrieveAvengerByVillainName(String villainName) {
Avenger avenger = null;
/**
* Selected a detached criteria so we do not need a session to run it
* within.
*/
DetachedCriteria criteria = DetachedCriteria.forClass(Avenger.class);
/**
* Here we are doing an inner join with the Villain table in order to do
* a name comparison with the villainName passed in as a method
* parameter
*/
DetachedCriteria villainCriteria = criteria.createCriteria("enemyList");
villainCriteria.add(Restrictions.eq("villainName", villainName));
villainCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
@SuppressWarnings("unchecked")
List<Avenger> avengerList = getHibernateTemplate().findByCriteria(
criteria);
if (!avengerList.isEmpty()) {
avenger = avengerList.get(0);
getHibernateTemplate().initialize(avenger.getEnemyList());
}
return avenger;
}
在这种方法中,我们要做的是首先为主类创建一个条件,在本例中为Avenger.class 。 然后,我们需要与Villain表进行联接,因此,我们将使用我们在Avenger域类中定义的列表名称,从主要条件中创建一个子条件。
那么就需要使反派域名的属性与传入的反派名称相等。
Criteria API的强大功能使您可以轻松创建动态查询,如果我们要使用纯HQL,这将很麻烦,而纯HQL需要大量的字符串连接才能实现。
提供了一个名为AvengerTest.java的示例测试类,其附件位于最顶部。 请注意,您需要删除avenger-context.xml上的注释,以便创建此示例所需的表。
就是这样。
复仇者联盟现在可以避免冒险,因为他们拥有一个系统,可以将任何超级反派与联盟中的超级英雄联系起来。
一如既往地欢迎和赞赏您的意见和建议。
感谢您抽出宝贵的时间阅读!!!!
参考:“ 通过示例进行休眠–第2部分(DetachedCriteria)”,来自我们的JCG合作伙伴 Dinuka Arseculeratne,在“ 我的旅程” IT博客中
翻译自: https://www.javacodegeeks.com/2011/11/hibernate-by-example-part-2.html