`
paladin1988
  • 浏览: 330015 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hibernate基于连接表的一对多单向关联

 
阅读更多

基于连接表,顾名思义就是需要建立中间表来保存两个表的关联关系。与基于外键的一对多关联关系不同的是多了一个保存外键关系的关联表,通过关联表维护两个实体之间的关系。


同时,既然是一对多,一端的Set集合肯定也是少不了的,那么在一端的hbm中,肯定也会有<set>标签出现。

 

一个Person有多个地址,建立3表,连接表jointable保存2个实体表的主键,jointable维护实体表的关联关系。
Person.java实体类中使用集合Set,保存多端的关系,并在Person.hbm.xml文件中配置关联关系。

 

 

 

创建数据库脚本如下:(参看附件)

 

-- MySQL dump 10.13  Distrib 5.1.55, for Win32 (ia32)
--
-- Host: localhost    Database: hibernate_demo
-- ------------------------------------------------------
-- Server version	5.1.55-community

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `address`
--

DROP TABLE IF EXISTS `address`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `address` (
  `addressId` int(11) NOT NULL AUTO_INCREMENT,
  `item` varchar(30) NOT NULL,
  PRIMARY KEY (`addressId`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `address`
--

LOCK TABLES `address` WRITE;
/*!40000 ALTER TABLE `address` DISABLE KEYS */;
INSERT INTO `address` VALUES (1,'address_no2'),(2,'address_no1');
/*!40000 ALTER TABLE `address` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `person`
--

DROP TABLE IF EXISTS `person`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `person` (
  `personid` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) NOT NULL,
  `sex` varchar(10) NOT NULL,
  PRIMARY KEY (`personid`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `person`
--

LOCK TABLES `person` WRITE;
/*!40000 ALTER TABLE `person` DISABLE KEYS */;
INSERT INTO `person` VALUES (1,10,'M');
/*!40000 ALTER TABLE `person` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `personadd`
--

DROP TABLE IF EXISTS `personadd`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `personadd` (
  `pid` int(11) NOT NULL,
  `aid` int(11) NOT NULL,
  KEY `pid` (`pid`),
  KEY `aid` (`aid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `personadd`
--

LOCK TABLES `personadd` WRITE;
/*!40000 ALTER TABLE `personadd` DISABLE KEYS */;
INSERT INTO `personadd` VALUES (1,1),(1,2);
/*!40000 ALTER TABLE `personadd` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2012-08-09 23:04:56
 

 

 

//Address.java

 

public class Address implements java.io.Serializable {

	// Fields

	private Integer addressId;
	private String item;

 

 

//Person.java

public class Person implements java.io.Serializable {

	// Fields

	private Integer personid;
	private Integer age;
	private String sex;
	private Set<Address> address = new HashSet<Address>();

 

//Person.hbm.xml

    	<!-- 基于连接表的一对多单项关联 -->
    	<!-- set name表示Person表中的Address集合,table是关联表名,cascade级联操作 -->
    	<!-- key column是一端主键在关联表中的外键名 -->
    	<!-- many-to-many column是多端主键在关联表中的外键名 -->
    	<set name="address" table="personadd" cascade="save-update">
        	<key column="pid"/>
        	<many-to-many column="aid"
            	unique="true"
            	class="com.v512.examples.Address"/>
    	</set>

 


保存数据

//HibernateTest.java

 

	public static void addInfo()
	{
		Address ad1 = new Address();
		ad1.setItem("address_no1");
		Address ad2 = new Address();
		ad2.setItem("address_no2");
		
		Person person = new Person();
		person.setAge(10);
		person.setSex("M");
		
		Set<Address> address = new HashSet<Address>();
		address.add(ad1);
		address.add(ad2);
		person.setAddress(address);
		
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();
		//启用级联操作
		session.save(person);
//		session.save(ad1);
//		session.save(ad2);
		tx.commit();
		session.close();
		HibernateUtil.shutdown();

	}

 

 

 

操作信息如下: 

 

22:59:30,843 DEBUG ConnectionManager:444 - opening JDBC connection
22:59:30,843 DEBUG JDBCTransaction:87 - current autocommit status: false
22:59:30,843 DEBUG IncrementGenerator:104 - fetching initial value: select max(personid) from person
22:59:30,843 DEBUG AbstractBatcher:410 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
22:59:30,859 DEBUG SQL:111 - 
    select
        max(personid) 
    from
        person
Hibernate: 
    select
        max(personid) 
    from
        person
22:59:30,859 DEBUG IncrementGenerator:119 - first free id: 1
22:59:30,859 DEBUG AbstractBatcher:418 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
22:59:30,875 DEBUG AbstractSaveEventListener:135 - generated identifier: 1, using strategy: org.hibernate.id.IncrementGenerator
22:59:30,890 DEBUG IncrementGenerator:104 - fetching initial value: select max(addressId) from address
22:59:30,890 DEBUG AbstractBatcher:410 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
22:59:30,890 DEBUG SQL:111 - 
    select
        max(addressId) 
    from
        address
Hibernate: 
    select
        max(addressId) 
    from
        address
22:59:30,890 DEBUG IncrementGenerator:119 - first free id: 1
22:59:30,890 DEBUG AbstractBatcher:418 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
22:59:30,937 DEBUG AbstractSaveEventListener:135 - generated identifier: 1, using strategy: org.hibernate.id.IncrementGenerator
22:59:30,937 DEBUG AbstractSaveEventListener:135 - generated identifier: 2, using strategy: org.hibernate.id.IncrementGenerator
22:59:30,937 DEBUG JDBCTransaction:134 - commit
22:59:30,937 DEBUG AbstractFlushingEventListener:134 - processing flush-time cascades
22:59:30,937 DEBUG AbstractFlushingEventListener:177 - dirty checking collections
22:59:30,937 DEBUG Collections:199 - Collection found: [com.v512.examples.Person.address#1], was: [<unreferenced>] (initialized)
22:59:30,984 DEBUG AbstractFlushingEventListener:108 - Flushed: 3 insertions, 0 updates, 0 deletions to 3 objects
22:59:30,984 DEBUG AbstractFlushingEventListener:114 - Flushed: 1 (re)creations, 0 updates, 0 removals to 1 collections
22:59:30,984 DEBUG Printer:106 - listing entities:
22:59:30,984 DEBUG Printer:113 - com.v512.examples.Person{sex=M, address=[com.v512.examples.Address#1, com.v512.examples.Address#2], age=10, personid=1}
22:59:30,984 DEBUG Printer:113 - com.v512.examples.Address{item=address_no1, addressId=2}
22:59:30,984 DEBUG Printer:113 - com.v512.examples.Address{item=address_no2, addressId=1}
22:59:30,984 DEBUG AbstractBatcher:410 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
22:59:30,984 DEBUG SQL:111 - 
    insert 
    into
        hibernate_demo.person
        (age, sex, personid) 
    values
        (?, ?, ?)
Hibernate: 
    insert 
    into
        hibernate_demo.person
        (age, sex, personid) 
    values
        (?, ?, ?)
22:59:30,984 DEBUG AbstractBatcher:66 - Executing batch size: 1
22:59:30,984 DEBUG AbstractBatcher:418 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
22:59:30,984 DEBUG AbstractBatcher:410 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
22:59:30,984 DEBUG SQL:111 - 
    insert 
    into
        hibernate_demo.address
        (item, addressId) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        hibernate_demo.address
        (item, addressId) 
    values
        (?, ?)
22:59:31,000 DEBUG AbstractBatcher:248 - reusing prepared statement
22:59:31,000 DEBUG SQL:111 - 
    insert 
    into
        hibernate_demo.address
        (item, addressId) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        hibernate_demo.address
        (item, addressId) 
    values
        (?, ?)
22:59:31,000 DEBUG AbstractBatcher:66 - Executing batch size: 2
22:59:31,000 DEBUG AbstractBatcher:418 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
22:59:31,000 DEBUG AbstractCollectionPersister:1112 - Inserting collection: [com.v512.examples.Person.address#1]
22:59:31,000 DEBUG AbstractBatcher:410 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
22:59:31,000 DEBUG SQL:111 - 
    insert 
    into
        personadd
        (pid, aid) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        personadd
        (pid, aid) 
    values
        (?, ?)
22:59:31,000 DEBUG AbstractBatcher:248 - reusing prepared statement
22:59:31,000 DEBUG SQL:111 - 
    insert 
    into
        personadd
        (pid, aid) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        personadd
        (pid, aid) 
    values
        (?, ?)
22:59:31,000 DEBUG AbstractCollectionPersister:1194 - done inserting collection: 2 rows inserted
22:59:31,000 DEBUG AbstractBatcher:66 - Executing batch size: 2
22:59:31,000 DEBUG AbstractBatcher:418 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
22:59:31,000 DEBUG JDBCTransaction:147 - committed JDBC Connection
22:59:31,000 DEBUG ConnectionManager:427 - aggressively releasing JDBC connection
22:59:31,000 DEBUG ConnectionManager:464 - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
22:59:31,000  INFO SessionFactoryImpl:853 - closing
22:59:31,000  INFO DriverManagerConnectionProvider:170 - cleaning up connection pool: jdbc:mysql://localhost:3306/hibernate_demo
 

 

 

 

其他的代码都是通过myeclipse生成的,不是很麻烦。

 


刚开始大家可能会有疑惑,是呀,有3个表,为什么不建3个类,3个hbm文件呢?


事实是这样的,数据库之间的表关联关系通过外键实现,现在有了外键关系表。而实体呢?实体之间是通过集合类进行关联的,我们在Person.hbm.xml文件中配置了一对多的关联关系,自然也不同在建立什么关联关系表的映射文件了,对吧。况且,2个文件能做的事情,何必用3个文件呢。

 

 

分享到:
评论

相关推荐

    Hibernate Annotation 基于连接表的单向一对多关联

    本篇文章将详细讲解如何利用Hibernate的注解实现基于连接表的单向一对多关联。 首先,理解一对多关联:在数据库设计中,一对多关联意味着一个实体(表)可以与多个其他实体(表)相对应。例如,一个学生可以有多个...

    hibernate多对多单向关联

    总结来说,Hibernate中的多对多单向关联是一种高效的数据映射方式,它允许我们在不增加复杂性的情况下处理两个实体之间的复杂关系。通过学习和实践,开发者能够更好地掌握这种关联类型,从而在实际项目中灵活运用。

    Hibernate关联映射

    8. Hibernate 多对多单向关联: 多对多关联通常通过连接表实现,但单向关联意味着只有一方(如 Course)知道这个关联,另一方(如 Student)不知情。Course 实体类中会有一个 `set` 或 `list` 类型的属性,使用 `...

    Hibernate教程13_关系映射之多对多单向关联

    在本教程中,我们将深入探讨Hibernate中的一个关键概念——关系映射,特别是多对多单向关联。在数据库设计中,多对多关系是两个实体之间最复杂的关系类型,允许一个实体实例与多个其他实体实例相关联,反之亦然。在...

    Hibernate关于注解的一对多,多对多,一对一

    本篇文章将深入探讨Hibernate中注解的一对多、多对多和一对一关系映射。 ### 一对多关系 在现实生活中,例如一个班级有一个班主任,而班主任可以管理多个学生,这就是典型的“一对多”关系。在Hibernate中,我们...

    hibernate单向多对多映射(注解版)

    3. `@JoinColumn`: 定义一对一或一对多关系中的外键字段,这里用在`@JoinTable`中,表示多对多关系的连接表中外键的属性。 在上述代码中,`Student`实体有一个`courses`集合,它包含了与之关联的所有`Course`实体。...

    hibernate多对多关联映射(单项关联)

    总的来说,这篇博客和相关代码示例为开发者提供了一个理解和实现Hibernate中多对多单向关联的起点,帮助他们更好地处理复杂的数据库关系映射。学习和实践这部分内容对于提升Java后端开发能力,特别是使用Hibernate...

    Hibernate一对一单向外键关联 (联合主键annotation)

    在Java的持久化框架Hibernate中,一对一(One-to-One)关联是常见的关系映射类型,它用于表示两个实体之间存在唯一的对应关系。本篇将详细讲解如何使用Hibernate进行一对一单向外键关联,并且该关联涉及到联合主键的...

    hibernate一对多与多对一

    例如,在一对多关系中,如果班级知道它的所有学生,但学生不知道他们属于哪个班级,这就是单向关联。如果学生也知道他们所属的班级,那就构成了双向关联。在双向关联中,我们需要在两个实体类中分别使用`@ManyToOne`...

    hibernate实例(一对多,多对一)

    在这个“hibernate实例(一对多,多对一)”的主题中,我们将深入探讨两种重要的关联关系:一对一(One-to-One)和一对多(One-to-Many)。 **一对一关联(One-to-One)** 在一对一关联中,一个实体与另一个实体之间...

    hibernate实体关联关系映射

    本文旨在深入探讨Hibernate中的实体关联关系映射技术,主要包括一对一、一对多、多对多等不同类型的关联关系及其在实际开发中的应用技巧。通过本文的学习,开发者可以更好地理解和掌握Hibernate框架下的实体关联关系...

    Hibernate 一对一,一对多,多对多例子

    4. **双向关联**:在一对一和一对多关联中,关联可以是单向或双向的。双向关联意味着两个实体都能访问到彼此,需要在双方都添加相应的注解。例如,对于一对一关联,需要在双方都使用`@OneToOne`,对于一对多,需要在...

    hibernate关联关系2

    - `@JoinColumn`用于一对一或一对多的单向关联,指定外键所在的列。 - `@JoinTable`用于多对多关联,定义连接表及其列。 二、项目实践 该项目可能包含以下关键文件: - `pom.xml`:Maven项目配置文件,包含了...

    Hibernate_实体关联关系映射--学习总结

    - **一对多连接表关联**:通过一个连接表来建立一对多的关联关系。 3. **多对多关联**: - **多对多连接表关联**:多对多关系通常通过一个连接表来实现,连接表中包含两个外键,分别指向相关联的两个实体的主键。...

    Hibernate关联关系映射目录

    在多对多单向关联中,两个实体之间可以相互关联,这种关联通常通过第三个表(连接表或关联表)来实现。 **表结构示例**: - **Student表**: - `studentid`: 主键 - `name`: 姓名 - `age`: 年龄 - **Course表**:...

    Hibernate关联关系总结

    本篇文章将深入探讨Hibernate中的三种主要关联关系:一对一、一对多和多对多。 **一对一关联(One-to-One)** 一对一关联在现实生活中很常见,例如一个人只有一个身份证。在Hibernate中,这种关联可以通过`@...

    Hibernate_Annotation关联映射

    通过在被拥有的实体端(owned entity)增加一个外键列来实现一对多单向关联是很少见的,也是不推荐的,建议通过一个联接表来实现这种关联(下面会讲到)。 @JoinColoumn批注来描述这种单向关联关系 @Entity Public class...

    hibernate的关联映射

    - 这种关联实际上是一对多关联的反向视角,配置方式与一对多的单向关联类似,只是角色互换。 4. **多对多关联映射** - **中间表关联**:多对多关联通常需要一个中间表来存储两个实体的连接信息。在映射文件中,...

Global site tag (gtag.js) - Google Analytics