`
cloudtech
  • 浏览: 4721365 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

、 只要openSession一次,hibernate内部就会连接数据库一次,所以在代码中opesnSession的次数,越多效率越低

 
阅读更多

Hibernate课堂笔记

1Hibernate是什么

Hibernate是一个数据库的操作框架

1.1Jdbc的缺点

ljdbc的效率比较低

每一次请求,打开连接、发送sql语句,在数据库中解析sql语句等需要消耗大量的资源。

重复性代码特别多

每一次都需要关闭connection,statement,rs

Jdbc没有做到面向对象编程

没有做到数据缓存

现在世界上数据缓存做的很不错的框架(hibernate,oscache,ehcache)

Oscacheehcache都有页面缓存

*就是把页面上的数据缓存到本地磁盘上

*当应用程序再次访问的时候,直接从磁盘上读取数据就

可以了

*页面缓存不适合做更新特别频繁的数据

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学习hibernatecrud操作

l持久化对象的状态

l一对多和多对多(重点)

l数据缓存(一级缓存、二级缓存、查询缓存)(重点)数据缓存的特点

lHql语句

3hibernatecrud操作

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

说明:

159行的session67行的session是两个session

261行产生的classes67行产生的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

分析:因为classesstudent都是临时状态,所以应该是在保存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表的关系(外键),如果inversefalse,则维护,如果为true,则不维护

9.1.2.1案例1

分析:

1、该例子从数据库的角度分析,把sid2的值的外键修改一下就可以了

2、从hibernate的角度是修改关系

3、查看classes.hbm.xml映射文件中,classes能否修改classesstudent之间的关系。

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、一对多,用一的一方维护关系,效率比较低。当数量级别比较大的时候,会发出nupdate语句

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元素中lazyfalse

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+1sql语句/在加载classes的时候就把student的数据加载出来了/extra在这里等同于true

True/false/extra

subselect

如果检测到由子查询,则用subselect

说明:

1、如果第一页面只有一的一方的数据,然后根据超级连接才要显示多的一方的数据,这种情况用select或者subselect

2、如果页面上既有一的一方的数据也有多的一方的数据,用join是比较好的选择。

1select默认的

1、先查询班级(cid:1,2,3)

2、根据班级中的每一个cid去查相应的学生

2subselect子查询

根据需求分析先写出sql句,只要sql语句中含有子查询,那么肯定是子查询的效率比较高

3join连接

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行代码可以判断出classesstudents建立关联

映射文件:Classes.hbm.xml

总体分析:

1、把session.save(classes)这样的保存称为显示保存

2、在保存classes的同时保存student,保存student的操作是由hibernate内部完成的,我们把这样的操作称为隐式保存

3、在classes.hbm.xml文件set元素中并没有配置cascade

4、只有在客户端建立classesstudent之间的关系,然后在映射文件中再次确认关联(cascade)两个地方都配置了,级联保存才能有效

5、因为在classes.hbm.xml文件中,没有针对studentcascade,所以student对象处于临时状态,hibernate是不允许这种情况出现的

6、这个错误只有在多表的情况下才有可能产生

11.9错误九

session关闭以后还要视图从数据库中提取数据就会报这样一个错误。

解决方案:

session关闭之前把数据全部提取出来

分享到:
评论

相关推荐

    hibernate框架下对oracle数据库操作所需jar包.zip

    在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它简化了与数据库交互的过程,使得开发者可以使用面向对象的方式来操作数据库。对于Oracle数据库的支持,Hibernate提供了专门的驱动和配置,使得...

    java利用hibernate连接数据库

    Java通过Hibernate连接数据库是Java开发中的常见操作,Hibernate作为一个强大的对象关系映射(ORM)框架,极大地简化了数据库操作。本篇文章将详细讲解如何利用Hibernate在Java项目中建立数据库连接,以及提供一个...

    HibernateC3P0 数据库连接池架包.rar

    在当今的Web应用开发中,数据库连接管理是不可或缺的一部分,而数据库连接池技术则是优化这一过程的关键。HibernateC3P0作为一款常用的开源数据库连接池,其高效、稳定的特点使得它在众多开发者中广受欢迎。本文将...

    java用hibernate连接数据库提取中文

    在本项目中,“java用hibernate连接数据库提取中文”是利用Hibernate框架在Eclipse集成开发环境中与Oracle数据库进行交互,以读取和处理中文数据的小程序。下面我们将详细讨论相关的知识点。 首先,我们需要了解...

    Hibernate连接数据库的注册的项目

    在IT行业中,尤其是Java开发领域,Hibernate是一个非常重要的框架,它简化了与数据库交互的过程,提供了对象关系映射(ORM)的功能。本文将深入探讨如何在项目中使用Hibernate进行数据库连接的注册,以及相关的重要...

    java多种方式连接不同的数据库(+关键代码)总结

    在实际开发中,我们通常会结合使用Spring和Hibernate,利用Spring管理数据库连接,通过Hibernate处理对象关系映射,以提高开发效率和代码的可维护性。理解并熟练掌握这些技术,对于Java开发者来说至关重要。

    hibernate反向生成数据库程序

    在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者使用面向对象的方式来操作数据库。"hibernate反向生成数据库程序"是指通过Hibernate框架,从已有的数据库结构生成对应的Java实体类和...

    hibernate根据字段生成数据库表

    在软件开发过程中,特别是在进行多数据库支持的应用程序开发时,我们经常需要将同一套代码部署到不同的数据库系统上。这种情况下,手动为每个数据库创建相同的表结构既耗时又容易出错。Hibernate 提供了一个非常实用...

    hibernate操作数据库笔记

    //该方法会立即加载/获取数据(只要调用该方法就会立即向数据库发出查询语句),该方法只在内部缓存查找数据,如果内部缓存中没有数据就直接去数据库查询,当数据库中没有要查询的数据时返回null (6).load(Class ...

    hibernate于各大数据库的连接

    在Java开发中,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者能够通过Java对象来处理数据,而无需编写大量的SQL语句。本篇文章将深入探讨Hibernate如何与各种主流数据库进行连接,...

    Hibernate连接数据库.pdf

    本篇将深入探讨如何使用Hibernate进行数据库连接,以便在实际开发中更好地运用这一工具。 首先,Hibernate的核心思想是通过映射Java类到数据库表,使得开发者可以使用面向对象的方式来处理数据库操作,从而避免了...

    hibernate 连接数据库基础源码

    Hibernate 提供了一种在Java应用中持久化对象的机制,它通过映射Java类到数据库表,使得开发者可以避免编写大量的JDBC代码,专注于业务逻辑。其主要特性包括对象-关系映射、缓存管理、事务处理等。 2. Hibernate ...

    hibernate 连接数据库基础源码2

    在深入探讨Hibernate连接数据库的基础源码之前,我们首先要理解Hibernate是什么。Hibernate是一个开源的对象关系映射(ORM)框架,它简化了Java应用程序与数据库之间的交互。通过使用Hibernate,开发者可以将业务...

    Hibernate操作数据库的步骤

    Hibernate是一款强大的Java持久化框架,它简化了与关系型数据库如SQL Server的交互。通过将对象映射到数据库表,Hibernate使得开发人员可以专注于业务逻辑,而无需关注底层的SQL语句。以下是对"Hibernate操作数据库...

    hibernate 连接数据库基础源码3

    在Java编程中,Hibernate是一个非常流行的对象关系映射(ORM)框架,它简化了数据库操作,使开发者可以使用面向对象的方式来处理数据库事务。本教程将深入探讨Hibernate连接MySQL数据库的基础源码实现,非常适合初学...

    Hibernate数据库事务

    在 Hibernate 中,所有对数据库的操作都需要在一个事务中进行。事务提供了 ACID 特性(原子性、一致性、隔离性和持久性),确保数据的一致性和完整性。没有事务的支持,任何对数据库的更改都可能造成不可预测的结果...

    hibernate连接数据[Mysql]的代码实例

    在Java应用程序中,Hibernate是一个非常流行的ORM(Object-Relational Mapping)框架,它提供了强大的数据库操作能力,简化了Java与关系型数据库如MySQL之间的交互。本实例将深入讲解如何使用Hibernate连接到MySQL...

    基于hibernate的简单数据库实现

    Hibernate提供了一种便捷的事务管理方式,可以将多个数据库操作封装在一个Transaction中,保证原子性和一致性。 通过以上内容,我们了解了Hibernate的基本操作和核心概念。在实际项目中,可以根据需求选择合适的...

    java使用hibernate操作数据库jar

    Java使用Hibernate操作数据库是现代Java应用中常见的技术实践,Hibernate作为一个强大的对象关系映射(ORM)框架,极大地简化了数据库的交互。它允许开发者用Java对象来表示数据库中的记录,而无需关心底层SQL的实现...

Global site tag (gtag.js) - Google Analytics