对于的操作,全部利用面向对象的思维来理解和实现的。一般的单独表的映射,相信大家都没有问题,但是对于一些表之间的特殊关系,Hibernate提供了一些独特的方式去简化它。
今天就来说说多对一的关联映射。
数据库中有多对一的关系,Hibernate自然也有对象的多对一的关联关系。比如用户和用户组,一个用户只属于一个组,一个组有多名用户。我们就可以说用户和用户组的关系就是多对一的关系。用对象的uml图表示一下:
在Hibernate中如何来实现呢?首先定义这两个实体类:
- package com.bjpowernode.hibernate;
- /**
- * 用户组
- * @author Longxuan
- *
- */
- public class Group {
- private int id;
- private String name;
- 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;
- }
- }
- package com.bjpowernode.hibernate;
- /**
- * 用户类
- * @author Longxuan
- *
- */
- public class User {
- private int id;
- private String name;
- private Group group;
- public Group getGroup() {
- return group;
- }
- public void setGroup(Group group) {
- this.group = group;
- }
- 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;
- }
- }
hibernate.cfg.xml配置文件:
- <!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
- <hibernate-configuration>
- <session-factory name="foo">
- <property name="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</property>
- <property name="hibernate.show_sql">true</property><!-- 设置是否显示生成sql语句 -->
- <property name="hibernate.format_sql">false</property><!-- 设置是否格式化sql语句-->
- <mapping resource="com/bjpowernode/hibernate/Tables.hbm.xml" />
- </session-factory>
- </hibernate-configuration>
hibernate.properties配置文件:
- ## MySQL
- hibernate.dialect org.hibernate.dialect.MySQLDialect
- #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
- #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
- hibernate.connection.driver_class com.mysql.jdbc.Driver
- hibernate.connection.url jdbc:mysql://localhost:3306/hibernate_many2one
- hibernate.connection.username root
- hibernate.connection.password root
我们当然可以按一般的方法来做。添加的时候,先手动添加组,再添加用户。删除时,先删除所有的用户,再删除用户组。但是Hibernate为我们提供了一种便捷的方式——many-to-one。在映射文件hbm.xml中配置后,就可以不用再想那些限制了。Hibernate会自动添加上所引用的数据。
给出映射文件:
- <?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.bjpowernode.hibernate.User" table="t_user">
- <id name="id">
- <generator class="native" />
- </id>
- <property name="name"></property>
- <many-to-one name="group" column="groupid" cascade="save-update"></many-to-one>
- </class>
- <class name="com.bjpowernode.hibernate.Group" table="t_group">
- <id name="id">
- <generator class="native" />
- </id>
- <property name="name"></property>
- </class>
- </hibernate-mapping>
配置了many-to-one会自动在t_user表中创建外键groupid,与t_group的id映射。
many-to-one标签用到了cascade,指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作。其属性值如下:
- all:在所有的情况下都执行级联操作;
- none:在所有情况下都不执行级联操作;
- save-update:在保存和更新的时候执行级联操作;、
- delete:在删除的时候执行级联操作。
类Many2OneTest:
- package com.bjpowernode.hibernate;
- import junit.framework.TestCase;
- import org.hibernate.Session;
- public class Many2OneTest extends TestCase {
- /**
- * 测试添加用户
- */
- public void testSave3(){
- Session session = null;
- try{
- session = HibernateUtils.getSession();
- session.beginTransaction();
- Group group = new Group();
- group.setName("提高班");
- User user1 = new User();
- user1.setName("张三");
- user1.setGroup(group);
- User user2 = new User();
- user2.setName("李四");
- user2.setGroup(group);
- //普通方法 :必须先保存group,再保存user
- //配置了many-to-one 则不用再手动save group了。
- //session.save(group);
- session.save(user1);
- session.save(user2);
- session.getTransaction().commit();
- }catch(Exception e){
- e.printStackTrace();
- session.getTransaction().rollback();
- }finally{
- HibernateUtils.closeSession(session);
- }
- }
- }
结果图:
执行测试前: , 执行测试后:
用many-to-one进行配置后,hibernate会自动去添加外键,而我们做的任何操作都不需要去考虑它的结构,也不用手动去维护这个关系,关系由Hibernate自动维护。这就是Hibernate的魅力所在。