Spring 项目快速整合 Hibernate

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 前言Hibernate 作为前些年广为流行的 ORM 框架,Spring 在诞生之初也进行了支持,并且抽象出一个 spring-orm 模块。

前言


Hibernate 作为前些年广为流行的 ORM 框架,Spring 在诞生之初也进行了支持,并且抽象出一个 spring-orm 模块。


Spring 可以将 Hibernate 加入自身的事务管理,并且可以将 Hibernate 产生的异常转换为 Spring 数据访问异常,而且提供了一个便于数据库操作的 HibernateTemplate 类。


由于 Hibernate 设计较为复杂,因此在 《认识 ORM 框架 Hibernate,为什么 2022 年了还在谈论它?》 一篇中花了不少篇幅介绍 Hibernate 本身,这篇希望用简短的内容介绍如何在 Spring 项目中整合 Hibernate。


Spring Framework 整合 Hibernate


1. 依赖引入


Spring 整合 Hibernate 首先需要引入一些依赖,这里使用的依赖如下。

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.29</version>
</dependency>
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>4.0.3</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.6.9.Final</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>5.2.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.6.RELEASE</version>
</dependency>

各依赖作用如下:


mysql-connector-java :Java 通过 JDBC 访问数据库必须依赖具体的数据库驱动,这里使用的是 MySQL 数据库驱动。

HikariCP :使用 JDBC 访问数据库需要建立连接和释放连接,为了降低这些开销通常使用带有连接池的数据源,HikariCP 就是一种常见的数据源实现,也是 Spring Boot 默认支持的。


hibernate-core :这个是使用 Hibernate 必须的依赖。

spring-orm :这个依赖是 Spring 整合 Hibernate 所使用的模块,可以将 Hibernate 加入 Spring 的事务管理。

spring-context : Spring 上下文所需的模块,包含 ApplicationContext 和一些 Spring 注解的定义。


2. 映射关系定义


Hibernate 作为一个 ORM 框架,映射关系的定义是必须的。这里测试使用的数据库表定义如下。


create table user
(
    id          bigint unsigned auto_increment comment '主键'
        primary key,
    username    varchar(20)  not null comment '用户名',
    password    varchar(20)  not null comment '密码'
);

数据库表对应的实体类如下。

@Data
public class User {
    private Long id;
    private String username;
    private String password;
}

映射关系可以使用 XML 文件定义,也可以使用 JPA 注解,这里使用 XML 文件定义,类路径下创建文件 hibernate/mapping/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>
    <class name="com.zzuhkp.hibernate.entity.User" table="user">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="username" column="username"/>
        <property name="password" column="password"/>
    </class>
</hibernate-mapping>

3. Spring 配置


先看下定义的 Spring 配置类,然后再进行解释。

@Configuration
@EnableTransactionManagement
public class HibernateConfig {
    @Bean
    public DataSource dataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setDriverClassName(Driver.class.getName());
        dataSource.setUsername("root");
        dataSource.setPassword("12345678");
        return dataSource;
    }
    @Bean
    public LocalSessionFactoryBean localSessionFactoryBean() {
        Properties properties = new Properties();
        properties.put(AvailableSettings.SHOW_SQL, true);
        properties.put(AvailableSettings.FORMAT_SQL, true);
        LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
        factoryBean.setDataSource(dataSource());
        factoryBean.setHibernateProperties(properties);
        factoryBean.setMappingResources("hibernate/mapping/User.hbm.xml");
        return factoryBean;
    }
    @Bean
    public PlatformTransactionManager transactionManager(SessionFactory sessionFactory) {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory);
        transactionManager.setDataSource(dataSource());
        return transactionManager;
    }
}


首先定义的是一个数据源 DataSource bean,这里我们使用的是 HikariCP。


然后配置类中定义了 LocalSessionFactoryBean 类型的 bean,使用 Hibernate 需要创建一个 SessionFactory,这个 bean 是 spring-orm 模块提供的用于创建 SessionFactory 的 FactoryBean。创建 SessionFactory 所使用的配置都在这个 bean 中定义,这里配置了数据源、Hibernate 的属性以及映射文件。


为了将 Hibernate 加入 Spring 的事务管理,这里定义了一个专用于 Hibernate 的事务管理器

HibernateTransactionManager,只需要设置事务管理器所使用的 SessionFacotry 以及数据源 DataSource 就可以了。


通过 LocalSessionFactoryBean 与 HibernateTransactionManager 的配合,已经可以实现通过编程的方式将 Hibernate 加入 Spring 的事务管理了,为了简化事务使用方式,这里通过 @EnableTransactionManagement 注解开启声明式事务,这样只需要在类或方法上添加 @Transactional 注解就可以了。


4. 数据库操作


必要的准备工作都做好了,下面就可以使用 Hibernate 提供的 API 操作数据库了,示例代码如下。


@Repository
public class UserRepository {
    @Autowired
    private SessionFactory sessionFactory;
    @Transactional(rollbackFor = Exception.class)
    public void saveUser(User user) {
        Session session = sessionFactory.getCurrentSession();
        session.save(user);
        System.out.println(user.getId());
    }
}


需要注意,为了将 Hibernate 加入事务管理,只能通过 SessionFactory.getCurrentSession 方法获取 Session,Spring 会在事务结束后自动提交事务和关闭会话,无需用户手动 close Session。


为了简化数据库操作,spring-orm 模块还提供了一个 HibernateTemplate 类,这个类的设计类似 JdbcTemplate,使用方式如下。


@Configuration
public class HibernateConfig {
    @Bean
    public HibernateTemplate hibernateTemplate(SessionFactory sessionFactory) {
        HibernateTemplate hibernateTemplate = new HibernateTemplate();
        hibernateTemplate.setSessionFactory(sessionFactory);
        return hibernateTemplate;
    }
}
@Repository
public class UserRepository {
    @Autowired
    private HibernateTemplate hibernateTemplate;
    @Transactional(rollbackFor = Exception.class)
    public void saveUser(User user) {
        hibernateTemplate.save(user);
    }
}

Spring Boot 整合 Hibernate


Spring Boot 项目确实对 Hibernate 进行了默认的支持,提供了一些自动化装配的特性,不过这种支持建立在 JPA 的 API 之上,而且没有提供 starter 供用户直接使用。


关于 Spring Boot 整合 Hibernate、JPA,很多博客都提到了 spring-boot-starter-data-jpa,其实这已经属于 Spring Data 项目范畴的内容了,这是 Spring Boot 对 spring-data-jpa 的支持,而非对 spring-orm 的直接支持。


关于 Spring Boot 通过 JPA API 的方式整合 Hibernate,将在下篇 Spring 整合 JPA 文章中介绍。


总结

Spring 对 Hibernate 提供了原生的支持,将 Hibernate 加入到 Spring 的事务管理,屏蔽了底层事务的差异。如果确实需要使用 Hibernate,推荐使用 Spring 提供的 HibernateTemplate 操作数据库。


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
网络安全
ssh(Spring+Spring mvc+hibernate)——DeptDaoImpl.java
ssh(Spring+Spring mvc+hibernate)——DeptDaoImpl.java
12 0
|
1月前
|
网络安全
ssh(Spring+Spring mvc+hibernate)——BaseDaoImpl.java
ssh(Spring+Spring mvc+hibernate)——BaseDaoImpl.java
12 0
|
1月前
|
Shell
sh(Spring+Spring mvc+hibernate)——IEmpDao.java
sh(Spring+Spring mvc+hibernate)——IEmpDao.java
11 0
|
1月前
|
Shell
sh(Spring+Spring mvc+hibernate)——IDeptDao.java
sh(Spring+Spring mvc+hibernate)——IDeptDao.java
13 0
|
1月前
|
Java Spring
【编程笔记】在 Spring 项目中使用 RestTemplate 发送网络请求
【编程笔记】在 Spring 项目中使用 RestTemplate 发送网络请求
94 0
|
1月前
|
网络安全
ssh(Spring+Spring mvc+hibernate)——Dept.java
ssh(Spring+Spring mvc+hibernate)——Dept.java
12 0
|
1月前
|
SpringCloudAlibaba Java 持续交付
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
146 0
|
2月前
|
监控 IDE Java
Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase()解决大小写不一致问题
Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase()解决大小写不一致问题
42 0
|
12天前
|
JSON 前端开发 Java
统一异常处理:让Spring Boot项目异常更优雅
统一异常处理:让Spring Boot项目异常更优雅
24 1
|
16天前
|
SQL Java 数据库连接
jpa、hibernate、spring-data-jpa、jdbcTemplate
jpa、hibernate、spring-data-jpa、jdbcTemplate