hibernate多对多,Hibernate的多对一和一对多操作实例
hibernate多对多,Hibernate的多对一和一对多操作实例详细介绍
本文目录一览: hibernate 多对多关系中 关联表中可以有其他属性吗
可以
这个多对多,你就分成2个多对一:
student(id,name,...)对stu_tea(studentId,teacherId,xxx)多对一
teacher(id,name,...)对stu_tea(studentId,teacherId,xxx)多对一
就可以了
操作就直接对stu_tea(studentId,teacherId,xxx)操作
========================
补充:
1、多对多的本质就是2个多对一。
2、所谓的多对多就是用配置,自动产生按一定命名规范表名的中间表,实际上是都产生中间表的(可以建个空的库,在多对多配置后,跑一下,然后可以去数据库自己去看)。
3、分成2个多对一,只不过是我们自己定义了中间表的表名而已。
4、记得给分啊……
Hibernate的多对一和一对多操作实例
Hibernate <>的一对多和多对一操作真的很方便 如果系统采用Hibernate作为持久层 完全可以把对应的一对多和多对一逻辑关系放在Hibernate里面控制 减少数据库的负担 而且也更清晰
多对一和一对多概念
其实这个概念上来说很简单 比如一个客户可以有多个订单 多个订单属于同一个客户 就是最基本的一对多 和多对一 数据库使用中 感觉多对一和一对多算是比较常见的逻辑关系了
我曾经做过一些数据库 比如某些 *** 部门的 其表单很设计的很简单粗糙 甚至连主键都没有 完全靠在事务层补全这些关系 其实通过Hibernate持久层来实现逻辑关系也是很不错的方法 下面的例子 就是数据库逻辑上基本没有定义 主要放在持久层里面 这个也主要是我对数据库操作属于半通水的原因
数据库层
这里面有两个表单 一个CUSTOMER 客户表单 一个是ORDERS 订单表单 生成客户表单 这个是在SQLServer里面做的 其实其他都一样 因为逻辑关系在Hibernate上面 id是主键非空 其他可以为空
CREATETABLE[dbo] [CUSTOMER](
[id][numeric]( )NOTNULL
[name][varchar]( )NULL
[age][int]NULL
CONSTRAINT[PK_CUSTOMER]PRIMARYKEY)
订单表单
id为主键非空 CUSTOMER_id是对应客户主键 也非空 这里不做外键设置
CREATETABLE[dbo] [ORDERS](
[id][numeric]( )NULLPRIMARYKEY
[CUSTOMER_id][numeric]( )NOTNULL
[ORDER_NUMBER][varchar]( )NULL
[PRICE][numeric]( )NULL
)
Hibernate设定
HIbernate里面 一对多的对象体现 是客户有一个集合set set里面放著对应订单 而多对一体现 是订单里面有一个CUSTOMER对象 表明该订单所属的客户 其中 CUSTOMER类为
publicclassCustomerimplementsjava io Serializable{
privateLongid;
privateStringname;
privateIntegerage;
privateSetrderses=newHashSet();
}
后面的getXXX和setXXX方法就省去了 同样订单类就是
publicclassOrdersimplementsjava io Serializable{
privateLongid;
privateCustomercustomer;
privateStringorderNumber;
privateDoubleprice;
}
而对应hbm文档 就是map文档如下
CUSTOMER hbm xml
mapping dtd >
<!-- MappingfileautogeneratedbyMyEclipsePersistenceTools
>
这个里面 其他都很简答了 其中
表示主键值自动增加 这个主要针对字符串对应的 主要体现多对以的是
其中 set表示 对应集合 fetch和lazy主要是用来级联查询的 而cascade和inverse主要是用来级联插入和修改的 这几个主要包括对集合的控制
表示对应类 即set里面包含的类 而key主要是用于确定set里面对应表单列
ORDERS的hbm
mapping dtd >
<!-- MappingfileautogeneratedbyMyEclipsePersistenceTools
>
表示CUSTOMER熟悉对应的类 和其作为key的列名 上面这些都可以在MyEclipse里面自动生成 另外注意的一点是 在生成的DAO里面 涉及表单操作的save()和delete()方法 必须要事件提交 数据库才有反映 可以就该Hibernate xml 或者用下面这样代码来实现
Sessionse=getSession();
Transactiontx=se beginTransaction();
se delete(persistentInstance);
//se save(instance);
mit();
验证效果
新增用户
如果新增一个用户 该用户里面包含有两个表单 那么 由于持久层已经实现了逻辑关系 只要用户类里面的set包含了表单 则表单可以自动增加 实现代码
CustomerDAOcd=newCustomerDAO();
Customerxd=newCustomer( 王小虎 null);
Ordersord =newOrders();
ord setCustomer(xd);
ord setOrderNumber( 王小虎的买单 );
Ordersord =newOrders();
ord setCustomer(xd);
ord setOrderNumber( 王小虎的买单 );
Setrderses=newHashSet();
orderses add(ord );
orderses add(ord );
xd setOrderses(orderses);
cd save(xd);
代码里面 加入一个王小虎用户 两个订单 通过setOrderses加入 只使用cd save这一个对持久层操作 完成后查询
王小虎
=================================
王小虎的买单
王小虎的买单
显示 CUSTOMER里面加入了王小虎 ORDERS里面也加入他的订单
删除操作
List
csList=cd findByProperty( name 王小虎 );
for(Customercs:csList){
cd delete(cs);
}
这个很简单了 通过其中findByProperty( name 王小虎 );对应SQL为deletefromtableCUSTOMERwherename= 王小虎 ;删除了王小虎 而ORDERS里面 王小虎对应的表单也同时被删除
小小总结
lishixinzhi/Article/program/Java/ky/201311/28543
hibernate 多对多关系中 关联表中可以有其他属性吗
可以
这个多对多,你就分成2个多对一:
student(id,name,...)对stu_tea(studentId,teacherId,xxx)多对一
teacher(id,name,...)对stu_tea(studentId,teacherId,xxx)多对一
就可以了
操作就直接对stu_tea(studentId,teacherId,xxx)操作
========================
补充:
1、多对多的本质就是2个多对一。
2、所谓的多对多就是用配置,自动产生按一定命名规范表名的中间表,实际上是都产生中间表的(可以建个空的库,在多对多配置后,跑一下,然后可以去数据库自己去看)。
3、分成2个多对一,只不过是我们自己定义了中间表的表名而已。
4、记得给分啊……
hibernate多对多关系配置,怎样实现新增中间
多对多表结构设计是添加一张中间关联表,如下图:
学生实体添加老师实体的关键代码:
public class Student ...{private String stuId;private String stuName;//学员名称private Integer stuInAge;//入学年龄//////////////////////////////////////private Set
teachers = new HashSet
(0);
学生实体的映射文件:
老师实体添加学生实体的关键代码:
package com.turing.entity;import java.util.Date; import java.util.HashSet; import java.util.Set;public class Teacher ...{private String tcId;private String tcName;private String tcInfo;//////////////////////////////////////////private Set
students = new HashSet
(0);
老师实体的映射文件:
hibernate多对多映射中间表有多余字段问题该如何映射
省省是吧。已myeclipse为例
--》
,直接自动生成吧
将多对多转换成一个多对一和一个一对多。中间表自己控制。
将多对多创建成两个一对多关系就行了。
你的中间表对象没有主键,第一种方式就是你为中间表增加一个主键,这个也是如果要把中间表映射成对象的推荐方式。
第二种方式就比较复杂,你需要在中间表对象里面再增加两个属性,int role_id,int power_id,用来映射你中间表中作为复合组件的两个外键,然后在Role_power对象中把role_id和power_id映射成compositeid,然后仍然把Role role和Power power两个属性映射成many2one,然后设置这两个属性对应的many-to-one的column为role_id和power_id,然后把这两个属性的insert="false" update="false",就可以了。这样就比较麻烦
还有一种就是你中间表就不要Role role和Power power,而直接把这两个对象改成int roleId,int powerId来映射。
hibernate 多对一 一对多 出现死循环
https://blog.csdn.net/ludengji/article/details/11584281
环境:springmvc+hibernate+json
在controller返回数据到统一json转换的时候,出现了json infinite recursion stackoverflowerror的错误,即json在将对象转换为json格式的数据的时候,出现了无限递归调用的情况。
具体的情况如下:
A类中,有个属性:List b, A与B的关系为 OneToMany;在B类中,有属性A a,引用到A中的字段id,并作为外键。hibernate查询结果正常,可以看到返回的A对象中,有b参数值,但在json转换的时候就出现了无限递归的情况。个人分析,应该是json在序列化A中的b属性的时候,找到了B类,然后序列化B类,而B类中有a属性,因此,为了序列化a属性,json又得去序列化A类,如此递归反复,造成该问题。
解决:
在B类中a的getter setter方法上加注解@JsonBackReference,其实自己试过只在setter方法上加@JsonBackReference也够了。
参考文章:
http://my.oschina.net/u/943437/blog/145246
hibernate多对多关系删除关联,更新不关联的问题
在多对多关系中,中间关系表中的数据本身就是靠role和popedom来进行控制的。
当添加role或popedom时,会自动根据多对多的set集合中的数据在对中间关系表的数据进行添加。
删除时也一样,根据Set集合中的数据来对中间关系表进行删除。
而当进行更新操作时,hibernate会自动先将中间关系表中的数据删除,再将现在Set集合中的数据添加到中间表中,以完成修改的目的。(先删除原有数据,再添加新的数据)
如果不想这样自动修改,可以直接使用HQL进行修改,而不使用session.update()方法,这样可以防止这种关系表的级联操作。也可以通过配置inverse="true"来完成。
关系表中的数据只能通过这种关联的方式来更新。
hibernate 一对多,多对多时 ,表一定要外键吗
以上回答需要的都真的做过项目吗??
明显是不需要的,
hibernate
的级联关系不需要表有任何
外键
,只要在逻辑上确实数据之间的关系和配置的级联关系符合就行了。
其实验证这个很简单,建一个最简单的一对一关系表,先是有外键的,运行期间把外键删了,什么事没有,跑的好好的
hibernate中多对多关系如何保存中间表其他表数据不变
可以试试用Hibernate原生查询直接用SQL语句向中间表插入数据。
Query query=session.createSQLQuery("insert into t_stu_tea(stu_id,tea_id) values(?,?)");
query.setInteger(1,1);
query.setInteger(2,1);
query.executeUpdate();
希望有帮助。我也暂时没具体的执行验证,想思考看看有没有更好的办法
在配置文件里写,比如说:Teacher 和 Student 的关系 一个学生可以有多个老师,一个老师也可以有多个学生
配置文件内容
--Student一方的配置文件--
//中间表与Student 关联的列 与Student中的主键关联
//Teacher与中间表关联的列 与Teacher主键关联
--Teacher一方的配置文件--
//此处column值必须与上面
处的column值一致
//此处column值必须与上面
的column值一致
在hibernate多对多使用连接表双向关联,添加新关系时,hibernate会把所有的关联先查询出来,如何提高效率
使用了多对多关联和hibernate,那么不管你从student表还是从teacher表添加,都会要把所有的teacher或者student查出来。
使用多对对,数据库表设计就有瑕疵,要提高效率,考虑下表设计。
Many2Many:定义多对多关联, 通过@table描述关联表和关联表之间的关系,双向关联时一端必须定义为owner,另一端必须定义为inverse
@ManyToMany(targetEntity=全路径.calss)
@JoinTable(name=”table_name”),
JoinColumn(name=”column_name”)需要关联的列名,
InverseJoinColumns=@JoinColumn(name=”cloumn_name”)指向目标实体表的外键.
要是这么你都觉得效率低,那就不要用 hibernate,直接用sql插入一条记录到teacher_student表够快了吧。一个是面向对象,一个面向关系,有得必有失。
设置 lazy="false"
您可以
aStudent.getTeachers().add(aTeacher);
这样一个学生关联老师的数量是少的。在学生这一侧做操作比在老师一侧做操作关联的数据量少。提高效率。
否则,就需要使用本地SQL的方式进行操作了。但是这样就又失去了使用Hibernate的意义了。使用Hibernate的一般原则是尽量通过Hibernate提供的API来完成数据库操作,这样会简化代码编写,提高开发效率。但是有的时候考虑程序运行效率和需求,需要使用本地SQL的方式来操作数据库,目的是提高效率。在这样的矛盾中,根据需求进行取舍吧。