Hibernater学习笔记

简介

Hibernate 将 Java 类映射到数据库表中,从 Java 数据类型中映射到 SQL 数据类型中,并把开发人员从 95% 的公共数据持续性编程工作中解放出来。Hibernate 是传统 Java 对象和数据库服务器之间的桥梁,用来处理基于 O/R 映射机制和模式的那些对象。如下图所示:
在这里插入图片描述

Hibernate 优势
  • Hibernate 使用 XML 文件来处理映射 Java 类别到数据库表格中,并且不用编写任何代码。
  • 为在数据库中直接储存和检索 Java 对象提供简单的 APIs。
  • 如果在数据库中或任何其它表格中出现变化,那么仅需要改变 XML 文件属性。
  • 抽象不熟悉的 SQL 类型,并为我们提供工作中所熟悉的 Java 对象。
  • Hibernate 不需要应用程序服务器来操作。
  • 操控你数据库中对象复杂的关联。
  • 最小化与访问数据库的智能提取策略。
  • 提供简单的数据询问。
  • 更换数据库简单,与数据库引擎耦合度不高。
Hibernate 劣势
  • 做太复杂的查询很不方便。
  • 不写或是少写SQL语句,是优点也是缺点,优点是方便等,缺点调优或是改写SQL不便。
  • 就现在而言,学习成本相对比较高。
  • 全自动也要也要付出相应的维护代价,mybatis半自动前期麻烦,后期维护简单。
总结:

现在企业的情况是国内mybatis用的比hibernater多,国外相反。但hibernater也比mybatis自动、安全,选哪个学好呢,俩字:都学!

Hibernate 架构

Hibernate 架构是分层的,作为数据访问层,你不必知道底层 API 。Hibernate 利用数据库以及配置数据来为应用程序提供持续性服务(以及持续性对象)。
下面是一个非常高水平的 Hibernate 应用程序架构视图。
在这里插入图片描述
下面是一个详细的 Hibernate 应用程序体系结构视图以及一些重要的类。
在这里插入图片描述
Hibernate 使用不同的现存 Java API,比如 JDBC,Java 事务 API(JTA),以及 Java 命名和目录界面(JNDI)。JDBC 提供了一个基本的抽象级别的通用关系数据库的功能, Hibernate 支持几乎所有带有 JDBC 驱动的数据库。JNDI 和 JTA 允许 Hibernate 与 J2EE 应用程序服务器相集成。

配置对象

配置对象是你在任何 Hibernate 应用程序中创造的第一个 Hibernate 对象,并且经常只在应用程序初始化期间创造。它代表了 Hibernate 所需一个配置或属性文件。配置对象提供了两种基础组件。

  • 数据库连接:由 Hibernate 支持的一个或多个配置文件处理。这些文件是 hibernate.properties 和 hibernate.cfg.xml。
  • 类映射设置:这个组件创造了 Java 类和数据库表格之间的联系。
SessionFactory 对象

配置对象被用于创造一个 SessionFactory 对象,使用提供的配置文件为应用程序依次配置 Hibernate,并允许实例化一个会话对象。SessionFactory 是一个线程安全对象并由应用程序所有的线程所使用。

Session 对象

一个会话被用于与数据库的物理连接。Session 对象是轻量级的,并被设计为每次实例化都需要与数据库的交互。持久对象通过 Session 对象保存和检索。

Transaction 对象

一个事务代表了与数据库工作的一个单元并且大部分 RDBMS 支持事务功能。在 Hibernate 中事务由底层事务管理器和事务(来自 JDBC 或者 JTA)处理。这是一个选择性对象,Hibernate 应用程序可能不选择使用这个接口,而是在自己应用程序代码中管理事务。

Query 对象

Query 对象使用 SQL 或者 Hibernate 查询语言(HQL)字符串在数据库中来检索数据并创造对象。一个查询的实例被用于连结查询参数,限制由查询返回的结果数量,并最终执行查询。

Criteria 对象

Criteria 对象被用于创造和执行面向规则查询的对象来检索对象。

Hibernate 配置

Hibernate 需要事先知道在哪里找到映射信息,这些映射信息定义了 Java 类怎样关联到数据库表。Hibernate 也需要一套相关数据库和其它相关参数的配置设置。所有这些信息通常是作为一个标准的 Java 属性文件提供的,名叫 hibernate.properties。又或者是作为 XML 文件提供的,名叫 hibernate.cfg.xml。在与SpringBoot结合时,可以直接写在application.properties中。

常见数据库配置

在这里插入图片描述

Session 接口方法

Session 接口提供了很多方法,以下是常用方法。
在这里插入图片描述
在这里插入图片描述

Hibernate 持久化类

Hibernate 的完整概念是提取 Java 类属性中的值,并且将它们保存到数据库表单中。映射文件能够帮助 Hibernate 确定如何从该类中提取值,并将它们映射在表格和相关域中
以下所列就是持久化类的主要规则,但没有一条是硬性要求。

  • 所有将被持久化的 Java 类都需要一个默认的构造函数。
  • 为了使对象能够在 Hibernate 和数据库中容易识别,所有类都需要包含一个 ID。此属性映射到数据库表的主键列。
  • 所有将被持久化的属性都应该声明为 private,并具有由 JavaBean 风格定义的 getXXX 和 setXXX 方法。
  • Hibernate 的一个重要特征为代理,它取决于该持久化类是处于非 final 的,还是处于一个所有方法都声明为 public 的接口。
  • 所有的类是不可扩展或按 EJB 要求实现的一些特殊的类和接口。

Hibernate 映射文件

一个对象/关系型映射一般定义在 XML 文件中。映射文件指示 Hibernate 如何将已经定义的类或类组与数据库中的表对应起来。
注:以前的开发喜欢用XML映射文件,但配置太多显得太杂乱无章了,所以现在大多用注解的方式代替XML文件。

Hibernate 映射类型

当你准备一个 Hibernate 映射文件时,我们已经看到你把 Java 数据类型映射到了 RDBMS 数据格式。在映射文件中已经声明被使用的 types 不是 Java 数据类型;它们也不是 SQL 数据库类型。这种类型被称为 Hibernate 映射类型,可以从 Java 翻译成 SQL,反之亦然。

原始类型

在这里插入图片描述

日期和时间类型

在这里插入图片描述

二进制和大型数据对象

在这里插入图片描述

JDK 相关类型

在这里插入图片描述

Hibernate O/R 映射

O/R 映射还有三个更加重要的有关映射。这三个话题是集合的映射实体类的关联映射以及组件映射

集合映射

如果一个实例或者类中有特定变量的值的集合,那么我们可以应用 Java 中的任何的可用的接口来映射这些值。Hibernate 可以保存 java.util.Map, java.util.Set, java.util.SortedMap, java.util.SortedSet, java.util.List 和其它持续的实例或者值的任何数组的实例。
在这里插入图片描述

关联映射

实体类之间的关联映射以及表之间的关系是 ORM 的灵魂之处。对象间的关系的子集可以用下列四种方式解释。关联映射可以是单向的也可以是双向的。
在这里插入图片描述

组件映射

作为变量的一员实体类很可能和其它类具有相关关系。如果引用的类没有自己的生命周期并且完全依靠于拥有它的那个实体类的生命周期的话,那么这个引用类因此就可以叫做组件类。组件集合的映射很可能和正常集合的映射相似,只会有很少的设置上的不同。
在这里插入图片描述

Hibernate注解

Hibernate 注释是一种强大的来给对象和关系映射表提供元数据的方法。所有的元数据被添加到 POJO java 文件代码中,这有利于用户在开发时更好的理解表的结构和 POJO。你可以额外使用注解或直接代替 XML 映射元数据。

@Entity 注释

@Entity 标志着这个类为一个实体 bean,所以它必须含有一个没有参数的构造函数并且在可保护范围是可见的。

@Table 注释

@table 注释允许您明确表的详细信息保证实体在数据库中持续存在

@Id 和 @GeneratedValue 注释

每一个实体 bean 都有一个主键,你在类中可以用 @Id 来进行注释。主键可以是一个字段或者是多个字段的组合,这取决于你的表的结构。

@Column

@Column 注释用于指定某一列与某一个字段或是属性映射的细节信息。您可以使用下列注释的最常用的属性:

  • name 属性允许显式地指定列的名称。
  • length 属性为用于映射一个值,特别为一个字符串值的列的大小。
  • nullable 属性允许当生成模式时,一个列可以被标记为非空。
  • unique 属性允许列中只能含有唯一的内容

Hibernate 查询语言

Hibernate 查询语言(HQL)是一种面向对象的查询语言,类似于 SQL,但不是去对表和列进行操作,而是面向对象和它们的属性。 HQL 查询被 Hibernate 翻译为传统的 SQL 查询从而对数据库进行操作。
尽管你能直接使用本地 SQL 语句,但我还是建议你尽可能的使用 HQL 语句,以避免数据库关于可移植性的麻烦,并且体现了 Hibernate 的 SQL 生成和缓存策略。
在 HQL 中一些关键字比如 SELECT ,FROM 和 WHERE 等,是不区分大小写的,但是一些属性比如表名和列名是区分大小写的。

FROM 语句

如果你想要在存储中加载一个完整并持久的对象,你将使用 FROM 语句。

Query query = session.createQuery("FROM Employee");

或完全限定类名

Query query = session.createQuery("FROM com.hibernatebook.criteria.Employee");
AS 语句

在 HQL 中 AS 语句能够用来给你的类分配别名,尤其是在长查询的情况下。

Query query = session.createQuery("FROM Employee AS E");
SELECT 语句

SELECT 语句比 from 语句提供了更多的对结果集的控制。如果你只想得到对象的几个属性而不是整个对象你需要使用 SELECT 语句。

Query query = session.createQuery("SELECT E.firstName FROM Employee E");
WHERE 语句

如果你想要精确地从数据库存储中返回特定对象,你需要使用 WHERE 语句。

Query query = session.createQuery("FROM Employee E WHERE E.id = 10");
ORDER BY 语句

为了给 HSQ 查询结果进行排序,你将需要使用 ORDER BY 语句。你能利用任意一个属性给你的结果进行排序,包括升序或降序排序。

Query query = session.createQuery("FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC");
GROUP BY 语句

这一语句允许 Hibernate 将信息从数据库中提取出来,并且基于某种属性的值将信息进行编组,通常而言,该语句会使用得到的结果来包含一个聚合值。

Query query = session.createQuery("SELECT SUM(E.salary), E.firtName FROM Employee E GROUP BY E.firstName");
使用命名参数

Hibernate 的 HQL 查询功能支持命名参数。这使得 HQL 查询功能既能接受来自用户的简单输入,又无需防御 SQL 注入攻击。

Query query = session.createQuery("FROM Employee E WHERE E.id = :employee_id");
query.setParameter("employee_id",10);
UPDATE 语句

HQL Hibernate 3 较 HQL Hibernate 2,新增了批量更新功能和选择性删除工作的功能。查询接口包含一个 executeUpdate() 方法,可以执行 HQL 的 UPDATE 或 DELETE 语句。
UPDATE 语句能够更新一个或多个对象的一个或多个属性。

Query query = session.createQuery("UPDATE Employee set salary = :salary WHERE id = :employee_id");
query.setParameter("salary", 1000);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
DELETE 语句

DELETE 语句可以用来删除一个或多个对象。
Query query = session.createQuery(“DELETE FROM Employee WHERE id = :employee_id”);
query.setParameter(“employee_id”, 10);
int result = query.executeUpdate();

INSERT 语句

HQL 只有当记录从一个对象插入到另一个对象时才支持 INSERT INTO 语句。

String hql = "INSERT INTO Employee(firstName, lastName, salary) SELECT firstName, lastName, salary FROM old_employee";
Query query = session.createQuery(hql);
int result = query.executeUpdate();
聚合方法

HQL 类似于 SQL,支持一系列的聚合方法,它们以同样的方式在 HQL 和 SQL 中工作,以下列出了几种可用方法:
在这里插入图片描述

使用分页查询

以下为两种分页查询界面的方法:
在这里插入图片描述
每次取 10 行

String hql = "FROM Employee";
Query query = session.createQuery(hql);
query.setFirstResult(1);
query.setMaxResults(10);
List results = query.list();

Hibernate 原生 SQL

如果你想使用数据库特定的功能如查询提示或 Oracle 中的 CONNECT 关键字的话,你可以使用原生 SQL 数据库来表达查询。Hibernate 3.x 允许您为所有的创建,更新,删除,和加载操作指定手写 SQL ,包括存储过程。

标量查询

最基本的 SQL 查询是从一个或多个列表中获取一个标量(值)列表。

SQLQuery query = session.createSQLQuery(SELECT first_name, salary FROM EMPLOYEE);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List results = query.list();
实体查询

以上的查询都是关于返回标量值的查询,只是基础性地返回结果集中的“原始”值。

SQLQuery query = session.createSQLQuery("SELECT * FROM EMPLOYEE");
query.addEntity(Employee.class);
指定 SQL 查询

以下是从原生 SQL 查询中通过 addEntity() 方法和使用指定 SQL 查询来获取实体对象整体的语法

SQLQuery query = session.createSQLQuery("SELECT * FROM EMPLOYEE WHERE id = :employee_id");
query.addEntity(Employee.class);
query.setParameter("employee_id", 10);
List results = query.list();

Hibernate 缓存

缓存是关于应用程序性能的优化,降低了应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。Hibernate 有两级缓存。
在这里插入图片描述

一级缓存

第一级缓存是 Session 缓存并且是一种强制性的缓存,所有的要求都必须通过它。Session 对象在它自己的权利之下,在将它提交给数据库之前保存一个对象。
如果你对一个对象发出多个更新,Hibernate 会尝试尽可能长地延迟更新来减少发出的 SQL 更新语句的数目。如果你关闭 session,所有缓存的对象丢失,或是存留,或是在数据库中被更新。

二级缓存

第二级缓存是一种可选择的缓存,在询问第二级缓存之前总是先询问第一级缓存。第二级缓存可以在每一个类和每一个集合的基础上被安装,并且它主要负责跨会话缓存对象。
Hibernate 使用默认的一级缓存并且你不用使用一级缓存。让我们直接看向可选的二级缓存。不是所有的类从缓存中获益,所以能关闭二级缓存是重要的。
Hibernate 的二级缓存通过两步设置。第一,你必须决定好使用哪个并发策略。之后,你使用缓存提供程序来配置缓存到期时间和物理缓存属性。

并发策略

一个并发策略是一个中介,它负责保存缓存中的数据项和从缓存中检索它们。如果你将使用一个二级缓存,你必须决定,对于每一个持久类和集合,使用哪一个并发策略。

  • Transactional:为主读数据使用这个策略,在一次更新的罕见状况下并发事务阻止过期数据是关键的。
  • Read-write:为主读数据再一次使用这个策略,在一次更新的罕见状况下并发事务阻止过期数据是关键的。
  • Nonstrict-read-write:这个策略不保证缓存和数据库之间的一致性。如果数据几乎不改变并且过期数据不是很重要,使用这个策略。
  • Read-only:一个适合永不改变数据的并发策略。只为参考数据使用它。

Hibernate 拦截器

在 Hibernate 中,一个对象将被创建和保持。一旦对象已经被修改,它必须被保存到数据库里。这个过程持续直到下一次对象被需要,它将被从持久的存储中加载。因此一个对象通过它生命周期中的不同阶段,并且 Interceptor 接口提供了在不同阶段能被调用来进行一些所需要的任务的方法。这些方法是从会话到应用程序的回调函数,允许应用程序检查或操作一个持续对象的属性,在它被保存,更新,删除或上传之前。以下是在 Interceptor 接口中可用的所有方法的列表。
在这里插入图片描述
Hibernate 拦截器给予了我们一个对象如何应用到应用程序和数据库的总控制。

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小夏陌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值