Spring 项目快速整合 Hibernate

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 前言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 操作数据库。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
12天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
23 2
|
16天前
|
SQL Java 数据库连接
从理论到实践:Hibernate与JPA在Java项目中的实际应用
本文介绍了Java持久层框架Hibernate和JPA的基本概念及其在具体项目中的应用。通过一个在线书店系统的实例,展示了如何使用@Entity注解定义实体类、通过Spring Data JPA定义仓库接口、在服务层调用方法进行数据库操作,以及使用JPQL编写自定义查询和管理事务。这些技术不仅简化了数据库操作,还显著提升了开发效率。
29 3
|
1月前
|
设计模式 前端开发 Java
Spring MVC——项目创建和建立请求连接
MVC是一种软件架构设计模式,将应用分为模型、视图和控制器三部分。Spring MVC是基于MVC模式的Web框架,通过`@RequestMapping`等注解实现URL路由映射,支持GET和POST请求,并可传递参数。创建Spring MVC项目与Spring Boot类似,使用`@RestController`注解标记控制器类。
37 1
Spring MVC——项目创建和建立请求连接
|
1月前
|
Java 关系型数据库 MySQL
Maven——创建 Spring Boot项目
Maven 是一个项目管理工具,通过配置 `pom.xml` 文件自动获取所需的 jar 包,简化了项目的构建和管理过程。其核心功能包括项目构建和依赖管理,支持创建、编译、测试、打包和发布项目。Maven 仓库分为本地仓库和远程仓库,远程仓库包括中央仓库、私服和其他公共库。此外,文档还介绍了如何创建第一个 SpringBoot 项目并实现简单的 HTTP 请求响应。
127 1
Maven——创建 Spring Boot项目
|
1月前
|
Java 关系型数据库 MySQL
如何使用 maven 创建一个 Spring Boot项目
Maven 是一个强大的项目管理工具,通过配置 `pom.xml` 文件自动获取所需的 jar 包,提高开发效率。其核心功能包括项目构建和依赖管理。项目构建支持编译、测试、打包和发布等流程,而依赖管理则通过中央仓库、本地仓库和私有服务器获取和管理项目依赖。示例中展示了如何创建第一个 SpringBoot 项目并实现简单接口。
28 1
如何使用 maven 创建一个 Spring Boot项目
|
1月前
|
Java 应用服务中间件 Android开发
Eclipse创建Spring项目
本文介绍了在Eclipse中创建Spring项目的步骤,包括如何配置Tomcat服务器、创建项目、部署项目到Tomcat以及添加Spring框架所需的JAR包。
60 1
Eclipse创建Spring项目
|
1月前
|
Java Spring
ij社区版如何创建spring项目
如何在IntelliJ IDEA社区版中创建Spring项目,包括安装Spring Boot Helper插件的步骤和创建过程。
66 1
ij社区版如何创建spring项目
|
1月前
|
Java Apache Maven
Java/Spring项目的包开头为什么是com?
本文介绍了 Maven 项目的初始结构,并详细解释了 Java 包命名惯例中的域名反转规则。通过域名反转(如 `com.example`),可以确保包名的唯一性,避免命名冲突,提高代码的可读性和逻辑分层。文章还讨论了域名反转的好处,包括避免命名冲突、全球唯一性、提高代码可读性和逻辑分层。最后,作者提出了一个关于包名的问题,引发读者思考。
Java/Spring项目的包开头为什么是com?
|
1月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
57 2
|
1月前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
182 2
下一篇
无影云桌面