- 浏览: 372388 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
云卷云舒灬:
...
Java读取XML配置文件详细总结(dom4j方式) -
ancoa:
多谢博主分享
jQuery实现多选下来框(multiple select) -
aa51513:
图片看不成
java利器---jodd -
wanggang0321:
正在学习中,看完文章了,谢谢写的教程!!!
Tomcat负载均衡和集群环境的搭建 -
yasyas001:
引用
如何实现双(多)语种网站内容的国际化?
多对多(many-to-many):在操作和性能方面都不太理想,所以多对多的映射使用较少,实际使用中最好转换成一对多的对象模型;hibernate会为我们创建中间关联表,转换成两个一对多。
1. E-R图
2. 实体类:
Teacher实体类如下:
Java代码:
Student实体类如下:
java代码:
3.映射文件如下:
Teacher.hbm.xml如下:
Xml代码
Student.hbm.xml如下:
Xml代码
一定要注意映射文件中<many-to-many class="Teacher" column="teacher_id"/>中class的值,它必须与你另一个关联映射文件中的class属性的name值一致,其实就是与你的实体类的类名一致,如:<many-to-many class="Teacher" column="teacher_id"/>中class的值就不能写成"teacher"。如果写成这样的话,就会抛出如下异常:An association from the table teacher_student refers to an unmapped class: com.reiyen .hibernate.domain.teacher
4. 测试程序如下:
Java代码
运行此程序后:控制台打印的sql语句如下所示:
Hibernate: insert into Teacher (name) values (?)
Hibernate: insert into Teacher (name) values (?)
Hibernate: insert into Student (name) values (?)
Hibernate: insert into Student (name) values (?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
一共在中间表里面插入了4条记录。
中间表结构如下所示:
DROP TABLE IF EXISTS `test`.`teacher_student`;
CREATE TABLE `test`.`teacher_student` (
`teacher_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
PRIMARY KEY (`student_id`,`teacher_id`),
KEY `FK2E2EF2DE6C8A2663` (`teacher_id`),
KEY `FK2E2EF2DE5BEEDBC3` (`student_id`),
CONSTRAINT `FK2E2EF2DE5BEEDBC3` FOREIGN KEY (`student_id`) REFERENCES `student` (`id`),
CONSTRAINT `FK2E2EF2DE6C8A2663` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表中插入的记录如下所示:
mysql> select * from teacher_student;
+------------+------------+
| teacher_id | student_id |
+------------+------------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 2 |
+------------+------------+
4 rows in set (0.00 sec)
程序中注释为1的语句非常重要,它是建立Teacher与Student关联的语句,如果没有这两条语句,虽然程序照样会执行,但是在中间表teacher_student没有任何记录,也就是Teacher与Student之间未关联。
当然你也可以通过程序中注释为2的语句来建立Teacher与Student之间的关联关系,同样会产生与注释为1的语句的效果。但是你不能在程序中同时出现以上四句程序,否则会抛出异常( PRIMARY KEY (`student_id`,`teacher_id`),所以会出现主键冲突的异常 ),:
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
解决上面产生异常的办法是设置inverse属性。即在Tearcher一端或Student一端设置inverse="true",即让他们之中的某一方放弃维护关联关系。此时,虽然上面四句程序在测试程序中同时出现了(其实就是在对象模型上相互设置了他们的关联关系),但程序照样能运行正常,因为了在数据库模型上,只会有两句程序生效,也就是没有设置inverse="true"的那一端会去维护关联关系。有关inverse的说细信息,可以参看我的文章hibernate级联(cascade和inverse).
执行测试程序中的查询测试,控制台打印的信息如下所示:
Hibernate: select teacher0_.id as id5_0_, teacher0_.name as name5_0_ from Teacher teacher0_ where teacher0_.id=?
Hibernate: select students0_.teacher_id as teacher1_1_, students0_.student_id as student2_1_, student1_.id as id7_0_, student1_.name as name7_0_ from teacher_student students0_ left outer join Student student1_ on students0_.student_id=student1_.id where students0_.teacher_id=?
students:2
从打印出的sql语句可以看出,多对多关系进行查询时,效率是比较低的。
1. E-R图
2. 实体类:
Teacher实体类如下:
Java代码:
package com.reiyen.hibernate.domain; import java.util.Set; public class Teacher { private int id; private String name; private Set<Student> students; //setter和getter方法 }
Student实体类如下:
java代码:
package com.reiyen.hibernate.domain; import java.util.Set; public class Student { private int id; private String name; private Set<Teacher> teachers; //setter和getter方法 }
3.映射文件如下:
Teacher.hbm.xml如下:
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.reiyen.hibernate.domain"> <class name="Teacher"> <id name="id"> <generator class="native" /> </id> <property name="name" /> <!-- 通过table项告诉hibernate中间表的名称 --> <set name="students" table="teacher_student"> <!-- 通过key属性告诉hibernate在中间表里面查询teacher_id值相应的teacher记录 --> <key column="teacher_id" /> <!-- 通过column项告诉hibernate对student表中查找student_id值相就的studnet记录 --> <many-to-many class="Student" column="student_id" /> </set> </class> </hibernate-mapping>
Student.hbm.xml如下:
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.reiyen.hibernate.domain"> <class name="Student" > <id name="id" > <generator class="native" /> </id> <property name="name" /> <set name="teachers" table="teacher_student"> <key column="student_id" /> <many-to-many class="Teacher" column="teacher_id"/> </set> </class> </hibernate-mapping>
一定要注意映射文件中<many-to-many class="Teacher" column="teacher_id"/>中class的值,它必须与你另一个关联映射文件中的class属性的name值一致,其实就是与你的实体类的类名一致,如:<many-to-many class="Teacher" column="teacher_id"/>中class的值就不能写成"teacher"。如果写成这样的话,就会抛出如下异常:An association from the table teacher_student refers to an unmapped class: com.reiyen .hibernate.domain.teacher
4. 测试程序如下:
Java代码
public class Many2Many { public static void main(String[] args) { add(); //query(1); } static void query(int id) { Session s = null; Transaction tx = null; try { s = HibernateUtil.getSession(); tx = s.beginTransaction(); Teacher t = (Teacher) s.get(Teacher.class, id); System.out.println("students:" + t.getStudents().size()); tx.commit(); } finally { if (s != null) s.close(); } } static void add() { Session s = null; Transaction tx = null; try { Set<Teacher> ts = new HashSet<Teacher>(); Teacher t1 = new Teacher(); t1.setName("t1 name"); ts.add(t1); Teacher t2 = new Teacher(); t2.setName("t2 name"); ts.add(t2); Set<Student> ss = new HashSet<Student>(); Student s1 = new Student(); s1.setName("s1"); ss.add(s1); Student s2 = new Student(); s2.setName("s2"); ss.add(s2); t1.setStudents(ss); //1 t2.setStudents(ss); //1 // // s1.setTeachers(ts); //2 // s2.setTeachers(ts); //2 s = HibernateUtil.getSession(); tx = s.beginTransaction(); s.save(t1); s.save(t2); s.save(s1); s.save(s2); tx.commit(); } finally { if (s != null) s.close(); } } }
运行此程序后:控制台打印的sql语句如下所示:
Hibernate: insert into Teacher (name) values (?)
Hibernate: insert into Teacher (name) values (?)
Hibernate: insert into Student (name) values (?)
Hibernate: insert into Student (name) values (?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
一共在中间表里面插入了4条记录。
中间表结构如下所示:
DROP TABLE IF EXISTS `test`.`teacher_student`;
CREATE TABLE `test`.`teacher_student` (
`teacher_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
PRIMARY KEY (`student_id`,`teacher_id`),
KEY `FK2E2EF2DE6C8A2663` (`teacher_id`),
KEY `FK2E2EF2DE5BEEDBC3` (`student_id`),
CONSTRAINT `FK2E2EF2DE5BEEDBC3` FOREIGN KEY (`student_id`) REFERENCES `student` (`id`),
CONSTRAINT `FK2E2EF2DE6C8A2663` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表中插入的记录如下所示:
mysql> select * from teacher_student;
+------------+------------+
| teacher_id | student_id |
+------------+------------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 2 |
+------------+------------+
4 rows in set (0.00 sec)
程序中注释为1的语句非常重要,它是建立Teacher与Student关联的语句,如果没有这两条语句,虽然程序照样会执行,但是在中间表teacher_student没有任何记录,也就是Teacher与Student之间未关联。
当然你也可以通过程序中注释为2的语句来建立Teacher与Student之间的关联关系,同样会产生与注释为1的语句的效果。但是你不能在程序中同时出现以上四句程序,否则会抛出异常( PRIMARY KEY (`student_id`,`teacher_id`),所以会出现主键冲突的异常 ),:
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
解决上面产生异常的办法是设置inverse属性。即在Tearcher一端或Student一端设置inverse="true",即让他们之中的某一方放弃维护关联关系。此时,虽然上面四句程序在测试程序中同时出现了(其实就是在对象模型上相互设置了他们的关联关系),但程序照样能运行正常,因为了在数据库模型上,只会有两句程序生效,也就是没有设置inverse="true"的那一端会去维护关联关系。有关inverse的说细信息,可以参看我的文章hibernate级联(cascade和inverse).
执行测试程序中的查询测试,控制台打印的信息如下所示:
Hibernate: select teacher0_.id as id5_0_, teacher0_.name as name5_0_ from Teacher teacher0_ where teacher0_.id=?
Hibernate: select students0_.teacher_id as teacher1_1_, students0_.student_id as student2_1_, student1_.id as id7_0_, student1_.name as name7_0_ from teacher_student students0_ left outer join Student student1_ on students0_.student_id=student1_.id where students0_.teacher_id=?
students:2
从打印出的sql语句可以看出,多对多关系进行查询时,效率是比较低的。
发表评论
-
Java算法—农夫和牛的问题
2013-04-10 16:05 4943问题:一个农夫养了一头牛,三年后,这头牛每年会生出一头牛,生 ... -
Java读取Txt文件
2013-02-28 10:15 2104java读取txt文件的内容 类 ... -
java利器---jodd
2013-01-25 17:26 18563网上对Jodd的描述如下: Jodd是一个普通开源Java ... -
Java程序发送邮件的两种方法
2013-01-24 15:17 3970前一段时间我在博客中发表过Java接收解析邮件的程序,今天, ... -
FreeMarker
2012-12-17 15:19 1863在Web应用中,有时需要按照固定的模板将数据导出到Word,如 ... -
Java读取XML配置文件详细总结(dom4j方式)
2012-11-30 16:57 4715最初的想法是不把mysql的连接参数写到程序中,因为每次要修改 ... -
XML的特殊字符
2012-11-30 16:53 32921XML中共有5个特殊的字符,分别是:&<> ... -
JAVA获取各种各样的时间、时间对比 方法汇总
2012-11-28 17:01 2668import java.text.DateFormat; ... -
ftp 主动模式与被动模式
2012-11-23 12:25 2226tp的工作原理 ftp要用到两个tcp连接即要使用两个端口 一 ... -
JAVA中使用FTPClient上传下载
2012-11-16 15:03 3462在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上 ... -
Java获取网页内容s实现自动化(IASI)
2012-11-16 09:58 3348IasiClient package com.iasi. ... -
httpclient 用java调用 的方式获取网页内容,
2012-11-16 09:43 190321. 读取网页(HTTP/HTTPS) ... -
Java实现Zip压缩,解压缩(二)
2012-11-15 11:16 1610今天写了个用java压缩的功能,可以实现对文件和目录的压缩。 ... -
Java实现Zip压缩,解压缩(一)
2012-11-15 10:37 1637package org; import java.i ... -
java 接收、解析邮件实例(三)
2012-11-15 10:20 1353package com.prase.email.four; ... -
java 发送、解析邮件实例(二)
2012-11-14 16:47 1074package com.prase.email.eight ... -
java 发送、解析邮件实例(一)
2012-11-14 16:40 1474package com.prase.email.six; ... -
java发送邮件详细参数解析总结(一)
2012-11-14 16:36 137581.介绍: Java Mail API的开发是SUN为Jav ... -
JavaMail学习笔记(一)、理解邮件传输协议(SMTP、POP3、IMAP、MIME)
2012-11-14 16:33 1723电子邮件需要在邮件客户端和邮件服务器之间,以及两个邮件服务器之 ... -
Spring MVC页面传参乱码问题解决
2012-11-13 16:26 1853在eclipse环境里,页面传输数据的时候通常用ISO-885 ...
相关推荐
【标题】:“Hibernate多对多” 在Java编程领域,Hibernate是一个非常重要的对象关系映射(ORM)框架,它简化了数据库操作,使开发者能够用Java对象来操作数据库数据。"Hibernate多对多"指的是在Hibernate中处理两...
标题"Hibernate多对多实例+数据库代码"揭示了我们将在讨论一个使用Hibernate框架实现的多对多关系映射的实际案例。在这个实例中,开发人员将两个或多个实体之间的复杂关联转化为简单易懂的数据库操作。描述中提到...
本示例主要关注的是Hibernate中的多对多关联映射及其添加与查询方法。 多对多关联是数据库设计中的一种常见关系类型,指的是两个实体之间可以存在多个对应关系。例如,在学生与课程的关系中,一个学生可以选修多门...
在这个“hibernate 多对多映射实例,学生 选课”项目中,我们将探讨如何使用Hibernate处理多对多关系,以及如何构建一个学生选课的系统。 首先,我们要理解多对多关系。在现实生活中,学生和课程之间就是一个典型的...
hibernate关联映射注解多对多单向关联、
hibernate多对多关系的增删查改 修改有问题
多对多单向关联 <br>需要注意映射规则: <set name="users" table="t_user_role"><br> <key column="roleid"/><br> <many-to-many class="com.bjsxt.hibernate.User" column="userid"/> </set>
用hibernate3.5 xml文件映射,junit实现多对多自动建表,下载后解压用myeclipse导入,这里要注意:需要junit的包。这个是学hibernate的关键,建议新手作为重点,大虾就请多多指教了
博文链接:https://shaqiang32.iteye.com/blog/201317
本项目“hibernate一对多项目”旨在演示如何在JavaWeb应用中使用Hibernate处理一对多的关系映射。这里我们将深入探讨 Hibernate 的一对多关系、配置以及在实际项目中的应用。 首先,一对多关系在数据库中很常见,...
本教程将带你入门Hibernate的多对多实体映射,帮助你理解如何通过源码来实现这种复杂的关系映射。 一、Hibernate概述 Hibernate是一个对象关系映射(ORM)框架,它允许我们将Java对象(实体)与数据库表进行映射,...
hibernate 一对多和多对一的理解 自己的个人看法 大家也来看看
总结,"Hibernate 多表连接分页查询示范项目"是一个实用的示例,它展示了如何在实际应用中利用 Hibernate Criteria API 实现复杂查询和分页,对于学习和掌握 Hibernate 的高级特性和数据库操作技巧非常有帮助。...
hibernate 多表查询 hibernate 多表不同于一般的sql嵌套查询,嵌套查询是不支持的,所以必须要配置好才能实现多表!只要配置好了,还是特别好用的
“Hibernate 一对一,一对多,多对多例子” 指的是使用Hibernate框架实现数据库中不同关联关系的示例。Hibernate是一个Java持久化框架,它提供了对象关系映射(ORM)功能,使得开发人员可以方便地在Java对象和关系...
包含《多对多双向关联映射》《多对一单向关联映射》《多对一双向关联映射》《一对多单向关联映射》等文档,并有图解及例子,非常适合新手学习,尤其是刚刚接触hibernate,对映射关系不清楚的。。。。
"33-37Hibernate1对N案例笔记.pdf"和"38-43Hibernate多对多案例笔记.pdf"则深入探讨了这些关联在实际项目中的应用。 Spring框架是一个全面的后端解决方案,不仅包含MVC框架,还有面向切面编程(AOP)、依赖注入(DI...
在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,这个是xml配置的例子
在多租户场景下,Hibernate 4提供了对多租户支持,允许根据不同的租户ID动态切换到对应的数据库Schema,从而实现数据的隔离。 1. **多租户实现方式** Hibernate 4提供了两种主要的多租户实现方式:基于Schema的多...
接着,描述中的"Spring+Hibernate多数据源的整合实现demo"意味着这是一个实际操作的示例,它可能包含了一个或多个配置文件和Java代码,展示了如何在Spring Boot或者传统的Spring环境下配置和使用多数据源。...