Hibernate框架
Hibernate框架简化了java应用程序与数据库交互的开发。 Hibernate是一个开源,轻量级的ORM(对象关系映射)工具。
ORM工具简化了数据创建,数据处理和数据访问。它是将对象映射到数据库中存储的数据(表)的编程技术。
ORM工具内部使用JDBC API与数据库进行交互。
Hibernate框架有很多优点。它们分别如下:
- 开源和轻量级: Hibernate框架是根据LGPL许可证和轻量级的开源工具。
- 快速性能: Hibernate框架的性能很快,因为缓存在Hibernate框架内部使用。 hibernate框架中有两种类型的缓存:一级缓存和二级缓存。一级缓存默认是启用的。
- 数据库独立查询: HQL(Hibernate查询语言)是面向对象的SQL版本。 它生成数据库独立查询。 所以你不需要编写数据库特定的查询语句。 在Hibernate之前,如果项目更改了数据库,我们需要更改SQL查询,从而导致维护变得非常复杂。
- 自动创建表: Hibernate框架提供了自动创建数据库表的功能。 因此,无需手动在数据库中创建表。
- 简化复杂连接: 在hibernate框架中可轻松获取多个表中的数据。
- 提供查询统计和数据库状态: Hibernate支持查询缓存,并提供有关查询和数据库状态的统计信息。
Hibernate架构包括许多对象持久对象,会话工厂,事务工厂,连接工厂,会话,事务等。
hibernate架构中有4
层Java应用层,hibernate框架层,反手api层和数据库层。请参见hibernate架构图:
这是Hibernate的高级架构,具有映射文件和配置文件。
Hibernate框架使用许多对象会话工厂,会话,事务等以及现有的Java API,如JDBC(Java数据库连接),JTA(Java事务API)和JNDI(Java命名目录接口)。
Hibernate体系结构的要素
要创建第一个hibernate应用程序,我们必须知道Hibernate架构的元素。 它们如下:
会话工厂(SessionFactory)
SessionFactory
是ConnectionProvider
的会话和客户端工厂。 它拥有数据的二级缓存(可选)。 org.hibernate.SessionFactory
接口提供了工厂方法来获取Session
的对象。
会话(Session)
Session对象提供应用程序和存储在数据库中的数据之间的接口。 它是一个短生命周期的对象并包装JDBC连接。 它是事务,查询和标准的工厂。 它拥有一级缓存(强制性)数据。 org.hibernate.Session
接口提供插入,更新和删除对象的方法。 它还提供了事务,查询和标准的工厂方法。
事务(Transaction)
事务对象指定工作的原子单位,它是一个可选项。 org.hibernate.Transaction
接口提供事务管理的方法。
连接提供者(ConnectionProvider)
它是一个JDBC连接工厂。 它从DriverManager
或DataSource
抽象出来的应用程序。 它是一个可选项。
事务工厂(TransactionFactory)
它是一个事务工厂,是一个可选项。
创建持久化类的映射文件
在这里,我们正在创建与上一主题中创建的相同的映射文件。 要创建映射文件,右键单击src
-> new
-> file
-> 指定文件名(例如employee.hbm.xml
) , 它必须在包外部。
employee.hbm.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.yiibai.mypackage.Employee" table="emp1000">
<id name="id">
<generator class="assigned"></generator>
</id>
<property name="firstName"></property>
<property name="lastName"></property>
</class>
</hibernate-mapping>
创建配置文件
配置文件包含数据库的所有信息,如:connection_url
,driver_class
,username
,password
等。hbm2ddl.auto属性用于自动在数据库中创建表。 我们将在下一个主题中深入学习Dialect
类。 要创建配置文件,请右键单击src
-> new
-> file
。 现在指定配置文件名,例如: hibernate.cfg.xml
。
hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="show_sql">true</property>
<mapping resource="employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
创建检索或存储持久对象的类
在这个类中,我们只是将employee
对象存储到数据库中。
package com.yiibai.mypackage;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class StoreData {
public static void main(String[] args) {
//creating configuration object
Configuration cfg=new Configuration();
cfg.configure("hibernate.cfg.xml");//populates the data of the configuration file
//creating seession factory object
SessionFactory factory=cfg.buildSessionFactory();
//creating session object
Session session=factory.openSession();
//creating transaction object
Transaction t=session.beginTransaction();
Employee e1=new Employee();
e1.setId(100);
e1.setFirstName("Max");
e1.setLastName("Su");
session.persist(e1);//persisting the object
t.commit();//transaction is committed
session.close();
System.out.println("successfully saved");
}
}
CREATE TABLE `tb_employee` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`firstName` varchar(32) NOT NULL DEFAULT '',
`lastName` varchar(32) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8;
Employee.java
package com.yiibai.mypackage;
public class Employee {
private int id;
private String firstName,lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Hibernate使用注释
可以使用注释创建hibernate应用程序。 有许多注释可用于创建hibernate应用程序,如@Entity,@Id,@Table等。
完整的 pom.xml 配置/声明如下所示Hibernate注释基于JPA 2规范,并支持所有功能。
所有JPA注释都在javax.persistence.*
包中定义。 Hibernate EntityManager实现由JPA规范定义的接口和生命周期。
使用hibernate注释的核心优点是我们不需要创建映射(*.hbm.xml
)文件直接创建对象关联。 在这里,hibernate注释用于提供元数据。
创建持久化类
在这里,我们创建一个持久化类: Employee
。 并使用注释完成与数据库表:tb_employee
的映射关联。
@Entity
注释将此类标记为实体。@Table
注释指定要保留此实体的数据的表名。 如果不使用@Table
注释,hibernate将使用类名作为表名称bydefault
。@Id
注释标记此实体的标识符。@Column
注释指定此属性或字段的列的详细信息。如果未指定@Column
注释,则属性名称将用作列名称bydefault
。
Employee.java 文件的代码如下 -
package com.yiibai;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "tb_employee")
public class Employee {
@Id
private int id;
private String firstName, lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
在配置文件中添加持久化类的映射
打开hibernate.cfg.xml
文件,并添加如下的映射资源条目:
<mapping class="com.yiibai.Employee"/>
现在完整的配置文件: hibernate.cfg.xml
,将如下所示:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping class="com.yiibai.Employee"/>
</session-factory>
</hibernate-configuration>
创建检索或存储持久对象的类
在这个类中,我们只是将Employee
类的对象存储到数据库中。 在这里,我们使用StandardServiceRegistryBuilder
类和MetadataSources
类从持久化类获取映射的信息。
Test.java
测试类代码如下 -
package com.yiibai;
import org.hibernate.*;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.*;
public class Test {
public static void main(String[] args) {
//Session session = new AnnotationConfiguration().configure().buildSessionFactory().openSession();
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml")
.build();
// 2. 根据服务注册类创建一个元数据资源集,同时构建元数据并生成应用一般唯一的的session工厂
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
/**** 上面是配置准备,下面开始我们的数据库操作 ******/
Session session = sessionFactory.openSession();// 从会话工厂获取一个session
Transaction t = session.beginTransaction();
Employee e1 = new Employee();
e1.setId(1001);
e1.setFirstName("Yii");
e1.setLastName("Bai");
Employee e2 = new Employee();
e2.setId(1002);
e2.setFirstName("Min");
e2.setLastName("Su");
session.persist(e1);
session.persist(e2);
t.commit();
session.close();
System.out.println("successfully saved");
}
}
在pom.xml
中,需要声明使用Hibernate 5
库,以及用于各种数据库类型(如Oracle,MySQL和SQL Server)的JDBC库,这里使用 MySQL JDBC。
完整的 pom.xml 配置/声明如下所示 -
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yiibai</groupId>
<artifactId>HibernateQuickStart</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>HibernateQuickStart</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Hibernate Core -->
<!-- http://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.2.Final</version>
</dependency>
<!-- MySQL JDBC driver -->
<!-- http://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<!-- SQLServer JDBC driver (JTDS) -->
<!-- http://mvnrepository.com/artifact/net.sourceforge.jtds/jtds -->
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
</project>
案例代码:https://www.yiibai.com/hibernate/hibernate-quick-guide.html
配置hibernate
配置hibernate目的是让Hibernate可以连接数据库并与数据库交互,并声明在前面的步骤中创建的实体列表。
在src/main/java中创建一个名称为:hibernate.cfg.xml 的配置文件,当前项目结构如下图所示 -
hibernate.cfg.xml 配置文件的内容如下所示 -
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping class="com.yiibai.entities.Department" />
<mapping class="com.yiibai.entities.Employee" />
<mapping class="com.yiibai.entities.SalaryGrade" />
<mapping class="com.yiibai.entities.Timekeeper" />
</session-factory>
</hibernate-configuration>
// 在5.1.0版本汇总,hibernate则采用如下新方式获取:
// 1. 配置类型安全的准服务注册类,这是当前应用的单例对象,不作修改,所以声明为final
// 在configure("cfg/hibernate.cfg.xml")方法中,如果不指定资源路径,默认在类路径下寻找名为hibernate.cfg.xml的文件
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure("hibernate.cfg.xml").build();
// 2. 根据服务注册类创建一个元数据资源集,同时构建元数据并生成应用一般唯一的的session工厂
SessionFactory sessionFactory = new MetadataSources(registry)
.buildMetadata().buildSessionFactory();
/**** 上面是配置准备,下面开始我们的数据库操作 ******/
Session session = sessionFactory.openSession();// 从会话工厂获取一个session
事务只是一个工作单位(单元)。 在这种情况下,如果一个步骤失败,则整个事务失败(称为原子性)。 ACID属性(原子性,一致性,隔离性和持久性)可以描述事务。
Hibernate中的事务接口
在hibernate框架中,我们有Transaction
接口来定义工作单元。 它维护了事务实现(JTA,JDBC)的抽象。
事务与Session
相关联,并通过调用session.beginTransaction()
实例化。
Transaction
接口的方法如下:
void begin()
开始一个新的事务。void commit()
结束工作单位,在FlushMode.NEVER
中除外。void rollback()
强制此事务回滚。void setTimeout(int seconds)
它为由此实例开始的后续调用启动的任何事务设置事务超时。boolean isAlive()
检查交易是否仍然存在。void registerSynchronization(Synchronization s)
为此事务注册用户同步回调。boolean wasCommited()
检查事务是否成功提交。boolean wasRolledBack()
检查事务是否成功回滚。
Hibernate中的事务管理示例
在hibernate中,如果发生任何异常,最好回滚事务,以便资源可以释放自由。 我们来看看hibernate中事务管理的例子。
Session session = null;
Transaction tx = null;
try {
session = sessionFactory.openSession();
tx = session.beginTransaction();
//some action
tx.commit();
}catch (Exception ex) {
ex.printStackTrace();
tx.rollback();
}
finally {session.close();}