hibernate map 映射,key和value只能是一对一吗,一个key对应多个value怎么办?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate map 映射,key和value只能是一对一吗,一个key对应多个value怎么办?相关的知识,希望对你有一定的参考价值。

即:value是个list或set。
m为map:
m.put("li", "123");
m.put("li", "123");
m.put("li", "124");
m.put("wang", "123");
m.put("wang", "126");

保存后,数据库里我想要有如下数据:
id| name| phoneNO
1 | li | 123
1 | li | 124
1 | wang| 123
1 | wang| 126

-----------------
但实际情况只有如下数据:
id| name| phoneNO
1 | wang| 126
1 | li | 124
是啊需求就是这样。
Person类里有个电话本 map <人名,Set<号码>>,一个有多个号码很正常啊。
但怎么做呢?session.saveOrUpdate();后存进去key所对应的只有一个,总是被后面的覆盖。
难道只能用原生sql了?

“那么这又是一个一对多了”,这个一对多要怎么映射呢?
---------------------------------------------
lixieinstein - 非常真心地感谢你,不给你加分都感觉可耻了:
你说得很对。这种电话本的情况是可以避开这种麻烦。但我还举个例子,我感觉非这样不可了:
有 老师类,班级类,课程类 。老师可以在不同班级教不同或相同课程。那么就正好碰上了此麻烦。
老师类 里放个 Map<班级,Set<课程>>。你看看是不是?

要明白ORM
实体类映射到数据库时,在数据库中生成的表是不一样的.
一个人有多个电话号码 一个电话号码也可以被多个人有
我就张三,李四的手机号,你也有张三,李四的手机号.
再详细些,我有张三的手机号,张三可能有多个手机号,有北京的手机号,有上海的手机号...
一对多这种关系一般要设置一个list/map集合来存,在数据库中体现为外键.
复杂的情况就是多对多关联关系.

楼主的这个情况我这样来分析.
首先是数据库,你想要的那种方式
保存后,数据库里我想要有如下数据:
id| name| phoneNO
1 | li | 123
1 | li | 124
1 | wang| 123
1 | wang| 126
这种方式明显存在着冗余.而且不可能实现,为啥?主键不唯一.
数据库里同时存着id=1的两条记录,那我想要查询id=1的记录怎么查?可以查,但是查出来的是两打记录.但是可以用联合主键id和name,phone三个字段共同确定主键.
但实际情况只有如下数据:
id| name| phoneNO
1 | wang| 126
1 | li | 124

你的的需求是想做什么?
session.saveOrUpdate();这种方式肯定会覆盖前一个,为啥?
你更新了这个类的某个属性phoneNO.

要想实现你想要的情况:
我个人觉得可以这样实现:
建两个实体类,会在数据库中生成两张表.
参照lixieinstein的回答...............
---------------------------------------------------
在Person中
private <Record> setRecord=new hashSet<Record>;
//record为联系记录.
再建立映射就行了.//关键要建立好关联关系的映射
当我们加载一个person类时,会加载这个person的属性setRecord
而setRecord是一个集合,我们可以从遍历集合里面取出这些联系记录.
如果某个人的手机号码更改了,你要更新的不是person类,而是更新
联系记录类record类中的某个属性.
参考技术A 我觉得应该这样设计数据库。实际情况下,一个人和他电话号码的就是一对多单向关联映射。电话本只是一个虚拟的概念,不需要实际存在于数据库中,实际存在于数据库中的是电话本中的联系记录。就是一个人对应多个联系记录。这样就行了。
如:person表:
id(主键) username(用户名) truename(真实姓名) ……
联系记录表:
id(主键) personId(外键,和person表中的id对应) name(联系人姓名) number(电话号码)
那么Person中只需要一个Set<联系记录>的属性就行了,然后再把Set中所有的信息根据“联系人姓名-Set<电话号码>”的键值对形式存入到一个Map中,那么这个Map就是你要的Map。
我语言表达比较差,不知道你看懂了没有。
参考技术B 如果这样的话,那么这又是一个一对多了
map里面嵌套有set了

是复杂了点,如果需求是这样,那也没办法
参考技术C 你为什么不用list去临时存放这些数据呢,而且对于这种id 是可以重复的时候不能用hibernate的saveOrUpdate() saveOrUpdate会根据你的table的主键判断是insert或者是update,在这里你需要的结果都是insert 所以最好还是用 JDBC的 sql写 比较好。 参考技术D

用图来回答你.包括文字方面的解释也在图片上.

java map表里,key值能否映射到多个Value?

参考技术A

map中的key和value是一一对应的,但是这里的value可以是一个集合,里面可能包含很多值,这样可以实现。使用时,要循环来访问。

Map的可以唯一无序,value无序且不唯一,所以不同的key会有相同的value,但是他的对内存中还是存储着多个相同的value,这是因为在存到里面的时候是根据hash码存的,hash是唯一的。

扩展资料:

注:将可变对象用作映射键时必须格外小心。当对象是映射中某个键时,如果以影响 equals比较的方式更改了对象的值,则映射的行为将是不确定的。此项禁止的一种特殊情况是不允许某个映射将自身作为一个键包含。虽然允许某个映射将自身作为值包含,但请格外小心:在这样的映射上 equals 和 hashCode方法的定义将不再是明确的。

参考资料来源:百度百科-Map

以上是关于hibernate map 映射,key和value只能是一对一吗,一个key对应多个value怎么办?的主要内容,如果未能解决你的问题,请参考以下文章

Go语言中映射表map的使用

Java的Map集合中多个不同的key可以映射到同一个value吗?

java map接口

D3.js的基础部分之数组的处理 映射(v3版本)

map

Map的学习