临时状态(Transient)
持久化状态(Persistent)
游离状态(Detached)
是否处于Session缓存中
×
√
×
数据库中是否有对应记录
×
√
√
两者都不会被Session关联,对象属性和数据库可能不一致;
游离对象由持久化对象关闭Session而转化而来,在内存中还有对象所以此时就变成游离状态了;
在操作了hibernate的方法如save()等后,并没有直接生成sql语句,去操作数据库,而是把这些更新存入Session中,只有Session缓存要被更新时,底层的sql语句才能执行,数据存入数据库。下面举例说明:
一、Session.save(user)运行机理。
PS:在你执行Session.save(user)后,在Session清理缓存前,如果你修改user对象属性值,那么最终存入数据库的值将是最后修改的值;此过程中ID不能被修改;
二、Session.delete(user)运行过程。
在以前的版本中,通常我们创建SessionFactory的方式是:
configure.buildSessionFactory();
Hibernate4.0之后引入新特性——Service Register机制,创建方式为:
StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
SessionFactory sf = configuration.buildSessionFactory(serviceRegistry);
但是紧接着在4.1之后的版本中,StandardServiceRegistryBuilder又被取消了,取而带之的做法是:
Configuration configiguration = new Configuration().configure();
ServiceRegistryBuilder builder = new ServiceRegistryBuilder().applySettings(configiguration.getProperties());
ServiceRegistry registry = builder.buildServiceRegistry();
factory = configiguration.buildSessionFactory(registry);
创建 Configuration类的对象时执行 configure() 方法:
Configuration cfg = new Configuration().configure();等同于Configuration cfg = new Configuration();
configure()方法默认会在classpath下面寻找hibernate.cfg.xml文件,如果没有找到该文件,系统会打印如下信息并抛出HibernateException异常。
1、一对一外键单向关联
主表类引用副表类,并在主表类的引用字段的get()方法上加@OneToOne
get()方法上加 @JoinColumn(name="该属性在数据库映射的字段名") 注解,在副表添加映射字段(缺省默认为.......)
2、一对一外键双向关联
主表类与副表类互相引用,并在各自引用字段的get()方法上加@OneToOne
建议在副表类设置mappedBy属性 @OneToOne(mappedBy="主控端引用的属性名") 注解,表示被控端不用额外添加外键关联,由对方设置(mappedBy的值是属性的get()方法逆向生成,但是通常与属性对应,可理解为等同,通常双向关联必设)
3、联合主键关联
被控端为有联合主键的类,主控端要在引用字段的get()方法上加 @OneToOne
get()方法上加上如下注解:
@JoinColumns(value={
@JoinColumn(name="主键1映射字段",referencedColumnName="所参考被控端主键1属性"),
@JoinColumn(name="主键2映射字段",referencedColumnName="所参考被控端主键2属性"),
})
4、组件映射
被嵌入类不要写 @Entity 注解,因为不作为单独表在数据库映射
主类要有被嵌入类的引用,在其get()方法上添加 @Embedded 注解
5、多对一外键单向关联
多对一在“多”的一方添加“一”的一方的引用,并用 @ManyToOne 注解
用 @JoinColumn(name="多的一方添加的字段名") 指定添加映射字段名。(缺省默认为.......)
6、一对多外键单向关联
一对多在“一”的一方添加“多”的一方的集合的引用(通常用Set,但是当集合里的对象需要排序时可以使用List,并用@OrderBy()注解——较少使用。最好将成员变量初始化,如:
private Set<User> users = new HashSet<User>();
),并用 @OneToMany 注解
一对多若缺省@JoinColumn注解会被默认当做多对多的特殊情况处理,即生成一张中间表
避免此情况应加一个注解 @JoinColumn(name="多的一方添加的字段名")
数据库添加的映射字段总是加在多的一方,因为数据库没有集合的概念
7、一对多&多对一双向外键关联(等同)
通常把“多”的一方作为主控端,因为以数据库的角度,关联字段在“多”的一方
主控端和被控端互相引用,即在“一”的一方添加“多”的一方的集合的引用,在“多”的一方添加“一”的一方的引用
主控端在引用字段的get()方法上加 @ManyToOne 注解
被控端在引用字段的get()方法上加 @OneToMany 注解,并设置mappedBy属性为主控端引用的属性名
8、多对多中间表单向关联
主控端引用被控端,并在引用字段的get()方法上加 @ManyToMany
要手动定制中间表的内容,可添加如下注解:
@JoinTable(name="role_user",
joinColumns={@JoinColumn(name="userID")}, //joinColumns是主操作表的中间表列
inverseJoinColumns={@JoinColumn(name="roleID")} //inverseJoinColumns是副操作表的中间表列
)
用joinColumns而不是joinColumn是因为可能会有联合主键
8、多对多中间表双向关联
“一”的一方和“多”的一方互相引用,即在“一”的一方添加“多”的一方的集合的引用,在“多”的一方添加“一”的一方的引用,并在各自的引用字段的get()方法上加 @ManyToMany 注解,其中一方设置mappedBy属性
cascade属性体现在CUD操作(Create Update Delete):
1、在“多”的一方加该注解 @ManyToOne(cascade=CascadeType.ALL)
说明级联类型为所有操作都进行关联,即当sava()“多”的一方的对象时,同时sava()关联的对象(即“一”的一方)
若需要sava()“一”的一方的对象时同时sava()关联的对象,可用注解@OneToMany(mappedBy="role",cascade=CascadeType.ALL)
但是这时需要注意必须设定双向关联(即set关联对象),否则“多”的一方在数据库里映射的外键关联字段可能为空。
2、当删除时如果被删除对象的cascade=CascadeType.ALL的话,会先级联删除关联的对象,然后删除自己,若关联得对象
cascade的值也是CascadeType.ALL,则继续级联删除。
要在删除“多”的一方时避免此现象,可以在删以前先手动去掉关联关系,即把关联属性设为null,或自己拼hql语句,再删除对应记录,如果不删记录,该记录就变成垃圾数据;
删除“一”的一方时得必须自己拼hql语句。
总之两点规律:
fetch属性体现在R操作(Read):
ManyToOne的fetch默认值是FetchType.EAGER —— @ManyToOne(fetch=FetchType.EAGER),如果手动改成FetchType.LAZY,则会在用到关联字段属性时发送SQL语句
OneToMany的fetch默认值是FetchType.LAZY —— @ManyToOne(fetch=FetchType.LAZY)
PS:双向关系不要两边都设fetch=FetchType.EAGER,否则可能会发出多余的SQL语句,一般用FetchType.LAZY足矣
原网址: 访问
创建于: 2018-10-13 16:42:01
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论