### Hibernate的配置与使用详解
#### 一、Hibernate概述
Hibernate是一种开源的对象关系映射(Object-Relational Mapping,简称ORM)框架,它为Java应用提供了利用SQL数据的持久化解决方案。通过ORM技术,开发人员可以将Java对象映射到数据库表上,从而避免了大量的SQL代码编写工作。
#### 二、Hibernate初始化
##### 1. 获取SessionFactory实例
- **通过Configuration实例**
- 配置文件(通常为`hibernate.cfg.xml`)包含了数据库连接等信息。
- 使用`Configuration`类加载这些配置信息,并创建`SessionFactory`对象。
- **SessionFactory实例创建**
- `SessionFactory`是线程安全的,通常在整个应用程序中只有一个实例。
- 创建时需要一个`Configuration`对象,该对象包含了所有连接数据库所需的配置信息。
- 可以通过`Configuration`的`configure()`方法自动读取默认配置文件,或者指定配置文件路径。
##### 2. SessionFactory与Session的关系
- **SessionFactory**:负责创建`Session`对象,它是整个应用程序中的数据处理工厂。
- **Session**:代表了与数据库的一次会话,每次与数据库交互都需要通过它进行。
- 每个`Session`实例代表了一个事务范围内的操作,即在一次数据库操作中只使用一个`Session`实例。
- `SessionFactory`可以提供多个`Session`实例,但每个实例都必须独立管理自己的资源。
##### 3. SessionFactory的缓存机制
- Hibernate的`SessionFactory`支持二级缓存,用于存储跨事务的数据,可以显著提高应用性能。
- 一级缓存(默认开启):由`Session`管理,当`Session`关闭后,缓存中的数据会被清除。
- 二级缓存(可选):由`SessionFactory`管理,可以配置多种缓存策略,如EhCache等。
#### 三、Session的操作流程
- **获取连接**
- 可以通过`SessionFactory`直接获取`Session`实例。
- 如果需要自定义连接,则可以通过外部提供的`Connection`对象来创建`Session`。
- **执行操作**
- 通过`Session`执行CRUD操作。
- 例如:`session.save(entity)`用于保存实体对象。
- **提交或回滚事务**
- 执行完数据库操作后,需要提交事务以确保更改被持久化。
- 如果操作失败或出现异常,可以选择回滚事务以撤销更改。
#### 四、对象的状态管理
- **瞬时状态(Transient)**
- 当一个对象被新建但尚未保存到数据库时,它处于瞬时状态。
- 在瞬时状态下,对象没有对应的数据库记录。
- **持续状态(Persisted)**
- 当一个对象被`Session`持久化后,它进入持续状态。
- 此时,对象与其数据库记录之间建立了关联。
- **游离状态(Detached)**
- 当一个对象从`Session`中移除后,它进入游离状态。
- 游离状态下的对象仍然保留其数据,但失去了与`Session`的关联。
#### 五、实体映射配置示例
以下示例展示了如何配置员工(Employee)与账户(Account)之间的`一对一`关系:
##### 1. Employee.hbm.xml
```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.tsinghua.manager.vo.EmployeeVO" table="Employee" schema="dbo" catalog="study">
<id name="oid" type="java.lang.Integer">
<column name="oid"/>
<generator class="native"/>
</id>
<property name="deptid" type="java.lang.Integer">
<column name="deptid"/>
</property>
<property name="empName" type="java.lang.String">
<column name="empName" length="20"/>
</property>
<property name="sex" type="java.lang.String">
<column name="sex" length="1"/>
</property>
<one-to-one name="account" class="com.tsinghua.manager.vo.AccountVO"/>
</class>
</hibernate-mapping>
```
##### 2. Account.hbm.xml
```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.tsinghua.manager.vo.AccountVO">
<!-- AccountVO 的属性配置 -->
</class>
</hibernate-mapping>
```
以上配置文件中,`EmployeeVO`与`AccountVO`通过`<one-to-one>`元素建立了一对一的关系。
#### 六、查询操作
##### 1. HQL(Hibernate Query Language)
- **基本语法**:HQL是一种面向对象的查询语言,语法类似于SQL。
- **示例**:`select e from Employee e where e.empName = 'John Doe'`。
##### 2. Criteria API
- **基本用法**:Criteria API提供了更为灵活的查询方式,可以动态构建查询条件。
- **示例**:
```java
Criteria criteria = session.createCriteria(Employee.class);
criteria.add(Restrictions.eq("empName", "John Doe"));
List<Employee> employees = criteria.list();
```
##### 3. Native SQL
- **应用场景**:对于一些复杂的查询,可以直接使用原生SQL语句。
- **示例**:
```java
String sql = "SELECT * FROM Employee WHERE empName = ?";
SQLQuery query = session.createSQLQuery(sql).addEntity(Employee.class);
query.setParameter(0, "John Doe");
List<Employee> employees = query.list();
```
Hibernate不仅简化了Java应用与数据库之间的交互,还提供了丰富的查询API,使得开发者能够更加高效地处理数据。无论是初学者还是经验丰富的开发者,都能够从中受益匪浅。