Hibernate课堂笔记
1Hibernate是什么
Hibernate是一个数据库的操作框架
1.1Jdbc的缺点
ljdbc的效率比较低
每一次请求,打开连接、发送sql语句,在数据库中解析sql语句等需要消耗大量的资源。
重复性代码特别多
每一次都需要关闭connection,statement,rs
Jdbc没有做到面向对象编程
没有做到数据缓存
现在世界上数据缓存做的很不错的框架(hibernate,oscache,ehcache)
Oscache和ehcache都有页面缓存
*就是把页面上的数据缓存到本地磁盘上
*当应用程序再次访问的时候,直接从磁盘上读取数据就
可以了
*页面缓存不适合做更新特别频繁的数据
1.2Jdbc的优点
是最底层的操作数据库的框架,所以在java的层面上说速度最快
Jdbc做到了connectionpool
1.3Hibernate优点
l面向对象编程
lHibernate的底层也是由jdbc实现的
lHibernate的数据缓存做的相当棒
lHibernate做到了connectionpool
1.4Hibernate缺点
Hibernate不会让程序员干涉sql语句的生成,sql语句是hibernate内部操作jdbc生成的,所以在一个项目中,如果对sql的优化要求比较高,这个时候,不适合用hibernate
如果一张表的数据量特别大(千万级别以上),也不适合用hibernate
2Hibernate的学习内容
l学习hibernate的crud操作
l持久化对象的状态
l一对多和多对多(重点)
l数据缓存(一级缓存、二级缓存、查询缓存)(重点)数据缓存的特点
lHql语句
3hibernate的crud操作
3.1类与表的映射关系
3.2Hibernate配置文件的加载方式
3.2.1方式一
注意:
1、配置文件的名称必须是hibernate.cfg.xml
2、把hibernate.cfg.xml文件必须放在classpath下
3.2.2方式二
注意:
1、利用该方法配置文件的名称可以随意写
2、路径可以随意放
3、Resource代表路径名称+文件名称
注意:hibernate的事务默认不是自动提交的
3.3crud操作注意事项
3.3.1session.get方法
1、要使用session.get方法,那么相对应的持久化类中必须保证有一个无参的构造函数
2、该方法的第二个参数与持久化类中的主键的类型要保持一致。
3、Session.get方法的第二个参数的形参:Serializable.因为只有这样才能接受所有的数据库的主键的类型
3.3.2session.update
参数可以是session.get方法得到的对象,也可以是新创建的对象,但是cid的值必须和数据库的值相对应。
4Hibernate流程
5sessionFactory
1、sessionFactory中存放配置文件和映射文件的所有的信息
2、一个数据库有且仅有一个sessionFactory
3、sessionFactory是一个单例的对象
4、sessionFactory是一个重量级别的类,只加载一次
5、sessionFactory是一个线程安全类
6主键的生成机制
考虑hibernate主键的生成机制可以从三方面去想:
客户端
Hibernate内部可以生成主键
数据库内部的机制生成主键
6.1Incrment
1、获取主键的最大值,然后加1
2、主键的类型必须是数字类型
3、第一步的过程是由hibernate内部做的
4、发出selectmax(cid)fromClasses这样的sql语句,所以效率比较低
5、主键的值是连续的
6.2Identity
1、适用于数字类型
2、数据库表本身的自动增长
3、主键是在数据库内部生成的
4、表必须得设置为自动增长
6.3Assigned
由程序员自己设置生成
6.4Uuid
由hibernate内部生成一个唯一的字符串
7Hibernate类型
Hibernate内部实现了从java类型到数据库类型的映射,所以在映射文件中选择java类型比选择hibenate类型效率要高
8对象的状态
对象的状态的定义
临时状态的对象:刚创建的对象
持久化状态的对象:该对象和session已经发生交互了
脱管状态的对象:由和session的交互变为和session的脱离
8.1案例1
说明:
1、第39行代码发出了update语句
2、在执行第36行代码的时候,利用session.get方法提取出来一个对象,该对象是持久化状态的对象
3、处于持久化状态的对象不用执行session.update方法
4、session.save和session.update方法都是把一个对象的状态变成持久化状态
8.2案例2
说明:
1、在执行40行代码的时候不会发出update语句,因为修改后的数据和原来的数据是一样的。
2、在hibernate内部,会生成该对象的一个镜像文件,在执行update方法的时候,
会查看镜像文件,如果一致,则不执行update,如果不一样才要执行update语句
8.3案例3
说明:
1、第51行代码把classes对象由临时状态转变成持久化状态
2、在第53行代码之前不用执行session.update方法
8.4案例4
说明:
1、59行的session和67行的session是两个session
2、61行产生的classes与67行产生的session直到程序结束没有发生关联
3、一个对象是否是持久化对象是针对一个session而言的
8.5案例5
分析:
1、当执行82行代码的时候,把classes从持久化状态的对象转化成脱管状态,这个时候和session没有关联了
2、在执行84行代码的时候没有执行update语句
3、要想执行update语句,必须使classes成为持久化状态的对象,所以执行update方法
8.6对象状态转化图
说明:
只有持久化状态的对象才能和session发生交互
9Hibernate对象关系
研究:
1、crud的操作
2、外键(面向对象:关系)
9.1一对多单项
9.1.1Cascade
1、cascade只能出现在多表中
2、针对一对多的情况
在保存或者更新classes的时候,针对student应该做什么样的操作
9.1.1.1案例1
分析:因为classes与student都是临时状态,所以应该是在保存classes的同时保存student
9.1.1.2案例2
分析:
1、因为在客户端和在映射文件中都有设置级联,所以cascade是起作用的
2、在上述代码中,因为classes的一般属性并没有发生改变,所以针对classes不会发出update语句
3、因为classes的集合发生改变了,而且级联起作用,所以hibernate内部会去检查classes中的集合的状态,因为集合中多了一个数据,所以增加了一个student
4、级联操作是对象与对象的操作
9.1.1.3案例3
当提交的时候,因为是级联操作,因为对student的一般属性发生了改变,所以在更新classes的时候更新了student
9.1.1.4总结
1、级联是对象与对象之间的操作,和关系无关
2、对一个对象进行操作的同时,怎么样操作级联对象,看级联对象是否是持久化对象(看级联对象对应数据库是否有数据),如果是持久化对象,则执行update操作,如果是临时状态的对象,则执行insert操作
9.1.2Inverse
对象对关系是否维护
上述的图的意思为Classes是否要维护student表的关系(外键),如果inverse为false,则维护,如果为true,则不维护
9.1.2.1案例1
分析:
1、该例子从数据库的角度分析,把sid为2的值的外键修改一下就可以了
2、从hibernate的角度是修改关系
3、查看classes.hbm.xml映射文件中,classes能否修改classes与student之间的关系。
4、因为关系的修改就是一个update操作而已,所以没有必要解除关系。
5、第136行代码是从classes端维护关系。如果从student端维护关系,那
代码应该是student.setClasses();
9.1.2.2案例2
分析:
1、根据映射文件可以得出classes维护关系
2、在对classes进行删除、增加、修改的时候同时要操作student
3、因为classes负责维护关系,所以在删除掉classes之前,hibernate内部会自动执行解除所有的关系的操作
9.1.2.3案例3
分析:
1、解除班级和所有学生之间的关系实际上就是把classes中的集合清空。
2、Classes.setStudents(null)这个时候hibernate内部会直接把关系设置为null,效率最高,根本不需要去查student
9.1.3总结
1、因为是一对多的单项,所以只能是classes维护关系
2、Classes维护关系,所以客户端的代码应该是通过classes对关系进行建立或者解除
3、只要涉及到关系的操作就得发出update语句,用来更新关系。所以用classes维护关系效率并不高
4、一对多,用一的一方维护关系,效率比较低。当数量级别比较大的时候,会发出n多update语句
9.2一对多的双向
9.2.1案例1
分析:
1、通过映射文件可以看出,在Student.hbm.xml文件中,不存在外键,意味着如果通过student建立与classes的联系,在hibernate内部是做不到。
2、Student.getClasses会报空指针异常,得不到,因为没有联系
3、通过classes操作student,看classes.hbm.xm文件,通过student操作classes,
看student.hbm.xml文件
4、所以在classes.hbm.xml文件和student.hbm.xml文件中都必须体现外键
9.2.2案例2
分析:
1、通过代码34行可以得出是通过student联系classes,所以看student.hbm.xml
2、35行代码是保存学生,因为在34行代码中通过student建立了与classes之间的关系,所以在插入学生的同时,在hibernate内部自动维护了关系
3、用学生端维护关系,不需要发出update语句
4、一对多,多的一方维护效率比较高
9.3多对多
9.3.1学习重点
1、映射文件的创建和持久化类的创建
2、关系
说明:
1、关系的操作
建立关系就是在第三张表中插入一行数据
解除关系在第三张表中删除相应的一行数据
改变关系
1、修改相应的行的数据
2、先删除再增加
3、多对多谁维护关系效率都一样,都得对第三张表发出相应的SQL语句
9.3.2练习
9.3.2.1案例1
分析:
1、因为要级联,因为是通过course级联,所以在course.hbm.xml文件中,针对set集合,应该设置cascade属性
2、因为多对多谁维护关系效率都一样,所以在两个映射文件中都维护关系
3、第53行代码,即级联又维护关系
9.3.2.2案例2
分析:
1、经过需求分析可以得出应该是修改学生和课程之间的关系
2、因为在学生类中存在的是课程的集合,而课程类中存在的也是学生的集合
3、集合不存在修改,所以修改关系就等于先解除后增加
4、通过哪个端修改关系都可以,但是要统一
10性能
10.1懒加载(延迟加载)
概念:需要时加载
10.1.1 类的懒加载
分析:
1、利用session.load方法就是类的延迟加载
2、利用session.load方法产生的是代理对象,利用session.load方法的出来的对象只有id值(标识符属性)
3、当得到具体的属性的时候才要发出sql语句
4、类的延迟加载只针对一般属性有效
5、必须在session关闭之前把数据提取出来
10.1.2集合的懒加载
分析:
1、集合的懒加载,只有在根据一的一方加载多的一方的情况下才要讨论这种情况
2、如果采用默认的加载方式,就是集合的懒加载
3、在遍历集合的时候才要发出sql语句
4、如果在set元素中lazy为false
1、在执行31行代码的时候,发出两条sql语句
第一条查询的是classes
第二条查询的是根据cid查询student
5、集合的懒加载还有一个值为extra,更进一步的懒加载
分析:因为不需要加载student的属性,只需要一个函数的结果,所以就发出了上面的sql语句
10.1.3单端关联的懒加载
因为单端关联只加载一个数据,所以用默认情况做就可以了
False/proxy(true)/no-proxy
10.2抓取策略
根据一方怎么样提取关联端
根据一的一方怎么样提取多的一方
根据多的一方怎么样提取一的一方
10.2.1方式
前提条件:针对集合
懒加载
|
抓取策略
|
Sql语句
|
True/false/extra
|
Join(子查询除外)
|
发出一条,把所有的数据全部加载了
|
True/false/extra
|
select
|
在遍历集合的时候才要发出sql语句,这个时候发出n+1条sql语句/在加载classes的时候就把student的数据加载出来了/extra在这里等同于true
|
True/false/extra
|
subselect
|
如果检测到由子查询,则用subselect
|
说明:
1、如果第一页面只有一的一方的数据,然后根据超级连接才要显示多的一方的数据,这种情况用select或者subselect
2、如果页面上既有一的一方的数据也有多的一方的数据,用join是比较好的选择。
1、select默认的
1、先查询班级(cid:1,2,3)
2、根据班级中的每一个cid去查相应的学生
2、subselect子查询
根据需求分析先写出sql句,只要sql语句中含有子查询,那么肯定是子查询的效率比较高
3、join连接
1、如果根据需求分析,得出的sql语句含有子查询,这个时候用join(左外连接)
不起作用
3、如果没有子查询,则利用join的方式(左外连接),就可以一次性的把一和多的数据全部查询出来
10.3懒加载与抓取策略的结合
10.4Session
10.4.1Session的产生方式
10.4.1.1openSession
分析:
1、只要代码中遇到sessionFactory.openSession,那么在hibernate内部就会新创建一个session
2、只要openSession一次,hibernate内部就会连接数据库一次,所以在代码中opesnSession的次数,越多效率越低
3、只要执行sessionFactory.openSession一次就会产生一次连接
4、Hibernate中的事务是依赖session的
5、最好一个方法只有一个session
10.4.1.2currentSession
分析:
1、在特别复杂的项目中,一个service方法可以操作很多内容,而这些内容有可能涉及到很多框架,而框架对于hibernate的操作对于程序员来说是不可见的
2、但是要想使上面的service方法运行成功,必须在一个事务环境下运行
3、要想在一个事务环境下运行,必须只有一个session
4、把当前线程绑定到session是一个特别好的解决方案
注意:
只要用到当前线程产生的session,crud操作必须在事务的环境下运行
当前线程的session还和事务绑定,这样可以提高安全性能
当事务提交的时候,当前线程中的session关闭了
用当前线程产生的session,不需要手动关闭session。
配置方式:
在hibernate.cfg.xml文件中
在代码中利用sessionFactory.getCurrentSession就可以实现了
10.4.2Session的生命周期
10.4.3Session中的缓存
10.4.4安全
说明:
1、不同的客户端访问有不同的线程,不同的线程就有不同的session,特定的数据在特定的session中
2、一个数据只能让一个客户端拥有
3、把session绑定到当前线程中解决了session中数据线程安全的问题
11Hibernate错误分析
11.1错误一
分析:
l在配置文件中加载该文件,但是路径写错了,找不到
l该文件根本没有加载到配置文件中
11.2错误二
分析:
当生成sql语句的时候,利用get方法获取值,这个时候,需要映射文件中的name属性拼接成get方法,然后利用java的反射机制赋值,拼接的时候出错了,所以属性找不到。
11.3错误三
分析:说明持久化没有找到,持久化类没有找到并不一定意味着该类不存在,有可能映射文件路径写错了
以上两个错误结合一起,就是总结出:
在映射文件中,class元素的name属性的值写错了
11.4错误四
在hibernate的配置文件中,映射文件的路径写错了
11.5错误五
分析:
1、有可能在映射文件中,class元素的name属性的值写错了
2、在客户端session.save进行操作的时候,因为操作的是持久化对象,所以该对象所在的类必须是映射文件中class元素的name属性,如果不一致,也会报这样的错误
11.6错误六
分析:
Session.get方法两个参数,第二个参数的类型必须与持久化类中的主键的类型保持一致。
11.7错误七
分析:
表本身默认的值,没有支持自动增长
11.8错误八
客户端截图:
分析:根据64行代码可以判断出classes与students建立关联
映射文件:Classes.hbm.xml
总体分析:
1、把session.save(classes)这样的保存称为显示保存
2、在保存classes的同时保存student,保存student的操作是由hibernate内部完成的,我们把这样的操作称为隐式保存
3、在classes.hbm.xml文件set元素中并没有配置cascade
4、只有在客户端建立classes与student之间的关系,然后在映射文件中再次确认关联(cascade)两个地方都配置了,级联保存才能有效
5、因为在classes.hbm.xml文件中,没有针对student的cascade,所以student对象处于临时状态,hibernate是不允许这种情况出现的
6、这个错误只有在多表的情况下才有可能产生
11.9错误九
当session关闭以后还要视图从数据库中提取数据就会报这样一个错误。
解决方案:
在session关闭之前把数据全部提取出来
相关推荐
在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它简化了与数据库交互的过程,使得开发者可以使用面向对象的方式来操作数据库。对于Oracle数据库的支持,Hibernate提供了专门的驱动和配置,使得...
Java通过Hibernate连接数据库是Java开发中的常见操作,Hibernate作为一个强大的对象关系映射(ORM)框架,极大地简化了数据库操作。本篇文章将详细讲解如何利用Hibernate在Java项目中建立数据库连接,以及提供一个...
在当今的Web应用开发中,数据库连接管理是不可或缺的一部分,而数据库连接池技术则是优化这一过程的关键。HibernateC3P0作为一款常用的开源数据库连接池,其高效、稳定的特点使得它在众多开发者中广受欢迎。本文将...
在本项目中,“java用hibernate连接数据库提取中文”是利用Hibernate框架在Eclipse集成开发环境中与Oracle数据库进行交互,以读取和处理中文数据的小程序。下面我们将详细讨论相关的知识点。 首先,我们需要了解...
在IT行业中,尤其是Java开发领域,Hibernate是一个非常重要的框架,它简化了与数据库交互的过程,提供了对象关系映射(ORM)的功能。本文将深入探讨如何在项目中使用Hibernate进行数据库连接的注册,以及相关的重要...
在实际开发中,我们通常会结合使用Spring和Hibernate,利用Spring管理数据库连接,通过Hibernate处理对象关系映射,以提高开发效率和代码的可维护性。理解并熟练掌握这些技术,对于Java开发者来说至关重要。
在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者使用面向对象的方式来操作数据库。"hibernate反向生成数据库程序"是指通过Hibernate框架,从已有的数据库结构生成对应的Java实体类和...
在软件开发过程中,特别是在进行多数据库支持的应用程序开发时,我们经常需要将同一套代码部署到不同的数据库系统上。这种情况下,手动为每个数据库创建相同的表结构既耗时又容易出错。Hibernate 提供了一个非常实用...
//该方法会立即加载/获取数据(只要调用该方法就会立即向数据库发出查询语句),该方法只在内部缓存查找数据,如果内部缓存中没有数据就直接去数据库查询,当数据库中没有要查询的数据时返回null (6).load(Class ...
在Java开发中,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者能够通过Java对象来处理数据,而无需编写大量的SQL语句。本篇文章将深入探讨Hibernate如何与各种主流数据库进行连接,...
本篇将深入探讨如何使用Hibernate进行数据库连接,以便在实际开发中更好地运用这一工具。 首先,Hibernate的核心思想是通过映射Java类到数据库表,使得开发者可以使用面向对象的方式来处理数据库操作,从而避免了...
Hibernate 提供了一种在Java应用中持久化对象的机制,它通过映射Java类到数据库表,使得开发者可以避免编写大量的JDBC代码,专注于业务逻辑。其主要特性包括对象-关系映射、缓存管理、事务处理等。 2. Hibernate ...
在深入探讨Hibernate连接数据库的基础源码之前,我们首先要理解Hibernate是什么。Hibernate是一个开源的对象关系映射(ORM)框架,它简化了Java应用程序与数据库之间的交互。通过使用Hibernate,开发者可以将业务...
Hibernate是一款强大的Java持久化框架,它简化了与关系型数据库如SQL Server的交互。通过将对象映射到数据库表,Hibernate使得开发人员可以专注于业务逻辑,而无需关注底层的SQL语句。以下是对"Hibernate操作数据库...
在Java编程中,Hibernate是一个非常流行的对象关系映射(ORM)框架,它简化了数据库操作,使开发者可以使用面向对象的方式来处理数据库事务。本教程将深入探讨Hibernate连接MySQL数据库的基础源码实现,非常适合初学...
在 Hibernate 中,所有对数据库的操作都需要在一个事务中进行。事务提供了 ACID 特性(原子性、一致性、隔离性和持久性),确保数据的一致性和完整性。没有事务的支持,任何对数据库的更改都可能造成不可预测的结果...
在Java应用程序中,Hibernate是一个非常流行的ORM(Object-Relational Mapping)框架,它提供了强大的数据库操作能力,简化了Java与关系型数据库如MySQL之间的交互。本实例将深入讲解如何使用Hibernate连接到MySQL...
Hibernate提供了一种便捷的事务管理方式,可以将多个数据库操作封装在一个Transaction中,保证原子性和一致性。 通过以上内容,我们了解了Hibernate的基本操作和核心概念。在实际项目中,可以根据需求选择合适的...
Java使用Hibernate操作数据库是现代Java应用中常见的技术实践,Hibernate作为一个强大的对象关系映射(ORM)框架,极大地简化了数据库的交互。它允许开发者用Java对象来表示数据库中的记录,而无需关心底层SQL的实现...