添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
【干货】Hibernate基础入门

【干货】Hibernate基础入门

0.Hibernate基础

0.1、什么是hibernate

hibernate是免费开源的框架,是一个OR-Mapping映射工具, 将实体类和数据库表形成映射关系,是一个优秀的持久层解决方案,hibernate对jdbc进行了封装,我们不需要再关心底层实现,只需要关系具体的业务实现即可。

hibernate核心类和接口

Configuration类: 加载hibernate.cfg.xml配置文件

SessionFactory接口:会话工厂,可以得到会话

Session接口: 会话,操作CRUD增删改查

Transaction接口: 事务,开启事务,提交事务,关闭事务

0.2、hibernate工作原理

通过Configuration对象加载hibernate.cfg.xml配置文件,

hibernate.cfg.xml配置文件主要管理数据库连接相关信息与实体类和数据库表的映射关系,所以当加载hibernate.cfg.xml配置文件的时候把实体类和数据库表之间建立了映射关系,然后调用buildSessionFactory()方法得到数据库连接的会话工厂sessionFactory,再通过会话工厂得到session会话,通过session会话开启事务,然后执行CRUD操作,再进行事务提交,最后关闭session会话。

0.3、为什么要用hibernate

hibernate是一个优秀的持久层解决方案,提供了标准化模版,能够为开发人员提高开发效率。

0.4、hibernate和jdbc的区别

查询效率:jdbc因为直接操作数据库,所以查询效率相比hibernate要高,

hibernate要对实体类和数据库表字段之间做映射关系的维护,所以查询效率相对来说要低。

开发效率:jdbc相当于手动式,SQL代码和封装都需要手动完成,而hibernate相当于自动化,由于对jdbc进行封装,所以底层代码不需要开发人员编写,所以开发效率hibernate要高。

0.5、Hibernate和MyBatis的区别?

1.Hibernate是全自动的ORM框架 而MyBatis是半自动的ORM框架

2.MyBatis 是一个基于DAO层处理的ORM框架 SQL语句和实体映射

Hibernate 是一个基于DAO层处理的ORM框架 表和实体的映射

3.Hibernate是一个重量级框架 适用于大中型项目

MyBatis是一个轻量级框架 适用于中小型项目 尤其是当下的互联网项目

4.Hibernate封装的比较好,而MyBatis比较灵活

1.引入dtd文件 提供配置文件自动提示功能

1.1:在hibernate3.jar解压 org.hibernate下面找dtd文件

1.2:在window-perferences-xml catalog下配置dtd

指定key和dtd文件对应

2.搭建Hibernate开发环境

2.1.导入jar包

hibernate3.jar和required下面的jar包

2.2.编写Hibernate配置文件 hibernate.cfg.xml

<hibernate-configuration>

<!-- 配置数据库连接信息 -->

<session-factory>

<!-- 配置数据库驱动 -->

<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

<!-- 配置数据库连接URL -->

<property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>

<!-- 配置用户名 -->

<property name="connection.username">system</property>

<!-- 配置密码 -->

<property name="connection.password">accp</property>

<!-- 方言 -->

<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>

<!-- Session上下文 -->

<property name="current_session_context_class">thread</property>

<!-- 配置日志 输出sql语句 -->

<property name="show_sql">true</property>

<!-- 配置日志 对输出的sql语句进行格式化处理 -->

<property name="format_sql">true</property>

<mapping resource="com/kawa/pojo/user.hbm.xml"/>

</session-factory>

</hibernate-configuration>

2.3.编写user.hbm.xml映射文件

<hibernate-mapping>

<class name="com.kawa.pojo.User" table="users">

<id column="id" name="id" type="java.lang.Integer"></id>

<property column="name" name="name" type="java.lang.String"></property>

<property column="pwd" name="pwd" type="java.lang.String"></property>

</class>

</hibernate-mapping>

2.4.测试

public void addUser(){

//1.获取Session对象

Configuration config = new Configuration().configure();

SessionFactory sessionFactory = config.buildSessionFactory();

Session session = sessionFactory.openSession();

//开启事务

Transaction tran = session.beginTransaction();

User user = new User();

user.setId(3);

user.setName("Marry");

user.setPwd("123456");

try {

//2.通过Session对象执行操作

session.save(user);

tran.commit();

System.out.println("数据插入成功!");

} catch (HibernateException e) {

// TODO Auto-generated catch block

e.printStackTrace();

tran.rollback();

}

//3.关闭Session对象

session.close();

}

2.5.注意

1.不要忘记在hibernate.cfg.xml中引入xxx.hbm.xml映射文件

2.在进行数据库增删改时不要忘记开启事务 成功提交事务,失败回滚事务

3.不要忘记导入slf4j.jar的log4j实现jar包 以及log4j.jar

2.6.常见问题

1.Hibernate无法连接Oracle数据库

Oracle数据库自身配置出现问题 .ora

2.使用Hibernate3.6.1

关闭Hibernate自动开启的验证 加上一句配置

<property name="javax.persistence.validation.mode">none</property>

3.使用MyEclipse搭建开发环境

1.配置数据库连接模板

2.创建web项目 添加hibernate支持

帮助我们将hibernate jar包导入到项目中,以及生成hibernate.cfg.xml配置文件

3.通过DB browser使用hibernate反向生成 通过表生成pojo实体类以及hbm.xml映射文件

在生成以上这些的同时还可以帮我们生成HibernateSessionFactory工具类

4.测试

4.主键生成策略

常用主键的生成策略如下:

4.1.increment: 对类型为long short 或 int的主键,以自动增长的方式生成主键的值。主键按数值顺序递增,增量为1.

4.2.identity: 对如SQLServer、DB2、MySQL等支持标识列的数据库,课使用该主键生成策略生成自动增长主键,但要在数据库中将该主键设置为标识列。

4.3.sequence: 对如Oracle、DB2等支持序列的数据库,可使用该主键生成策略生成自动增长主键,通过子元素param传入数据库中序列的名称。

4.4.native: 由Hibernate根据底层数据库自行判断采用何种主键生成策略,即由使用的数据库生成主键的值。

4.5.assigned: 主键由应用程序负责生成,无需Hibernate参与

5.Code Frist思想

代码第一,先有代码后有数据库 ,可以使用hibernate利用pojo和hbm.xml去生成数据库表

实现:在hibernate.cfg.xml中加入<property name="hibernate.hbm2ddl.auto">update</property>

6.主键查询

get查询和load查询的区别?

get: session.get(Users.class, new Short("4"));

load:session.load(Users.class, new Short("4"));

区别:

1.get查询不到数据会返回null 而load查询不到会抛出异常ObjectNotFoundException

2.hibernate默认使用懒加载,在缓存中不存在查询数据时,get会直接到数据库中查找,而load不会,

load只会产生一个代理对象,只有在其后进行除get之外的其他操作才会真正的查询数据库

7.Hibernate中java对象的三种状态

Hibernate框架通过Session来管理Java对象的状态

瞬时状态 new对象/delete

通过new创建对象后,没有存储到数据库,此时java对象的状态为瞬时状态。

持久状态 get、load/save/update

当对象与Session关联,被Session管理时,他就处于持久状态。

对象与Session关联:

1.通过Session查询接口,或者get()|load()

2.通过调用Session的save()|SaveOrUpdate()

游离状态 evict、clear、close

处于持久状态的对象,脱离与其关联的Session管理后,对象就处于游离状态。

Session提供两个方法(update() merge())将处于游离状态的对象与一个新的Session发生关联

8.三种状态之间的转换

8.1.瞬时状态转换为持久状态

使用Session对象的save()或saveOrUpdate()方法保存对象后,该对象的状态由瞬时状态转换为持久状态

使用Session对象的get()或load()方法获取对象,该对象的状态是持久状态

8.2.持久状态转换为瞬时状态

执行Session对象的delete()方法后,对象由原来的持久状态变为瞬时状态,因为此时该对象没有与任何的数据库数据关联

8.3.持久状态转为游离状态

执行了Session对象的evict()、clear()或close()方法,对象由原来的持久状态转为游离状态

8.4.游离状态转为持久状态

重新获取Session对象,执行Session对象的update()或saveOrUpdate()方法,对象由游离状态转为持久状态,该对象再次与Session对象关联

8.5.游离状态转为瞬时状态

执行Session对象的delete()方法,对象由游离状态转为瞬时状态。

处于瞬时状态或游离状态的对象不再被其他对象引用时,会被Java虚拟机安装垃圾回收机制处理。

9.脏检查和刷新缓存

脏检查: session中的对象信息与数据库不一致

刷新缓存: 解决session中的对象信息与数据库不一致的情况

实现:flush()、commit()

Session是Hibernate向应用程序提供的操纵数据库的主要接口,它提供了基本的保存、更新、删除和加载Java对象的方法。Session具有一个缓存,可以管理和跟踪所有持久化对象,对象和数据库中的相关记录对应。在某些时间点,Session会根据缓存中对象的变化来执行相关SQL语句,将对象包含的编号数据更新到数据库中,这一过程称为刷新缓存,换句话说就是将Session缓存同步刷新为与数据库一致。

1.脏检查

在Hibernate中,状态前后发生变化的对象,称为脏对象。

当事务提交时,Hibernate会对Session中持久状态的对象进行检测,判断对象的数据时候发生了改变,这种判断称为脏检查。

Hibernate为什么要进行脏检查呢?

因为如果对象发生了改变,就需要将改变更新到数据库中,以确保内存中的对象与数据库中的数据保持一致。

Session是如何进行脏检查的呢?

当一个Dept对象被加入到Session缓存中时,Session会为Dept对象的值类型的属性复制一份快照。当Session刷新缓存是,会先进行脏检查,即比较Dept对象的当前属性与它的快照,来判断Dept对象的属性是否发生了变化。如果发生了变化,Session会根据脏对象的最新属性值来执行相关的SQL语句,将变化更新到数据库中。

2.刷新缓存机制

当Session缓存中对象的属性每次发生变化时,Session并不会立即刷新缓存和执行相关的SQL语句,而是在特定的时间点才刷新缓存。这使得Session能够把几条相关的SQL语句合并为一条或者一批SQL语句,减少了访问数据库的次数,从而提高应用程序的数据访问性能。

Session在何时刷新缓存呢?

1 .当应用程序调用Transcation的commit()方法时 ,commit()方法先调用Session的刷新缓存方法flush(),然后向数据库提交事务。Hibernate之所以把刷新缓存时间点安排在事务快结束时,一方面是因为可以减少访问数据库的频率,林一方面是因为可以尽可能缩短当前事务对数据库中相关资源的锁定时间。

2. 当应用程序显示调用Session的flush()方法时 ,刷新缓存。

Session的flush()方法和Transaction的commit()方法的区别?

flush()方法进行刷新缓存的操作,执行一系列的SQL语句,但不会提交事务;commit()方法会先调用flush()方法,然后提交事务。提交事务意味着对数据库所做的更新被永久保存下来。

10.sava、update、savaOrUpdate、merge的区别?

save() 方法用于将一个临时对象转变为持久化对象,也就是将一个新的业务实体保存到数据库中;

update() 方法用于将一个游离对象重新转变为持久化对象,也就是更新一个已经存在的业务实体到数据库中;

saveOrUpdate() 兼具了save()和update()方法的功能,该方法根据传入参数的状态执行不同的操作,当为临时状态时,调用save()方法;当为持久化状态时,则直接返回;当为游离状态时,调用update()方法。

merge() 方法主要用于更新和保存实体,当实体不存在时,则执行保存操作,当实体已经存在时,执行更新操作,其实同saveOrUpdate()的功能是类似的。

10.1. update 和 merge的区别

首先在执行更新操作的时候,两者都必须要有id

update是直接执行update 语句,执行后状态为持久化状态

而merge则不一样:

1. 如果session中有与之对应的对象,也就是主键相同,则会把要保存的obj的值copy给session中的对象,然后update被复制后的session中的对象

2. 如果session中没有,则会先从数据库中select,然后把obj给查出来的对象copy,则update查出来的对象。

3. 所以merge会先select 再update

4. 所以merge后原来的对象状态为游离。

10.2、save 和update区别

把这一对放在第一位的原因是因为这一对是最常用的。

save的作用是把一个新的对象保存

update是把一个脱管状态的对象或自由态对象(一定要和一个记录对应)更新到数据库

10.3、update 和saveOrUpdate区别

这个是比较好理解的,顾名思义,saveOrUpdate基本上就是合成了save和update,而update只是update;引用hibernate reference中的一段话来解释他们的使用场合和区别

通常下面的场景会使用update()或saveOrUpdate():

程序在第一个session中加载对象,接着把session关闭

该对象被传递到表现层

对象发生了一些改动

该对象被返回到业务逻辑层最终到持久层

程序创建第二session调用第二个session的update()方法持久这些改动

saveOrUpdate(po)做下面的事:

如果该po对象已经在本session中持久化了,在本session中执行saveOrUpdate不做任何事

如果savaOrUpdate(新po)与另一个与本session关联的po对象拥有相同的持久化标识(identifier),抛出一个异常

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.itfuture.www.po.Xtyhb#5]

saveOrUpdate如果对象没有持久化标识(identifier)属性,对其调用save() ,否则update() 这个对象

(如果我分享的干货内容对你有帮助,可以通过赞或者评论的方式告诉我,我会持续分享大家感兴趣的IT干货)
发布于 2020-02-14 23:29