Hibernate与Spring整合实践实例

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: Hibernate与Spring整合实践实例

spring与hibernate的整合目的就是为了让 IOC 容器来管理 Hibernate 的核心接口SessionFactory以及让 Hibernate 使用上 Spring 的声明式事务来进行事务操作.


【1】Hibernate使用XML方式与Spring整合

即,Model上面不添加注解,使用*.hbm.xml方式与数据库进行关联。

① applicationContext.xm:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
  <!-- 导入资源文件 -->
  <context:property-placeholder location="classpath:db.properties"/>
  <context:component-scan base-package="com"></context:component-scan>
  <!-- 配置 C3P0 数据源 -->
  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="user" value="${jdbc.user}"></property>
    <property name="password" value="${jdbc.password}"></property>
    <property name="driverClass" value="${jdbc.driverClass}"></property>
    <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>  
    <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
    <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
  </bean>
  <!-- 配置 SessionFactory -->
  <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
    <!-- 如果不想使用额外的hibernate.cfg.xml,则需要进行如下设置 -->
    <property name="hibernateProperties">
            <props>  
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>  
                <prop key="hibernate.hbm2ddl.auto">update</prop>  
                <prop key="hibernate.show_sql">true</prop>  
                <prop key="hibernate.format_sql">true</prop>  
            </props>  
        </property>
    <property name="mappingLocations" value="classpath:com/jane/ssh/entities/*.hbm.xml"></property>
  </bean>
  <!-- 这里配置与MyBatis整合Spring很类似 -->
  <!-- 配置 Spring 的声明式事务 -->
  <!-- 1. 配置 hibernate 的事务管理器 -->
  <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"></property>
  </bean>
  <!-- 2. 配置事务属性 -->
   <!-- 配置哪些方法要加入事务控制 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 让所有的方法都加入事务管理,为了提高效率,可以把一些查询之类的方法设置为只读事务 -->
            <tx:method name="*" propagation="REQUIRED" read-only="true"/>
            <!-- 以下方法都是可能涉及写改的方法,就无法设置为只读 -->
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="save*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
  <!-- 3. 配置事务切入点, 再把事务属性和事务切入点关联起来 -->
  <aop:config>
    <aop:pointcut expression="execution(* com.jane.ssh.service.*.*(..))" id="txPointcut"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
  </aop:config>
  <!-- 开启HibernateTemplate,并且为其注入SessionFactory
    使用HibernateTemplate不太方便的就是要获取session得通过getSessionFactory()方法获取
    注意:这里之所以配置这个是因为Dao继承了HibernateDaoSupport
  -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
</beans>

② hibernate.cfg.xml

由于数据源,*.hbm.xml都在applicationContext.xml中进行了配置,故而hibernate.cfg.xml极其简化:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
      <!-- 配置 hibernate 的基本属性 -->
      <!-- 方言 -->
      <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
      <!-- 是否显示及格式化 SQL -->
      <property name="hibernate.show_sql">true</property>
      <property name="hibernate.format_sql">true</property>
      <!-- 生成数据表的策略 -->
      <property name="hibernate.hbm2ddl.auto">update</property>
      <!-- 启用二级缓存 -->
    <property name="cache.use_second_level_cache">true</property>
      <!-- 配置使用的二级缓存的产品 -->
      <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
      <!-- 配置启用查询缓存 -->
      <property name="cache.use_query_cache">true</property>
    </session-factory>
</hibernate-configuration>

【2】Hibernate注解版与Spring整合

即,Model上面添加注解,此时不再存在*.hbm.xml。


① applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
  <!-- 导入资源文件 -->
  <context:property-placeholder location="classpath:db.properties"/>
  <context:component-scan base-package="com"></context:component-scan>
  <!-- 配置 C3P0 数据源 -->
  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="user" value="${jdbc.user}"></property>
    <property name="password" value="${jdbc.password}"></property>
    <property name="driverClass" value="${jdbc.driverClass}"></property>
    <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>  
    <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
    <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
  </bean>
  <!-- 配置 SessionFactory -->
  <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="hibernateProperties">
            <props>  
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>  
                <prop key="hibernate.hbm2ddl.auto">update</prop>  
                <prop key="hibernate.show_sql">true</prop>  
                <prop key="hibernate.format_sql">true</prop>  
            </props>  
        </property>
    <!-- 如果实体类使用了注解,通常会使用如下方式
    通过扫描包方式设置Spring取哪个包查找相应的实体类 -->
        <property name="packagesToScan">
            <value>com.jane.ssh.entities</value>
        </property>
        -->
  </bean>
  <!-- 配置 Spring 的声明式事务 -->
  <!-- 1. 配置 hibernate 的事务管理器 -->
  <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"></property>
  </bean>
  <!-- 2. 配置事务属性 -->
   <!-- 配置哪些方法要加入事务控制 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 让所有的方法都加入事务管理,为了提高效率,可以把一些查询之类的方法设置为只读事务 -->
            <tx:method name="*" propagation="REQUIRED" read-only="true"/>
            <!-- 以下方法都是可能涉及写改的方法,就无法设置为只读 -->
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="save*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
  <!-- 3. 配置事务切入点, 再把事务属性和事务切入点关联起来 -->
  <aop:config>
    <aop:pointcut expression="execution(* com.jane.ssh.service.*.*(..))" id="txPointcut"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
  </aop:config>
  <!-- 开启HibernateTemplate,并且为其注入SessionFactory
    使用HibernateTemplate不太方便的就是要获取session得通过getSessionFactory()方法获取
    注意:这里之所以配置这个是因为Dao继承了HibernateDaoSupport
  -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
</beans>

② hibernate.cfg.xml

由于数据源,*.hbm.xml都在applicationContext.xml中进行了配置,故而hibernate.cfg.xml极其简化:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
      <!-- 配置 hibernate 的基本属性 -->
      <!-- 方言 -->
      <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
      <!-- 是否显示及格式化 SQL -->
      <property name="hibernate.show_sql">true</property>
      <property name="hibernate.format_sql">true</property>
      <!-- 生成数据表的策略 -->
      <property name="hibernate.hbm2ddl.auto">update</property>
      <!-- 启用二级缓存 -->
    <property name="cache.use_second_level_cache">true</property>
      <!-- 配置使用的二级缓存的产品 -->
      <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
      <!-- 配置启用查询缓存 -->
      <property name="cache.use_query_cache">true</property>
    </session-factory>
</hibernate-configuration>

当然,通常情况下,会去掉hibernate.cfg.xml,而将Hibernate相关属性配置在sessionFactory中。


③ 常见的Hibernate注解示例

package domain;
import java.io.Serializable;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
@Entity
@Table(name="article_inf")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class Article implements Serializable{
  private static final long serialVersionUID = 48L;
  @Id @Column(name="article_id")
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Integer id;
  @ManyToOne(targetEntity=Login.class)
  @JoinColumn(name="user_id",referencedColumnName="user_id",nullable=false)
  private Login login;
  @Column(name="boss_id")
  private Integer bossId;
  @Temporal(TemporalType.TIMESTAMP)
  @Column(name="create_date")
  private Date createDate;
  @Temporal(TemporalType.TIMESTAMP)
  @Column(name="modify_date")
  private Date modifyDate;
  @Column(name="article_authority")
  private Integer authority;
  @Column(name="title")
  private String title;
  @Column
  private String writer;
  @ElementCollection(targetClass=String.class)
  @CollectionTable(name="art_content",joinColumns=@JoinColumn(name="article_id",nullable=false))
  @Column(name="content",length=5000) @OrderColumn(name="No_")
  private List<String> contents=new LinkedList<>();
  @OneToMany(targetEntity=ArticlePictures.class,orphanRemoval=true,mappedBy="article",cascade=CascadeType.ALL)
  private List<ArticlePictures> pictures=new LinkedList<>();
  @OneToMany(targetEntity=ArticleComments.class,orphanRemoval=true,mappedBy="article",cascade=CascadeType.ALL)
  private List<ArticleComments> comments=new LinkedList<>();
  @OneToMany(targetEntity=ArticleVisitors.class,orphanRemoval=true,mappedBy="article",cascade=CascadeType.ALL)
  private List<ArticleVisitors> visitors=new LinkedList<>();
  @OneToMany(targetEntity=ArticleCharm.class,orphanRemoval=true,mappedBy="article",cascade=CascadeType.ALL)
  private List<ArticleCharm> charm=new LinkedList<>();
  //id
  public void setId(Integer id){
    this.id=id;
  }
  public Integer getId(){
    return id;
  }
  //login
  public void setLogin(Login login){
    this.login=login;
  }
  public Login getLogin(){
    return login;
  }
  //bossId
  public void setBossId(Integer bid){
    this.bossId=bid;
  }
  public Integer getBossId(){
    return bossId;
  }
  //createDate
  public void setCreateDate(Date date){
    this.createDate=date;
  }
  public Date getCreateDate(){
    return createDate;
  }
  //modifyDate
  public void setModifyDate(Date date){
    this.modifyDate=date;
  }
  public Date getModifyDate(){
    return modifyDate;
  }
  //authority
  public void setAuthority(Integer author){
    this.authority=author;
  }
  public Integer getAuthority(){
    return authority;
  }
  //title
  public void setTitle(String title){
    this.title=title;
  }
  public String getTitle(){
    return title;
  }
  //writer
  public void setWriter(String writer){
    this.writer=writer;
  }
  public String getWriter(){
    return writer;
  }
  //contents
  public void setContents(List<String> con){
    this.contents=con;
  }
  public List<String> getContents(){
    return contents;
  }
  //pictures
  public void setPictures(List<ArticlePictures> pic){
    this.pictures=pic;
  }
  public List<ArticlePictures> getPictures(){
    return pictures;
  }
  //comments
  public void setComments(List<ArticleComments> coms){
    this.comments=coms;
  }
  public List<ArticleComments> getComments(){
    return comments;
  }
  //visitors
  public void setVisitors(List<ArticleVisitors> visitors){
    this.visitors=visitors;
  }
  public List<ArticleVisitors> getVisitors(){
    return visitors;
  }
  //charm
  public void setCharm(List<ArticleCharm> charm){
    this.charm=charm;
  }
  public List<ArticleCharm> getCharm(){
    return charm;
  }
}

至于Hibernate注解有哪些,注解如何使用,请参考系列博文:Spring Data JPA那些事。毕竟,JPA的默认实现就是Hibernate。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
JSON 前端开发 Java
深入理解 Spring Boot 中日期时间格式化:@DateTimeFormat 与 @JsonFormat 完整实践
在 Spring Boot 开发中,日期时间格式化是前后端交互的常见痛点。本文详细解析了 **@DateTimeFormat** 和 **@JsonFormat** 两个注解的用法,分别用于将前端传入的字符串解析为 Java 时间对象,以及将时间对象序列化为指定格式返回给前端。通过完整示例代码,展示了从数据接收、业务处理到结果返回的全流程,并总结了解决时区问题和全局配置的最佳实践,助你高效处理日期时间需求。
167 0
|
1月前
|
存储 Java 数据库
Spring Boot 注册登录系统:问题总结与优化实践
在Spring Boot开发中,注册登录模块常面临数据库设计、密码加密、权限配置及用户体验等问题。本文以便利店销售系统为例,详细解析四大类问题:数据库字段约束(如默认值缺失)、密码加密(明文存储风险)、Spring Security配置(路径权限不当)以及表单交互(数据丢失与提示不足)。通过优化数据库结构、引入BCrypt加密、完善安全配置和改进用户交互,提供了一套全面的解决方案,助力开发者构建更 robust 的系统。
55 0
|
1月前
|
Java 开发者 微服务
Spring Cloud OpenFeign详解与实践
总结起来说,Spring Cloud OpenFeign提供了一种简单易懂且高效的方式去实现微服务之间通信.它隐藏了许多复杂性,并且允许开发者以声明式方式编写HTTP客户端代码.如果你正在开发基于Spring Cloud 的微服务架构系统,Spring Cloud Open Feign是一个非常好用且强大工具.
153 33
|
1月前
|
JSON 前端开发 Java
深入理解 Spring Boot 中日期时间格式化:@DateTimeFormat 与 @JsonFormat 完整实践
在 Spring Boot 开发中,处理前后端日期交互是一个常见问题。本文通过 **@DateTimeFormat** 和 **@JsonFormat** 两个注解,详细讲解了如何解析前端传来的日期字符串以及以指定格式返回日期数据。文章从实际案例出发,结合代码演示两者的使用场景与注意事项,解决解析失败、时区偏差等问题,并提供全局配置与局部注解的实践经验。帮助开发者高效应对日期时间格式化需求,提升开发效率。
214 2
|
2月前
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot中使用拦截器——拦截器使用实例
本文主要讲解了Spring Boot中拦截器的使用实例,包括判断用户是否登录和取消特定拦截操作两大场景。通过token验证实现登录状态检查,未登录则拦截请求;定义自定义注解@UnInterception实现灵活取消拦截功能。最后总结了拦截器的创建、配置及对静态资源的影响,并提供两种配置方式供选择,帮助读者掌握拦截器的实际应用。
46 0
|
3月前
|
前端开发 Java Nacos
🛡️Spring Boot 3 整合 Spring Cloud Gateway 工程实践
本文介绍了如何使用Spring Cloud Alibaba 2023.0.0.0技术栈构建微服务网关,以应对微服务架构中流量治理与安全管控的复杂性。通过一个包含鉴权服务、文件服务和主服务的项目,详细讲解了网关的整合与功能开发。首先,通过统一路由配置,将所有请求集中到网关进行管理;其次,实现了限流防刷功能,防止恶意刷接口;最后,添加了登录鉴权机制,确保用户身份验证。整个过程结合Nacos注册中心,确保服务注册与配置管理的高效性。通过这些实践,帮助开发者更好地理解和应用微服务网关。
281 0
🛡️Spring Boot 3 整合 Spring Cloud Gateway 工程实践
|
4月前
|
搜索推荐 NoSQL Java
微服务架构设计与实践:用Spring Cloud实现抖音的推荐系统
本文基于Spring Cloud实现了一个简化的抖音推荐系统,涵盖用户行为管理、视频资源管理、个性化推荐和实时数据处理四大核心功能。通过Eureka进行服务注册与发现,使用Feign实现服务间调用,并借助Redis缓存用户画像,Kafka传递用户行为数据。文章详细介绍了项目搭建、服务创建及配置过程,包括用户服务、视频服务、推荐服务和数据处理服务的开发步骤。最后,通过业务测试验证了系统的功能,并引入Resilience4j实现服务降级,确保系统在部分服务故障时仍能正常运行。此示例旨在帮助读者理解微服务架构的设计思路与实践方法。
208 17
|
4月前
|
人工智能 自然语言处理 Java
Spring Cloud Alibaba AI 入门与实践
本文将介绍 Spring Cloud Alibaba AI 的基本概念、主要特性和功能,并演示如何完成一个在线聊天和在线画图的 AI 应用。
736 7
|
5月前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
327 4
|
5月前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
95 14