1. 程式人生 > >(10)hibernate中ManyToMany

(10)hibernate中ManyToMany

1.通過在兩個類中分別設定set完成MnayToMany: 

public class Admin {
	private int id;
	private String name;
	private Set<Role> roles;
	public Admin() {
		roles=new HashSet<>();
	}
	public void add(Role role) {
		roles.add(role);
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set<Role> getRoles() {
		return roles;
	}
	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}
	
	
}
public class Role {
private int id;
private String name;
private Set<Admin> admins;

public Role() {
	admins=new HashSet<>();
}
public void add(Admin admin) {
	admins.add(admin);
}
public int getId() {
	return id;
}
public void setId(int id) {
	this.id = id;
}
public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
public Set<Admin> getAdmins() {
	return admins;
}
public void setAdmins(Set<Admin> admins) {
	this.admins = admins;
}


}
<hibernate-mapping>
    <class name="model.Admin" table="ADMIN">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <set name="roles" table="ROLE_ADMIN" lazy="extra">
            <key>
                <column name="A_ID" />
            </key>
            <many-to-many class="model.Role" column="R_ID"/>
        </set>
    </class>
</hibernate-mapping>

注意:(1).在admin中manytomany意思是admins to roles,class寫的是後者對應的類,column是後者對應的外來鍵id

<hibernate-mapping>
    <class name="model.Role" table="ROLE">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <set name="admins" table="ROLE_ADMIN" lazy="extra">
            <key>
                <column name="R_ID" />
            </key>
            <many-to-many class="model.Admin" column="A_ID"/>
        </set>
    </class>
</hibernate-mapping>

test01:

@Test
	void test1() {
		Session s=null;
		try {
			s=HibernateUtil.getSession();
			s.beginTransaction();
			Admin a1=new Admin();
			a1.setName("a1");
		    s.save(a1);
				
		    Admin a2=new Admin();
			a2.setName("a2");
		    s.save(a2);
		    
		    Role r1=new Role();
		    r1.setName("小明");
		    r1.add(a1);
		    r1.add(a2);
		    s.save(r1);
		    
		    Role r2=new Role();
		    r2.setName("小王");
		    r2.add(a1);
		    r2.add(a2);
		    s.save(r2);
		    
			s.getTransaction().commit();
		} catch (Exception e) {
			// TODO 自動生成的 catch 塊
			e.printStackTrace();
			s.getTransaction().rollback();
		}finally {
			HibernateUtil.closeSession(s);
		}
		
	}

test02:

@Test
	void test2() {
		Session s=null;
		try {
			s=HibernateUtil.getSession();
			s.beginTransaction();
			Admin a=s.load(Admin.class, 1);
			System.out.println(a.getName());
			for(Role r:a.getRoles()) {
				System.out.println(r.getName());
			}
			
			s.getTransaction().commit();
		} catch (Exception e) {
			// TODO 自動生成的 catch 塊
			e.printStackTrace();
			s.getTransaction().rollback();
		}finally {
			HibernateUtil.closeSession(s);
		}
		
	}

最佳實踐:使用manytomany,無論在哪一端維護關係都較為麻煩,並且有時關聯表需要加入其它屬性,所以在開發過程中,經常把manytomany改為2個onetomany,即3張表,如下:

public class Teacher {
	private int id;
	private String name;
	private Set<TeacherCourse> tcs;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set<TeacherCourse> getTcs() {
		return tcs;
	}
	public void setTcs(Set<TeacherCourse> tcs) {
		this.tcs = tcs;
	}
	
}
public class Course {
private int id;
private String name;
private Set<TeacherCourse> tcs;
public int getId() {
	return id;
}
public void setId(int id) {
	this.id = id;
}
public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
public Set<TeacherCourse> getTcs() {
	return tcs;
}
public void setTcs(Set<TeacherCourse> tcs) {
	this.tcs = tcs;
}


}
public class TeacherCourse {
private int id;
private double ach;
private Teacher teacher;
private Course course;
public int getId() {
	return id;
}
public void setId(int id) {
	this.id = id;
}
public double getAch() {
	return ach;
}
public void setAch(double ach) {
	this.ach = ach;
}
public Teacher getTeacher() {
	return teacher;
}
public void setTeacher(Teacher teacher) {
	this.teacher = teacher;
}
public Course getCourse() {
	return course;
}
public void setCourse(Course course) {
	this.course = course;
}

}
<hibernate-mapping>
    <class name="model.Teacher" table="TEACHER">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <set name="tcs" table="TEACHERCOURSE" inverse="true" lazy="extra">
            <key>
                <column name="T_ID" />
            </key>
            <one-to-many class="model.TeacherCourse" />
        </set>
    </class>
</hibernate-mapping>
<hibernate-mapping>
    <class name="model.Course" table="COURSE">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <set name="tcs" table="TEACHERCOURSE"  lazy="extra" inverse="true">
            <key>
                <column name="C_ID" />
            </key>
            <one-to-many class="model.TeacherCourse" />
        </set>
    </class>
</hibernate-mapping>
<hibernate-mapping>
    <class name="model.TeacherCourse" table="TEACHERCOURSE">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="ach" type="double">
            <column name="ACH" />
        </property>
        <many-to-one name="teacher" class="model.Teacher">
            <column name="T_ID" />
        </many-to-one>
        <many-to-one name="course" class="model.Course">
            <column name="C_ID" />
        </many-to-one>
    </class>
</hibernate-mapping>

test03:

@Test
	void test3() {
		Session s=null;
		try {
			s=HibernateUtil.getSession();
			s.beginTransaction();
			Teacher t1=new Teacher();
			t1.setName("小明老師");
			s.save(t1);
			
			Teacher t2=new Teacher();
			t2.setName("小紅老師");
			s.save(t2);
			
			Course c1=new Course();
			c1.setName("資料結構");
			s.save(c1);
			
			Course c2=new Course();
			c2.setName("計算機組成原理");
			s.save(c2);
			
			TeacherCourse tc1=new TeacherCourse();
			tc1.setAch(88);
			tc1.setCourse(c1);
			tc1.setTeacher(t1);
			s.save(tc1);
			
			tc1=new TeacherCourse();
			tc1.setAch(99);
			tc1.setCourse(c2);
			tc1.setTeacher(t1);
			s.save(tc1);
			
			tc1=new TeacherCourse();
			tc1.setAch(90);
			tc1.setCourse(c2);
			tc1.setTeacher(t2);
			s.save(tc1);
			
			tc1=new TeacherCourse();
			tc1.setAch(90);
			tc1.setCourse(c1);
			tc1.setTeacher(t2);
			s.save(tc1);
			
			s.getTransaction().commit();
		} catch (Exception e) {
			// TODO 自動生成的 catch 塊
			e.printStackTrace();
			s.getTransaction().rollback();
		}finally {
			HibernateUtil.closeSession(s);
		}
		
	}

test04:

void test4() {
		Session s=null;
		try {
			s=HibernateUtil.getSession();
			s.beginTransaction();
			Teacher t1=s.load(Teacher.class, 1);
			System.out.println(t1.getName()+":");
			for(TeacherCourse tc:t1.getTcs()) {
				System.out.println(tc.getCourse().getName()+":"+tc.getAch());
			}
			s.getTransaction().commit();
		} catch (Exception e) {
			// TODO 自動生成的 catch 塊
			e.printStackTrace();
			s.getTransaction().rollback();
		}finally {
			HibernateUtil.closeSession(s);
		}
		
	}