杰瑞科技汇

Hibernate4教程该怎么学?

Hibernate 4 教程:从入门到实践

Hibernate 是一个开源的 ORM(Object-Relational Mapping,对象关系映射)框架,它极大地简化了 Java 应用程序与数据库之间的交互,通过 Hibernate,您可以用面向对象的方式来操作数据库,而无需编写大量的 JDBC 代码。

Hibernate4教程该怎么学?-图1
(图片来源网络,侵删)

目录

  1. 第一部分:环境准备与项目搭建

    • 1 前提条件
    • 2 创建 Maven 项目
    • 3 添加 Hibernate 4 和 MySQL 依赖
    • 4 项目结构
  2. 第二部分:Hibernate 核心配置

    • 1 数据库连接配置 (hibernate.cfg.xml)
    • 2 实体类映射配置 (*.hbm.xml)
    • 3 整合配置:主配置文件引用映射文件
  3. 第三部分:编写第一个 Hibernate 程序

    • 1 创建实体类
    • 2 创建映射文件
    • 3 创建工具类(获取 SessionFactory)
    • 4 编写测试代码(保存一个对象)
  4. 第四部分:Hibernate 核心 API 详解

    • 1 Configuration: 配置加载
    • 2 ServiceRegistry: 服务注册中心 (Hibernate 4 核心变化)
    • 3 SessionFactory: 线程安全的工厂
    • 4 Session: 轻量级线程不安全的“非自动提交”连接
    • 5 Transaction: 事务管理
    • 6 QueryCriteria: 查询接口
  5. 第五部分:CRUD 操作

    • 1 创建 - save() / persist()
    • 2 读取 - get() / load()
    • 3 更新 - update()
    • 4 删除 - delete()
    • 5 HQL 查询示例
  6. 第六部分:进阶主题

    • 1 关系映射(一对多)
    • 2 注解方式配置(@Entity, @Id 等)

第一部分:环境准备与项目搭建

1 前提条件

  • Java Development Kit (JDK): 推荐 JDK 7 或 8。
  • IDE: IntelliJ IDEA 或 Eclipse。
  • 构建工具: Maven 或 Gradle,本教程使用 Maven。
  • 数据库: MySQL 5.7 或更高版本。
  • MySQL JDBC 驱动: mysql-connector-java

2 创建 Maven 项目

在您的 IDE 中,创建一个新的 Maven 项目,如果您使用命令行,可以执行:

mvn archetype:generate -DgroupId=com.example -DartifactId=hibernate4-tutorial -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

3 添加 Hibernate 4 和 MySQL 依赖

打开 pom.xml 文件,添加以下依赖:

<dependencies>
    <!-- Hibernate 4 Core -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.3.11.Final</version> <!-- 这是一个稳定的 Hibernate 4 最终版本 -->
    </dependency>
    <!-- MySQL Connector/J -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.28</version> <!-- 请根据您的 MySQL 版本选择合适的驱动 -->
    </dependency>
    <!-- JPA API (Hibernate 实现了 JPA 标准) -->
    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.1-api</artifactId>
        <version>1.0.2.Final</version>
    </dependency>
</dependencies>

4 项目结构

一个典型的 Maven 项目结构如下:

hibernate4-tutorial
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── example
│   │   │           ├── entity
│   │   │           │   └── User.java
│   │   │           ├── util
│   │   │           │   └── HibernateUtil.java
│   │   │           └── App.java
│   │   └── resources
│   │       ├── hibernate.cfg.xml
│   │       └── com
│   │           └── example
│   │               └── entity
│   │                   └── User.hbm.xml
│   └── test
│       └── java
└── pom.xml

第二部分:Hibernate 核心配置

Hibernate 使用 XML 文件来配置数据库连接和映射信息。

1 数据库连接配置 (hibernate.cfg.xml)

src/main/resources 目录下创建 hibernate.cfg.xml 文件,这是 Hibernate 的主配置文件。

<?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>
        <!-- 1. Database connection settings -->
        <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_db?useSSL=false&amp;serverTimezone=UTC</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">your_password</property>
        <!-- 2. Dialect: This makes Hibernate generate SQL for the right database -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
        <!-- 3. SQL Formatting -->
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <!-- 4. Auto create/update schema (for development only) -->
        <!-- update: Updates the schema if the model changes. -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!-- 5. Mapping resource files -->
        <!-- 告诉 Hibernate 去哪里找实体类的映射文件 -->
        <mapping resource="com/example/entity/User.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

配置说明:

  • driver_class: MySQL 驱动类。
  • url: 数据库连接 URL,请确保 hibernate_db 数据库已存在。
  • username / password: 数据库用户名和密码。
  • dialect: 指定数据库方言,让 Hibernate 生成针对特定数据库的优化 SQL。
  • show_sql: 在控制台打印生成的 SQL 语句,便于调试。
  • format_sql: 格式化输出的 SQL 语句,使其更易读。
  • hbm2ddl.auto:
    • none: 不自动创建或更新表。
    • update: 当实体类发生变化时,自动更新数据库表结构(开发推荐)。
    • create: 每次启动时都重新创建表,数据会丢失(测试用)。
    • create-drop: 创建表,当 SessionFactory 关闭时,删除表。
  • <mapping>: 引入实体类的映射文件。

2 实体类映射配置 (*.hbm.xml)

我们采用 XML 方式进行映射,为每个实体类创建一个对应的 .hbm.xml 文件,文件名通常与实体类名相同,放在与实体类相同的包路径下。

3 整合配置:主配置文件引用映射文件

如上所示,在 hibernate.cfg.xml 中,我们通过 <mapping resource="..."/> 标签将 User.hbm.xml 引入。


第三部分:编写第一个 Hibernate 程序

我们将创建一个 User 实体,并将其保存到数据库中。

1 创建实体类 (User.java)

src/main/java/com/example/entity 目录下创建 User.java

package com.example.entity;
public class User {
    private Long id;
    private String name;
    private String email;
    private int age;
    // 无参构造器是必须的
    public User() {
    }
    public User(String name, String email, int age) {
        this.name = name;
        this.email = email;
        this.age = age;
    }
    // Getter 和 Setter 方法
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

2 创建映射文件 (User.hbm.xml)

src/main/resources/com/example/entity 目录下创建 User.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example.entity">
    <class name="User" table="t_user">
        <!-- 
            name: 实体类属性名
            column: 数据库表列名
            type: 数据类型 (可选,Hibernate 可推断)
        -->
        <id name="id" column="id">
            <!-- 
                generator: 主键生成策略
                native: 自动选择数据库支持的最佳策略 (MySQL是自增, Oracle是序列)
            -->
            <generator class="native"/>
        </id>
        <property name="name" column="name"/>
        <property name="email" column="email"/>
        <property name="age" column="age"/>
    </class>
</hibernate-mapping>

3 创建工具类 (HibernateUtil.java)

SessionFactory 的创建非常耗费资源,它是线程安全的,通常在整个应用中只创建一个,我们将其创建在静态代码块中,并提供一个 getSession() 方法来获取 Session

src/main/java/com/example/util 目录下创建 HibernateUtil.java

package com.example.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class HibernateUtil {
    private static final SessionFactory sessionFactory;
    static {
        try {
            // 1. 创建 Configuration 对象,加载 hibernate.cfg.xml 配置文件
            Configuration configuration = new Configuration().configure();
            // 2. 创建 ServiceRegistry 对象 (Hibernate 4 的核心变化)
            // 这是 Hibernate 4 引入的,用于替代旧的 Properties 配置方式
            ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
                    .applySettings(configuration.getProperties())
                    .buildServiceRegistry();
            // 3. 使用 Configuration 和 ServiceRegistry 创建 SessionFactory
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        } catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

4 编写测试代码 (App.java)

修改 src/main/java/com/example/App.java,编写保存用户的代码。

package com.example;
import com.example.entity.User;
import com.example.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public class App {
    public static void main(String[] args) {
        // 1. 获取 SessionFactory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        // 2. 打开一个 Session
        Session session = sessionFactory.openSession();
        // 3. 开启一个事务
        Transaction transaction = null;
        try {
            transaction = session.beginTransaction();
            // 4. 创建 User 对象
            User user = new User("张三", "zhangsan@example.com", 25);
            // 5. 保存对象 (此操作会生成 INSERT 语句,但尚未提交到数据库)
            session.save(user);
            // 6. 提交事务
            transaction.commit();
            System.out.println("用户保存成功!用户ID: " + user.getId());
        } catch (Exception e) {
            // 如果发生异常,回滚事务
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            // 7. 关闭 Session
            session.close();
        }
        // 8. 关闭 SessionFactory (通常在应用关闭时执行)
        sessionFactory.close();
    }
}

运行程序:

  1. 确保您的 MySQL 服务正在运行,hibernate_db 数据库已创建。
  2. 运行 App.java
  3. 查看控制台输出,您会看到 Hibernate 生成的建表和插入 SQL 语句。
  4. 连接到您的 MySQL 数据库,检查 t_user 表,会发现新数据已成功插入。

第四部分:Hibernate 核心 API 详解

1 Configuration

负责加载 Hibernate 的配置信息(主要是 hibernate.cfg.xml),它会读取配置文件并创建一个 Configuration 实例。

2 ServiceRegistry

这是 Hibernate 4 的一个重大变化,在 Hibernate 3 中,配置信息直接传递给 SessionFactory,在 Hibernate 4 中,引入了 ServiceRegistry 作为中心服务注册表,所有 Hibernate 的服务(如连接池、缓存等)都注册在这里。Configuration 对象会根据配置文件创建并填充这个 ServiceRegistry

3 SessionFactory

线程安全的重量级对象,它负责创建 Session 对象,并管理数据库连接池,一个数据库通常只需要一个 SessionFactory,它通常在应用启动时创建,在应用关闭时销毁。

4 Session

非线程轻量级对象,相当于 JDBC 中的 Connection,它用于执行持久化操作(增删改查)。Session 内部有一个缓存(一级缓存),它不是自动提交的,所有操作都必须在事务中完成,用完之后必须关闭。

5 Transaction

管理事务,在 Hibernate 中,所有写操作(save, update, delete, saveOrUpdate 等)都必须在事务中执行,否则不会提交到数据库。

6 QueryCriteria

  • Query: 用于执行 HQL(Hibernate Query Language)或原生 SQL,HQL 是一种面向对象的查询语言,类似于 SQL,但操作的是对象和属性而非表和列。
  • Criteria: 一种面向对象的、类型安全的查询 API,通过 Java 代码动态构建查询条件,避免了书写字符串形式的 HQL。

第五部分:CRUD 操作

基于上面的 User 实体,我们演示完整的 CRUD。

1 创建 - save() / persist()

save(): 将一个临时态对象转变为持久态对象,并生成一个标识符(ID),它会在事务提交时执行 INSERT,返回生成的 ID。 persist(): 类似于 save(),但它保证不立即返回 ID,并且如果对象已经处于持久态,它不会执行任何操作,更符合 JPA 规范。

User newUser = new User("李四", "lisi@example.com", 30);
session.save(newUser); // 或 session.persist(newUser);

2 读取 - get() / load()

get(): 立即加载,它会立即执行 SELECT 语句,从数据库中查询数据,如果对象不存在,返回 nullload(): 延迟加载,它返回一个代理对象,只有当您第一次访问该对象的非 ID 属性时,才会执行 SELECT 语句,如果对象不存在,会抛出 ObjectNotFoundException

// 使用 get
User user1 = (User) session.get(User.class, 1L); // 立即查询
if (user1 != null) {
    System.out.println("找到用户: " + user1.getName());
}
// 使用 load
User user2 = (User) session.load(User.class, 2L); // 此时不查询
System.out.println("用户ID: " + user2.getId()); // 访问 ID,不会触发查询,因为 ID 已由 Hibernate 管理
System.out.println("用户名: " + user2.getName()); // 访问非 ID 属性,此时才会触发 SELECT 查询

3 更新 - update()

当您修改一个已经处于持久态对象(从 get(), load(), query 获取的)的属性时,Hibernate 会在事务提交时自动同步这些更改到数据库,您不需要手动调用 update()

但如果您修改的是一个游离态对象(即曾经是持久态,但 Session 已关闭或被清除),则需要手动调用 update() 将其重新关联到 Session。

// 场景1:持久态对象自动更新
User user = (User) session.get(User.class, 1L);
user.setName("王五更新"); // 修改属性
// transaction.commit(); // 提交时,Hibernate 会自动执行 UPDATE
// 场景2:游离态对象需要手动更新
User detachedUser = (User) session.get(User.class, 1L);
session.close(); // Session 关闭,user 变为游离态
detachedUser.setName("王五再次更新");
Session newSession = HibernateUtil.getSessionFactory().openSession();
Transaction newTx = newSession.beginTransaction();
newSession.update(detachedUser); // 将游离态对象重新附加到新的 Session
newTx.commit();
newSession.close();

4 删除 - delete()

可以从持久态或游离态对象中删除数据库记录。

// 场景1:从持久态对象删除
User userToDelete = (User) session.get(User.class, 1L);
session.delete(userToDelete); // 标记为删除
// transaction.commit(); // 提交时执行 DELETE
// 场景2:从游离态对象删除
User detachedUserToDelete = (User) session.get(User.class, 2L);
session.close();
Session newSession = HibernateUtil.getSessionFactory().openSession();
Transaction newTx = newSession.beginTransaction();
newSession.delete(detachedUserToDelete); // 删除游离态对象
newTx.commit();
newSession.close();

5 HQL 查询示例

HQL 类似 SQL,但使用对象名和属性名。

// 1. 获取 Query 对象
String hql = "FROM User WHERE age > :minAge";
Query query = session.createQuery(hql);
// 2. 设置命名参数
query.setParameter("minAge", 25);
// 3. 执行查询,获取结果列表
List<User> users = query.list();
// 4. 遍历结果
for (User user : users) {
    System.out.println(user);
}

第六部分:进阶主题

1 关系映射(一对多)

假设一个 Department 部门有多个 User 员工。

Department.java

package com.example.entity;
import java.util.HashSet;
import java.util.Set;
public class Department {
    private Long id;
    private String name;
    private Set<User> users = new HashSet<>();
    // getters, setters, constructors...
}

Department.hbm.xml

<hibernate-mapping package="com.example.entity">
    <class name="Department" table="t_department">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="name" column="name"/>
        <!-- 一对多关系 -->
        <set name="users" table="t_user">
            <key column="dept_id"/> <!-- t_user 表中的外键 -->
            <one-to-many class="User"/>
        </set>
    </class>
</hibernate-mapping>

User.hbm.xml (多的一方,添加外键)

<hibernate-mapping package="com.example.entity">
    <class name="User" table="t_user">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <!-- ... 其他属性 ... -->
        <property name="name" column="name"/>
        <property name="email" column="email"/>
        <property name="age" column="age"/>
        <!-- 多对一关系 (可选,但推荐) -->
        <many-to-one name="department" class="Department" column="dept_id"/>
    </class>
</hibernate-mapping>

2 注解方式配置

Hibernate 4 同时支持 JPA 注解,可以省略 .hbm.xml 文件。

修改 hibernate.cfg.xml:

<!-- 移除 <mapping resource="..."/> -->
<!-- 添加以下配置 -->
<property name="hibernate.archive.autodetection">class</property>

修改 User.java (添加注解):

package com.example.entity;
import javax.persistence.*;
import java.io.Serializable;
@Entity // 声明为实体类
@Table(name = "t_user") // 指定对应的表名
public class User implements Serializable { // 实现 Serializable 是一个好习惯
    @Id // 声明为主键
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 使用数据库自增策略
    @Column(name = "id") // 指定列名
    private Long id;
    @Column(name = "name", nullable = false, length = 50)
    private String name;
    @Column(name = "email", unique = true)
    private String email;
    @Column(name = "age")
    private int age;
    // ... getters, setters, constructors ...
}

使用注解后,就不需要 User.hbm.xml 文件了,Hibernate 会自动扫描实体类。


这份教程涵盖了 Hibernate 4 的基础知识,包括环境搭建、核心配置、CRUD 操作和基本的关系映射,Hibernate 4 相比 Hibernate 3 最大的变化是引入了 ServiceRegistry,并全面拥抱了 JPA 标准。

通过学习本教程,您应该能够掌握 Hibernate 的基本使用,并为进一步学习更高级的特性(如缓存、集合映射、继承映射等)打下坚实的基础。

分享:
扫描分享到社交APP
上一篇
下一篇