many-to-many
多对多关系映射,老师举得例子是用户和角色。
一个用户可以有多种角色
一个角色可以分配给多个用户
单从一边看,都是一对多的关系,但是放在一起就是多对多了.看代码吧。
单向关系:user一方持有Role一方的引用
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>
特别的地方就在这里了,table="t_user_role"会生成一个中间表,表中的字段为<set></set>
标签中配置的字段。
<keycolumn="user_id"/>:来自自己对象内部的属性
<many-to-manyclass="com.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标签的写法和单向时一样,table="t_user_role"注意要一致,还有key和many-to-many的column,别写错就行了。
还有一点关于结果的排序,如果配置了,那么hibernate会为我们排序,升序默认或esc,降序desc
<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中加入orderbyXXXdesc
保存不会有任何改变,只是先保存谁都无所谓了,
查询
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(); } } } } }