many-to-many
多対多関係マッピングで、先生が挙げた例はユーザーとキャラクターです。一つのユーザーが複数のキャラクターを持ってもいいです。一つのキャラクターは複数のユーザーに割り当てられます。一方から見れば、一つのペアが多い関係ですが、一緒に置くと多すぎます。コードを見ましょう。一方向関係:アメリカ側はRole側の引用を持っています。
Role.java です。
タブで設定されているフィールドです。
<key column=「useruuid」/>:自分のオブジェクトの内部からの属性
<many-to-many class=「comp.ahuzl.hibernate.Role」column=「role id」/>:他の対象からの属性なので、対象の類名をはっきり書く必要があります。
保存
変更されたところは大きくないです。Role.javaにのみUserの引用を入れました。またRole.hbm.xmlにUserの属性を入れました。
Role.javaもう一つのポイントは結果の並べ替えです。もし配置されたら、hibernateは私達のために並べ替えられます。昇順はデフォルトかesc、降順descです。
保存は何も変わりません。ただ、先に保存してもいいです。
クエリー
Role.java
package com.ahuzl.hibernate;
public class Role {
private int id;
private String name;
。。。 get set
}
Role.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.ahuzl.hibernate">
<class name="Role" table="t_role">
<id name="id" column="role_id">
<generator class="native"/>
</id>
<property name="name" column="role_name"/>
</class>
</hibernate-mapping>
User.java
package com.ahuzl.hibernate;
import java.util.Set;
public class User {
private int id;
private String name;
private Set role;
。。。 get set
}
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.ahuzl.hibernate.User" table="t_user" >
<id name="id" column="user_id">
<generator class="native"/>
</id>
<property name="name" column="user_name"/>
<set name="role" table="t_user_role">
<key column="user_id"/>
<many-to-many class="com.ahuzl.hibernate.Role" column="role_id"/>
</set>
</class>
</hibernate-mapping>
特別なところはここです。テーブルの中のフィールドはタブで設定されているフィールドです。
<key column=「useruuid」/>:自分のオブジェクトの内部からの属性
<many-to-many class=「comp.ahuzl.hibernate.Role」column=「role id」/>:他の対象からの属性なので、対象の類名をはっきり書く必要があります。
保存
public class Many2ManyTest extends TestCase {
public void testSave(){
Session session = null;
try{
session = HibernateUtils.getSession();
session.beginTransaction();
// , ,reader,manager
Role role1 = new Role();
role1.setName(" ");
session.save(role1);
Role role2 = new Role();
role2.setName("リーダー");
session.save(role2);
Role role3 = new Role();
role3.setName("マネージャ");
session.save(role3);
User user1 = new User();
user1.setName(" ");
Set roleOfUser1 = new HashSet();
roleOfUser1.add(role1);
user1.setRole(roleOfUser1);
session.save(user1);
// ,
User user2 = new User();
user2.setName(" ");
Set roleOfUser2 = new HashSet();
roleOfUser2.add(role1);
roleOfUser2.add(role2);
user2.setRole(roleOfUser2);
session.save(user2);
User user3 = new User();
user3.setName(" ");
Set roleOfUser3 = new HashSet();
roleOfUser3.add(role3);
user3.setRole(roleOfUser3);
session.save(user3);
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
if (session != null){
if (session.isOpen()){
session.close();
}
}
}
}
}
クエリー
public void testLoad(){
Session session = null;
try{
session = HibernateUtils.getSession();
session.beginTransaction();
User user = (User)session.get(User.class, 2);
System.out.println("userId : " + user.getId());
System.out.println("userName : " + user.getName());
// id 2
Set roleOfUser = user.getRole();
Iterator it = roleOfUser.iterator();
while(it.hasNext()){
Role role = (Role)it.next();
System.out.println("user's Role : " + role.getName());
}
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
if (session != null){
if (session.isOpen()){
session.close();
}
}
}
}
双方向は、それぞれ相手の引用を持っています。変更されたところは大きくないです。Role.javaにのみUserの引用を入れました。またRole.hbm.xmlにUserの属性を入れました。
Role.java
package com.ahuzl.hibernate;
import java.util.Set;
public class Role {
private int id;
private String name;
private Set user;
... get set
}
Role.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.ahuzl.hibernate">
<class name="Role" table="t_role">
<id name="id" column="role_id">
<generator class="native"/>
</id>
<property name="name" column="role_name"/>
<set name="user" table="t_user_role">
<key column="role_id"></key>
<many-to-many class="User" column="user_id"/>
</set>
</class>
</hibernate-mapping>
ここ
<set name="user" table="t_user_role" order-by="user_id desc">
<key column="role_id"/>
<many-to-many class="User" column="user_id"/>
</set>
上の配置のように、hibernateはSQLにorder by XXX descを追加します。保存は何も変わりません。ただ、先に保存してもいいです。
クエリー
public class Many2ManyTest extends TestCase {
public void testLoad2(){
Session session = null;
try{
session = HibernateUtils.getSession();
session.beginTransaction();
Role role = (Role)session.load(Role.class, 1);
System.out.println("roleId : " + role.getId());
System.out.println("roleName : " + role.getName());
// id 1
Set roleOfUser = role.getUser();
Iterator it = roleOfUser.iterator();
while(it.hasNext()){
User user = (User)it.next();
System.out.println("userID : " + user.getId());
System.out.println("userName: " + user.getName());
}
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
if (session != null){
if (session.isOpen()){
session.close();
}
}
}
}
}