Hibernate(四)——多对一单向关联映射


     Hibernate对于数据库的操作,全部利用面向对象的思维来理解和实现的。一般的单独表的映射,相信大家都没有问题,但是对于一些表之间的特殊关系,Hibernate提供了一些独特的方式去简化它。


      今天就来说说多对一的关联映射。


      数据库中有多对一的关系,Hibernate自然也有对象的多对一的关联关系。比如用户和用户组,一个用户只属于一个组,一个组有多名用户。我们就可以说用户和用户组的关系就是多对一的关系。用对象的uml图表示一下:



      在Hibernate中如何来实现呢?首先定义这两个实体类:

  1. package com.bjpowernode.hibernate;  
  2.   
  3. /** 
  4.  * 用户组 
  5.  * @author Longxuan 
  6.  * 
  7.  */  
  8. public class Group {  
  9.   
  10.     private int id;  
  11.     private String name;  
  12.     public int getId() {  
  13.         return id;  
  14.     }  
  15.     public void setId(int id) {  
  16.         this.id = id;  
  17.     }  
  18.     public String getName() {  
  19.         return name;  
  20.     }  
  21.     public void setName(String name) {  
  22.         this.name = name;  
  23.     }  
  24. }  
  25.   
  26.   
  27.   
  28. package com.bjpowernode.hibernate;  
  29.   
  30. /** 
  31.  * 用户类 
  32.  * @author Longxuan 
  33.  * 
  34.  */  
  35. public class User {  
  36.       
  37.     private int  id;  
  38.       
  39.     private String name;  
  40.   
  41.     private Group group;  
  42.       
  43.     public Group getGroup() {  
  44.         return group;  
  45.     }  
  46.   
  47.     public void setGroup(Group group) {  
  48.         this.group = group;  
  49.     }  
  50.   
  51.     public int getId() {  
  52.         return id;  
  53.     }  
  54.       
  55.     public void setId(int id) {  
  56.         this.id = id;  
  57.     }  
  58.   
  59.     public String getName() {  
  60.         return name;  
  61.     }  
  62.   
  63.     public void setName(String name) {  
  64.         this.name = name;  
  65.     }  
  66.   
  67. }  
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配置文件:

  1. <!DOCTYPE hibernate-configuration PUBLIC  
  2.     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
  3.     "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
  4.   
  5. <hibernate-configuration>  
  6.     <session-factory name="foo">    
  7.           
  8.         <property name="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</property>  
  9.         <property name="hibernate.show_sql">true</property><!-- 设置是否显示生成sql语句 -->  
  10.         <property name="hibernate.format_sql">false</property><!-- 设置是否格式化sql语句-->  
  11.           
  12.         <mapping resource="com/bjpowernode/hibernate/Tables.hbm.xml" />  
  13.     </session-factory>  
  14. </hibernate-configuration>  
<!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配置文件:

  1. ## MySQL  
  2.   
  3. hibernate.dialect org.hibernate.dialect.MySQLDialect  
  4. #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect  
  5. #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect  
  6. hibernate.connection.driver_class com.mysql.jdbc.Driver  
  7. hibernate.connection.url jdbc:mysql://localhost:3306/hibernate_many2one  
  8. hibernate.connection.username root  
  9. hibernate.connection.password root  
## 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会自动添加上所引用的数据。


      给出映射文件:

  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC   
  3.     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  5. <hibernate-mapping>  
  6.       
  7.     <class name="com.bjpowernode.hibernate.User" table="t_user">  
  8.         <id name="id">  
  9.             <generator class="native" />  
  10.         </id>  
  11.         <property name="name"></property>  
  12.         <many-to-one name="group" column="groupid" cascade="save-update"></many-to-one>  
  13.     </class>  
  14.           
  15.     <class name="com.bjpowernode.hibernate.Group" table="t_group">  
  16.         <id name="id">  
  17.             <generator class="native" />  
  18.         </id>  
  19.         <property name="name"></property>  
  20.     </class>  
  21.       
  22. </hibernate-mapping>  
<?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:

  1. package com.bjpowernode.hibernate;  
  2.   
  3. import junit.framework.TestCase;  
  4.   
  5. import org.hibernate.Session;  
  6.   
  7. public class Many2OneTest extends TestCase {  
  8.   
  9.         /** 
  10.          * 测试添加用户 
  11.          */  
  12.         public void testSave3(){  
  13.         Session session = null;  
  14.         try{  
  15.             session = HibernateUtils.getSession();  
  16.             session.beginTransaction();  
  17.               
  18.             Group group = new Group();  
  19.             group.setName("提高班");  
  20.               
  21.             User user1 = new User();  
  22.             user1.setName("张三");  
  23.             user1.setGroup(group);  
  24.               
  25.             User user2 = new User();  
  26.             user2.setName("李四");  
  27.             user2.setGroup(group);  
  28.               
  29.             //普通方法 :必须先保存group,再保存user  
  30.             //配置了many-to-one 则不用再手动save group了。  
  31.             //session.save(group);  
  32.             session.save(user1);  
  33.             session.save(user2);  
  34.               
  35.             session.getTransaction().commit();  
  36.         }catch(Exception e){  
  37.             e.printStackTrace();  
  38.             session.getTransaction().rollback();  
  39.         }finally{  
  40.             HibernateUtils.closeSession(session);  
  41.         }  
  42.     }  
  43.       
  44. }  
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的魅力所在。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hibernate是一个Java持久化框架,它能够将Java对象映射到数据库中的表格,同时支持各种关系数据库,如MySQL、Oracle等。在Hibernate中,对于一对一、一对多和多对多的关系,我们可以通过以下方式进行映射。 一对一关系:在Hibernate中,可以通过主键关联和外键关联来实现一对一关系的映射。主键关联是指两个实体之间的关联通过主键来进行,可以使用@PrimaryKeyJoinColumn注解将两个实体关联起来。外键关联是指通过一个实体引用另一个实体的主键作为外键,使用@JoinColumn注解来指定外键属性。 一对多关系:在Hibernate中,一对多关系通常通过外键关联来实现。在一的一方,使用@OneToMany注解来定义一对多关系,同时使用@JoinColumn注解指定外键属性。在多的一方,使用@ManyToOne注解来定义多对一关系,并使用@JoinColumn注解指定外键属性。 多对多关系:在Hibernate中,多对多关系通常通过中间表来实现。在多对多的两个实体中,使用@ManyToMany注解来定义多对多关系。同时,需要在中间表中创建两个外键,分别与两个实体的主键关联,并使用@JoinTable注解来指定中间表的表名和两个外键的列名。 总结:通过Hibernate的注解方式,可以方便地实现一对一、一对多和多对多关系的映射。通过合理地使用注解,可以减少编写映射文件的工作量,提高开发效率。同时,Hibernate还提供了在运行时自动生成表结构的功能,可以根据Java实体类来动态创建或更新对应的数据库表格,从而提高系统的可维护性和灵活性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值