Hibernate中多对多关系映射、保存、查询

首先是一些基础模型类的建立:

 

import java.io.Serializable;

public abstract class BaseObject implements Serializable {

	/**  */
	private static final long serialVersionUID = -7443978018690354629L;

	@Override
	public abstract String toString();

	@Override
	public abstract boolean equals(Object o);

	@Override
	public abstract int hashCode();

}
 
public abstract class DefaultIdGeneral extends BaseObject {

	/**  */
	private static final long serialVersionUID = -7483768110342207606L;

	// ID
	protected Long id;

	// 版本号,用于Hibernate乐观锁
	protected Integer version;

	/**
	 * 
	 * hibernate.id column="id" generator-class="native"
	 * 
	 * @return Returns the id.
	 */
	public abstract Long getId();

	/**
	 * @param id
	 *            The id to set.
	 */
	public abstract void setId(Long id);

	/**
	 * 
	 * @hibernate.version
	 * 
	 * @return Returns the version.
	 */
	public Integer getVersion() {
		return version;
	}

	/**
	 * @param version
	 *            The version to set.
	 */
	public void setVersion(Integer version) {
		this.version = version;
	}
}
 

1、多对多关系映射(房间表与设备进行多对多关系映射),两者之间的关系映射时必需有一端的inverse=true,另一端为false,不能两端的inverse都为true。不然在保存或删除两者间的关系时不会对中间表进行操作。

    1)房间表

import java.util.Set;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/**
 * title: 建筑中的房间
 * 
 * @author Administrator
 * @时间 2009-9-22:下午03:41:43
 * @hibernate.class table="fc_roombasic" dynamic-update="true"
 *                  dynamic-insert="true"
 */
public class MapRoom extends DefaultIdGeneral {

	/**  */
	private static final long serialVersionUID = -3216302518592517083L;

	/** 房间名称 room_name */
	private String name;

	/** 房间内设备 */
	private Set<Equipment> equipments;

	/**
	 * @hibernate.id column="room_id" generator-class="native"
	 * 
	 */
	@Override
	public Long getId() {
		return id;
	}

	@Override
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * @hibernate.property column="room_name"
	 * 
	 */
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @hibernate.set table="fc_room_equipment" lazy="true" cascade="all"
	 *                inverse="true"
	 * @hibernate.collection-many-to-many column="equipment_id"
	 *                                    class="com.yinhoo.map.model.Equipment"
	 * @hibernate.collection-key column="room_id"
	 * @return
	 */
	public Set<Equipment> getEquipments() {
		return equipments;
	}

	public void setEquipments(Set<Equipment> equipments) {
		this.equipments = equipments;
	}

	@Override
	public boolean equals(final Object other) {
          ...
	}

	@Override
	public int hashCode() {
          ....
	}

	@Override
	public String toString() {
          .........
	}

}

 2)设备

import java.util.Set;

/**
 * title: 设备信息
 * 
 * @author Administrator
 * @时间 2009-9-22:下午09:49:32
 * @hibernate.class table="fc_equip" dynamic-update="true" dynamic-insert="true"
 */
public class Equipment extends DefaultIdGeneral {

	/** 设备名称 */
	private String name;

	/** 使用房间(对应roombasic表room_id) */
	private Set<MapRoom> rooms;

	/**
	 * @hibernate.id column="equip_id" generator-class="native"
	 * 
	 */
	@Override
	public Long getId() {
		return id;
	}

	@Override
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * @hibernate.property column="equip_name"
	 * 
	 */
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	/**
	 * @hibernate.set table="fc_room_equipment" lazy="true" cascade="all"
	 *                inverse="false"
	 * @hibernate.collection-many-to-many column="room_id"
	 *                                    class="com.yinhoo.map.model.MapRoom"
	 * @hibernate.collection-key column="equipment_id"
	 * @return
	 */
	public Set<MapRoom> getRooms() {
		return rooms;
	}

	public void setRooms(Set<MapRoom> rooms) {
		this.rooms = rooms;
	}

}

2、多对多之间的查询。

public int getMapRoomTotalRecord(Equipment equipment) {
		String sql = "select count(room.id) from MapRoom as room where room.equipments.id="
				+ equipment.getId() + " ";
		// System.out.println(sql);
		return ((Long) getSession().createQuery(sql).uniqueResult())
				.intValue();
	}
 
String sql = "select count(room.id) from MapRoom as room join room.equipments as equip where equip.id="
				+ equipment.getId() + " ";
 
public int getMapRoomTotalRecord(Equipment equipment) {
		String sql = "select count(room.id) from MapRoom as room join room.equipments as equip where equip= :equipment";
		// System.out.println(sql);
		return ((Long) getSession().createQuery(sql).setParameter("equipment",
				equipment).uniqueResult()).intValue();
	}

  查询结果集:

public List<MapRoom> getMapRooms(Equipment equipment,
			int first, int max) {
		String sql = "select room from MapRoom as room join room.equipments as equip where equip= :equipment ";
		return getSession().createQuery(sql).setParameter("equipment",
				equipment).setFirstResult(first).setMaxResults(max).list();
	}
 

 

下面是参照http://www.blogjava.net/fuhoujun/archive/2009/01/06/232230.html


一个老师教许多学生,一个学生被许多老师教,一个学生有好多书,同一种书被许多同学拥有.
要查询教拥有书"a"的学生的老师!

Hql语句:

SELECT t FROM Teacher t join t.students s join s.books b where b.name = 'a' 
 

 

解释:t.students s中s并不是集合的意思,而是t的students对象的表别名,join t.students s这个hql,hibernate会翻译成两个表的内连接关系

错误写法:

SELECT t FROM teacher t where t.students.books.name = 'a' 
 

 

其实道理是很显然的,t.students是一个Set,那么这个Set怎么可能有books这样的属性呢?同理books.name也不对,所以 使用表间连接并给出别名t.students s,此时的对象s才有books属性,所以可以写s.books b,最后使用b.name限制查询b.name = 'a'. 

另外一种写法:

SELECT t FROM Teacher t,Student s,Book b where s.id in elements(t.students) and b.id in elements(s.books) 
 


这种方法没有出错!不过这种方式要用子查询!

你可能感兴趣的:(apache,sql,Hibernate,.net)