目 录CONTENT

文章目录

Hibernate

FatFish1
2025-11-06 / 0 评论 / 0 点赞 / 9 阅读 / 0 字 / 正在检测是否收录...

Hibernate与javax.persistence概述

javax.persistence包是J2EE原生包,其中提供了JPA 规范的核心注解和接口,例如:

  • @Entity@Table@Column 等注解(用于实体类映射)

  • EntityManagerQuery 等接口(用于数据库操作)

  • @EntityListener@PrePersist@PostPersist@PreUpdate@PostUpdate@PreRemove@PostRemove@PostLoad等用于监听器和回调相关注解

但是javax.persistence不实现这些接口,而是由业务提供方实现,例如Hibernate

Hibernate核心思想是将 Java 对象(POJO)映射到数据库表,将对象属性映射到数据库表的列。开发者可以直接操作 Java 对象,而 Hibernate 负责将这些操作转换为底层的 SQL 语句(如 INSERT, UPDATE, SELECT, DELETE)并执行,从而极大地简化了数据库持久层的开发

其核心概念包括:

  • Configuration(配置):负责读取 Hibernate 配置文件(hibernate.cfg.xml)和映射文件(*.hbm.xml)或注解,并用于创建 SessionFactory

  • SessionFactory(会话工厂):一个重量级、线程安全的对象。它是数据库的编译后的内存镜像。一个应用通常只有一个 SessionFactory。它是生成 Session 的工厂。

  • Session(会话):一个轻量级、非线程安全的对象。它代表了应用程序与数据库之间的一次交互(一个工作单元)。它封装了 JDBC 的 Connection,是进行 CRUD 操作、管理事务和获取查询对象的主要接口。核心中的核心

  • Transaction(事务):用于管理事务的接口,是对 JDBC 事务或 JTA 事务的抽象。

  • Query / Criteria(查询):用于执行数据库查询的接口

Hibernate项目实战

创建Entity

@Entity
@Table(name = "t_user")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "username")
    private String username;
    
    private String email;
}

创建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>
        <!-- 数据库连接设置 -->
        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/test_db</property>
        <property name="connection.username">root</property>
        <property name="connection.password">password</property>

        <!-- JDBC 连接池(使用 Hibernate 内置的) -->
        <property name="connection.pool_size">5</property>

        <!-- 数据库方言 -->
        <property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>

        <!-- 在控制台输出 SQL -->
        <property name="show_sql">true</property>

        <!-- 可选:格式化 SQL -->
        <property name="format_sql">true</property>

        <!-- DDL 自动创建/更新表 -->
        <property name="hbm2ddl.auto">update</property>

        <!-- 注解方式注册实体类 -->
        <mapping class="com.example.entity.User"/>
    </session-factory>
</hibernate-configuration>

编写CRUD操作

public class UserDao {
    public void saveUser(User user) {
        // 1. 获取 SessionFactory
        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
        // 2. 获取 Session
        Session session = sessionFactory.openSession();
        // 3. 开启事务
        Transaction tx = session.beginTransaction();

        try {
            // 4. 执行操作
            session.save(user);
            // 5. 提交事务
            tx.commit();
        } catch (Exception e) {
            // 6. 回滚事务
            if (tx != null) tx.rollback();
            e.printStackTrace();
        } finally {
            // 7. 关闭 Session
            session.close();
        }
    }

    public User getUserById(Long id) {
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            return session.get(User.class, id);
        }
    }
    // ... 其他 update, delete, query 方法
}

源码简读

Configuration

configure

public Configuration configure() throws HibernateException {
    return configure( StandardServiceRegistryBuilder.DEFAULT_CFG_RESOURCE_NAME );
}

这里即调用的默认位置

public static final String DEFAULT_CFG_RESOURCE_NAME = "hibernate.cfg.xml";
public Configuration configure(String resource) throws HibernateException {
    standardServiceRegistryBuilder.configure( resource );
    // todo : still need to have StandardServiceRegistryBuilder handle the "other cfg.xml" elements.
    //    currently it just reads the config properties
    properties.putAll( standardServiceRegistryBuilder.getSettings() );
    return this;
}

对xml中的配置内容进行配置

buildSessionFactory

public SessionFactory buildSessionFactory() throws HibernateException {
    log.debug( "Building session factory using internal StandardServiceRegistryBuilder" );
    standardServiceRegistryBuilder.applySettings( properties );
    return buildSessionFactory( standardServiceRegistryBuilder.build() );
}

在buildSessionFactory中完成配置,生成SessionFactory

SessionFactory

openSession

创建Session

public Session openSession() throws HibernateException {
    //The defaultSessionOpenOptions can't be used in some cases; for example when using a TenantIdentifierResolver.
    if ( this.defaultSessionOpenOptions != null ) {
       return this.defaultSessionOpenOptions.openSession();
    }
    else {
       return this.withOptions().openSession();
    }
}

Session/SessionImpl

是Hibernate的核心

看这个接口提供的方法是直接操作数据库的,例如

Serializable save(Object object);
void saveOrUpdate(Object object);
void delete(Object object);

基于SessionImpl看它的设计理念

成员变量

private transient ActionQueue actionQueue;
private LockOptions lockOptions;
private transient LoadEvent loadEvent; //cached LoadEvent instance
private transient TransactionObserver transactionObserver;

save

public Serializable save(String entityName, Object object) throws HibernateException {
    return fireSave( new SaveOrUpdateEvent( entityName, object, this ) );
}

执行在fireSave方法,同时将传进来的entity包装成了一个SaveOrUpdateEvent

public class SaveOrUpdateEvent extends AbstractEvent {
    private Object object;
    private Serializable requestedId;
    private String entityName;
    private Object entity;
    private EntityEntry entry;
    private Serializable resultId;

这个包装类实际上就是为了存储一些entity相关的信息

fireSave

private Serializable fireSave(final SaveOrUpdateEvent event) {
    checkOpen();
    checkTransactionSynchStatus();
    checkNoUnresolvedActionsBeforeOperation();
    fastSessionServices.eventListenerGroup_SAVE.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
    checkNoUnresolvedActionsAfterOperation();
    return event.getResultId();
}

执行操作

Hibernate集成springboot

hibernate集成springboot是比较简单的

只要添加springboot相关依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

就会自动引入hibernate相关依赖

在springboot场景下

在 application.properties 或 application.yml 中配置数据源和 JPA 属性:

# 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/test_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA 配置
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

然后基于springboot提供的repository层接口就可以直接使用

public interface UserRepository extends JpaRepository<User, Long> {
    // 可以根据方法名自动生成查询,也可以使用 @Query 注解自定义查询
    User findByUsername(String username);
}
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    public User saveUser(User user) {
        return userRepository.save(user);
    }
    
    public User findUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }
    
    // 其他业务方法...
}

0

评论区