hibernate 3.2(9)多対多相関マッピング
6681 ワード
原作者:http://www.verydemo.com/demo_c 146_i 2174.
ユーザーとキャラクターはマルチペアの関係に属しています。1人のユーザは複数のキャラクターを持ち、1つのキャラクターは複数のユーザに属してもいいです。
User.hbm.xml:
Role.hbm.xml:
ヒベルナ:insert into t_User(username)values(?)Hbernate:insert into t_Role(rolename)values(?)Hbernate:insert into t_Role(rolename)values(?)Hbernate:insert into t_User_Role(userid,roleid)values(?,?)Hbernate:insert into t_User_Role(userid,roleid)values(?、?)
ペアのマルチロードをテストして、user側から保存します。
印刷出力:
…………
双方向多対多相関マッピングは一方向の基本と一致しています。二重送信でsetセットを入れて関連関係を保存していますが、格納フィールドの場合は、一方を指定して追加したほうがいいです。両方とも記憶が混乱しやすくなります。一方のマッピングファイルのsetタグにinverse="true"を入れて制御権を他の方に処理してください。【inverse属性は一対の多双方向関連、多対多双方向関連にのみ適用可能】
Role.javaを変更:
inserse="true"を追加すると、Roleからデータを預け入れることはできません。上記のテスト方法でデータを保存します。中間表はデータを預け入れることはできませんが、inserseを削除すればいいです。エラーを防ぐために、やはりinverseを指定側から制御して追加したほうがいいです。
ユーザーとキャラクターはマルチペアの関係に属しています。1人のユーザは複数のキャラクターを持ち、1つのキャラクターは複数のユーザに属してもいいです。
public class User {
private int userid;
private String username;
private Set roles;
getter and setter..
}
public class Role {
private int roleid;
private String rolename;
getter & setter
}
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 package="com.wyx.hibernate">
<class name="User" table="t_User">
<id name="userid">
<generator class="native"/>
</id>
<property name="username"/>
<set name="roles" table="t_User_Role" cascade="all">
<key column="userid" />
<many-to-many class="Role" column="roleid"/>
</set>
</class>
</hibernate-mapping>
セットラベルのnameはuserの関連フィールドを指し、setは中間テーブルを表し、テーブルの名前をtableで指定し、keyのcolumn属性を外キーとしてuserテーブルのuserid、many-to-mangのcolumnを外キーとしてroleテーブルのroidを指し、複合マスターキーを構成しています。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.wyx.hibernate">
<class name="Role" table="t_Role">
<id name="roleid">
<generator class="native"/>
</id>
<property name="rolename"/>
</class>
</hibernate-mapping>
ペアの多さをテストして、user側から保存します。public void testSave(){
Session session = HibernateUtils.getSession();
try {
session.beginTransaction();
Role role1 = new Role();
role1.setRolename(" ");
//session.save(role1);
Role role2 = new Role();
role2.setRolename(" ");
//session.save(role2);
Set roles = new HashSet<Role>();
roles.add(role1);
roles.add(role2);
User user =new User();
user.setUsername(" ");
user.setRoles(roles);
session.save(user);
session.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
印刷出力:ヒベルナ:insert into t_User(username)values(?)Hbernate:insert into t_Role(rolename)values(?)Hbernate:insert into t_Role(rolename)values(?)Hbernate:insert into t_User_Role(userid,roleid)values(?,?)Hbernate:insert into t_User_Role(userid,roleid)values(?、?)
ペアのマルチロードをテストして、user側から保存します。
public void testLoad(){
Session session = HibernateUtils.getSession();
try {
session.beginTransaction();
User user = (User)session.load(User.class, 1);
Set<Role> roles = user.getRoles();
System.out.println("user.username = " + user.getUsername());
for(Iterator<Role> iter = roles.iterator(); iter.hasNext();){
Role role = iter.next();
System.out.println("user.role.rolename = " + role.getRolename());
}
session.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
印刷出力:
…………
双方向多対多相関マッピングは一方向の基本と一致しています。二重送信でsetセットを入れて関連関係を保存していますが、格納フィールドの場合は、一方を指定して追加したほうがいいです。両方とも記憶が混乱しやすくなります。一方のマッピングファイルのsetタグにinverse="true"を入れて制御権を他の方に処理してください。【inverse属性は一対の多双方向関連、多対多双方向関連にのみ適用可能】
Role.javaを変更:
package com.wyx.hibernate;
import java.util.Set;
public class Role {
private int roleid;
private String rolename;
private Set users;
getter & setter...
}
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.wyx.hibernate">
<class name="Role" table="t_Role">
<id name="roleid">
<generator class="native"/>
</id>
<property name="rolename"/>
<set name="users" table="t_User_Role" inverse="true" cascade="all" order-by="userid">
<key column="roleid"/>
<many-to-many class="User" column="userid"/>
</set>
</class>
</hibernate-mapping>
/**
* save role casecad user
*/
public void testSave(){
Session session = HibernateUtils.getSession();
try {
session.beginTransaction();
User user1 =new User();
user1.setUsername(" ");
User user2 =new User();
user2.setUsername(" ");
Set users = new HashSet<User>();
users.add(user1);
users.add(user2);
Role role = new Role();
role.setRolename(" ");
role.setUsers(users);
session.save(role);
session.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
inserse="true"を追加すると、Roleからデータを預け入れることはできません。上記のテスト方法でデータを保存します。中間表はデータを預け入れることはできませんが、inserseを削除すればいいです。エラーを防ぐために、やはりinverseを指定側から制御して追加したほうがいいです。