Spring ORM示例 - JPA,Hibernate,Transaction

欢迎来到Spring ORM示例教程。今天我们将使用Hibernate JPA事务管理来研究Spring ORM示例。我将向您展示一个具有以下功能的Spring独立应用程序的一个非常简单的示例。

  • 依赖注入(@Autowired annotation)
  • JPA EntityManager(由Hibernate提供)
  • 带注释的事务方法(@Transactional注释)

目录[ 隐藏 ]

  • 1 Spring ORM示例

    • 1.1 Spring ORM Maven依赖项
    • 1.2 Spring ORM模型类
    • 1.3 Spring ORM DAO类
    • 1.4 Spring ORM服务类
    • 1.5 Spring ORM示例Bean配置XML
    • 1.6 Spring ORM Hibernate JPA示例测试程序

Spring ORM示例

我在Spring ORM示例中使用了内存数据库,因此不需要任何数据库设置(但您可以将其更改为spring.xml数据源部分中的任何其他数据库)。这是一个Spring ORM独立应用程序,可以最大限度地减少所有依赖项(但如果您熟悉spring,则可以通过配置轻松地将其更改为Web项目)。

注意:对于基于Spring AOP的Transactional(没有@Transactional注释)方法解析方法,请查看本教程:Spring ORM AOP事务管理。

下图显示了我们最终的Spring ORM示例项目。

让我们逐个浏览每个Spring ORM示例项目组件。

Spring ORM Maven依赖项

下面是我们最终的具有Spring ORM依赖项的pom.xml文件。我们在Spring ORM示例中使用了Spring 4和Hibernate 4。


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>hu.daniel.hari.learn.spring</groupId><artifactId>Tutorial-SpringORMwithTX</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><properties><!-- Generic properties --><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.7</java.version><!-- SPRING & HIBERNATE / JPA --><spring.version>4.0.0.RELEASE</spring.version><hibernate.version>4.1.9.Final</hibernate.version></properties><dependencies><!-- LOG --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><!-- Spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>${spring.version}</version></dependency><!-- JPA Vendor --><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>${hibernate.version}</version></dependency><!-- IN MEMORY Database and JDBC Driver --><dependency><groupId>hsqldb</groupId><artifactId>hsqldb</artifactId><version>1.8.0.7</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin></plugins></build></project>
  • 我们需要spring-contextspring-orm作为Spring依赖。
  • 我们将hibernate-entitymanagerHibernate用作JPA实现。hibernate-entitymanager依赖于hibernate-core这个原因我们不必将hibernate-core明确地放在pom.xml中。它通过maven传递依赖进入我们的项目。
  • 我们还需要JDBC驱动程序作为数据库访问的依赖项。我们正在使用包含JDBC驱动程序和内存数据库的HSQLDB。

Spring ORM模型类

我们可以使用标准JPA注释在我们的模型bean中进行映射,因为Hibernate提供了JPA实现。


package hu.daniel.hari.learn.spring.orm.model;import javax.persistence.Entity;
import javax.persistence.Id;@Entity
public class Product {@Idprivate Integer id;private String name;public Product() {}public Product(Integer id, String name) {this.id = id;this.name = name;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Product [id=" + id + ", name=" + name + "]";}}

我们使用@Entity@IdJPA注释来将我们的POJO限定为实体并定义它的主键。

Spring ORM DAO Class

我们创建了一个非常简单的DAO类,它提供了persist和findALL方法。


package hu.daniel.hari.learn.spring.orm.dao;import hu.daniel.hari.learn.spring.orm.model.Product;import java.util.List;import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;import org.springframework.stereotype.Component;@Component
public class ProductDao {@PersistenceContextprivate EntityManager em;public void persist(Product product) {em.persist(product);}public List<Product> findAll() {return em.createQuery("SELECT p FROM Product p").getResultList();}}
  • @Component是Spring注释,告诉Spring容器我们可以通过Spring IoC(依赖注入)使用这个类。
  • 我们使用JPA @PersistenceContext注释来指示对EntityManager的依赖注入。Spring根据spring.xml配置注入适当的EntityManager实例。

Spring ORM服务类

我们的简单服务类有2个写入和1个读取方法 - add,addAll和listAll。


package hu.daniel.hari.learn.spring.orm.service;import hu.daniel.hari.learn.spring.orm.dao.ProductDao;
import hu.daniel.hari.learn.spring.orm.model.Product;import java.util.Collection;
import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;@Component
public class ProductService {@Autowiredprivate ProductDao productDao;@Transactionalpublic void add(Product product) {productDao.persist(product);}@Transactionalpublic void addAll(Collection<Product> products) {for (Product product : products) {productDao.persist(product);}}@Transactional(readOnly = true)public List<Product> listAll() {return productDao.findAll();}}
  • 我们使用Spring @Autowired注释在我们的服务类中注入ProductDao。
  • 我们希望使用事务管理,因此使用@TransactionalSpring注释对方法进行注释。listAll方法只读取数据库,因此我们将@Transactional注释设置为只读以进行优化。

Spring ORM示例Bean配置XML

我们的spring ORM示例项目java类已经准备就绪,现在让我们来看看我们的spring bean配置文件。

spring.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- Scans the classpath for annotated components that will be auto-registered as Spring beans --><context:component-scan base-package="hu.daniel.hari.learn.spring" /><!-- Activates various annotations to be detected in bean classes e.g: @Autowired --><context:annotation-config /><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="org.hsqldb.jdbcDriver" /><property name="url" value="jdbc:hsqldb:mem://productDb" /><property name="username" value="sa" /><property name="password" value="" /></bean><bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"p:packagesToScan="hu.daniel.hari.learn.spring.orm.model"p:dataSource-ref="dataSource"><property name="jpaVendorAdapter"><bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><property name="generateDdl" value="true" /><property name="showSql" value="true" /></bean></property></bean><!-- Transactions --><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="entityManagerFactory" /></bean><!-- enable the configuration of transactional behavior based on annotations --><tx:annotation-driven transaction-manager="transactionManager" /></beans>
  1. 首先我们告诉spring我们要对Spring组件(服务,DAO)使用类路径扫描,而不是在spring xml中逐个定义它们。我们还启用了Spring注释检测。
  2. 添加数据源,即当前HSQLDB内存数据库。
  3. 我们设置了一个JPA EntityManagerFactory,应用程序将使用它来获取EntityManager。Spring支持3种不同的方法,我们已经使用LocalContainerEntityManagerFactoryBean了完整的JPA功能。

    我们将LocalContainerEntityManagerFactoryBean属性设置为:

    1. packagesToScan属性指向我们的模型类包。
    2. 早期在spring配置文件中定义的datasource。
    3. jpaVendorAdapter作为Hibernate并设置了一些hibernate属性。
  4. 我们将Spring PlatformTransactionManager实例创建为JpaTransactionManager。此事务管理器适用于使用单个JPA EntityManagerFactory进行事务数据访问的应用程序。
  5. 我们基于注释启用事务行为的配置,并设置我们创建的transactionManager。

Spring ORM Hibernate JPA示例测试程序

我们的spring ORM JPA Hibernate示例项目已经准备就绪,所以让我们为我们的应用程序编写一个测试程序。


public class SpringOrmMain {public static void main(String[] args) {//Create Spring application contextClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/spring.xml");//Get service from context. (service's dependency (ProductDAO) is autowired in ProductService)ProductService productService = ctx.getBean(ProductService.class);//Do some data operationproductService.add(new Product(1, "Bulb"));productService.add(new Product(2, "Dijone mustard"));System.out.println("listAll: " + productService.listAll());//Test transaction rollback (duplicated key)try {productService.addAll(Arrays.asList(new Product(3, "Book"), new Product(4, "Soap"), new Product(1, "Computer")));} catch (DataAccessException dataAccessException) {}//Test element list after rollbackSystem.out.println("listAll: " + productService.listAll());ctx.close();}
}

您可以看到我们可以轻松地从main方法启动Spring容器。我们得到了第一个依赖注入入口点,即服务类实例。初始化spring上下文后ProductDao注入类的类引用ProductService

在我们得到ProducService实例之后,我们可以测试它的方法,由于Spring的代理机制,所有方法调用都是事务性的。我们还在此示例中测试回滚。

如果您在春季ORM示例测试程序之上运行,您将获得以下日志。


Hibernate: insert into Product (name, id) values (?, ?)
Hibernate: insert into Product (name, id) values (?, ?)
Hibernate: select product0_.id as id0_, product0_.name as name0_ from Product product0_
listAll: [Product [id=1, name=Bulb], Product [id=2, name=Dijone mustard]]
Hibernate: insert into Product (name, id) values (?, ?)
Hibernate: insert into Product (name, id) values (?, ?)
Hibernate: insert into Product (name, id) values (?, ?)
Hibernate: select product0_.id as id0_, product0_.name as name0_ from Product product0_
listAll: [Product [id=1, name=Bulb], Product [id=2, name=Dijone mustard]]

请注意,第二个事务将回滚,这就是产品列表未更改的原因。

如果您使用log4j.properties来自附加源的文件,您可以看到幕后发生了什么。

参考文献:http:
//docs.spring.io/spring/docs/current/spring-framework-reference/html/orm.html

您可以从下面的链接下载最终的Spring ORM JPA Hibernate示例项目,并使用它来了解更多信息。

使用Transaction Project下载Spring ORM

Spring ORM示例 - JPA,Hibernate,Transaction相关推荐

  1. orm jpa_Spring ORM示例– JPA,Hibernate,事务

    orm jpa Welcome to the Spring ORM Example Tutorial. Today we will look into Spring ORM example using ...

  2. Spring ORM示例 - 带有AOP事务管理

    Spring ORM示例 - 带有AOP事务管理 这是一个非常简单的Spring ORM示例,向您展示如何使用Spring配置应用程序 依赖注入(@Autowired annotation), JPA ...

  3. spring aop示例_具有AOP事务管理的Spring ORM示例

    spring aop示例 This is a very simple Spring ORM example that shows you how to configure an application ...

  4. 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(四):使用 命名空间 简化配置...

    在(三)里面.我们引入了 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBe ...

  5. 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(六): 一些常用的数据库 注解...

    一. 实体 Bean 每个持久化POJO类都是一个实体Bean, 通过在类的定义中使用 @Entity 注解来进行声明. 声明实体Bean @Entity public class Flight im ...

  6. 《Java Web高级编程——涵盖WebSockets、Spring Framework、JPA H

    2019独角兽企业重金招聘Python工程师标准>>> <Java Web高级编程--涵盖WebSockets.Spring Framework.JPA Hibernate和S ...

  7. Primefaces,Spring 4 with JPA(Hibernate 4 / EclipseLink)示例教程

    Primefaces,Spring 4 with JPA(Hibernate 4 / EclipseLink)示例教程 Java Persistence API是标准规范.它提供了一个由不同实现者框架 ...

  8. Spring ORM+Hibernate?Out!换 Spring Data JPA 吧!

    2019独角兽企业重金招聘Python工程师标准>>> 转载请注明出处:http://blog.csdn.net/anxpp/article/details/51415698,谢谢! ...

  9. jboss4.2.3_JBoss 4.2.x Spring 3 JPA Hibernate教程

    jboss4.2.3 在花费大量时间在网上搜索之后,尝试找到对几个项目使用Spring,JPA和Hibenate的最有效方法,我们得出了将在下面介绍的配置的结论. 将Spring与JPA和Hibern ...

最新文章

  1. emacs 搭建racket开发环境
  2. python爬虫案例-Python爬虫案例集合
  3. 像@Transactional一样利用注解自定义aop切片
  4. 【转】图解phpstorm常用快捷键
  5. 图像语义分割_图像语义分割(9)-DeepLabV3: 再次思考用于图像语义分割的空洞卷积...
  6. CDM CDP及传统备份技术对比
  7. LeetCode 5355. T 秒后青蛙的位置
  8. Vue.js 与 Webpack externals 的使用
  9. 检测和语义分割_分割和对象检测-第4部分
  10. win10计算机管理权限,win10如何获取管理员权限?win10获取最高权限的方法
  11. 转载:深圳入户和房价相关
  12. Gdrive 使用教程
  13. 云数据库Mysql 购买和使用(腾讯云为例)
  14. open cv轮廓周围绘制圆形和矩形
  15. 《现代控制理论》第四章
  16. 23种设计模式模式笔记+易懂案例
  17. win10/win7文件夹或文件查看方式怎么统一设置
  18. 机器人能源处理专题-机器人电源管理系统
  19. 如何查找Manifest merger failed with multiple errors问题原因
  20. Xcode插件所在的目录:~/Library/Application Support/Developer/Shared/Xcode/Plug-ins

热门文章

  1. jQuery: 插件开发模式详解 $.extend(), $.fn, $.widget()
  2. PHP XML操作类 xml2array -- 含节点属性
  3. double free or corruption 错误解决办法
  4. centos7/rhel7安装较高版本ruby2.2/2.3/2.4+
  5. Linux文件系统不是必须的,而是必要的!
  6. 【三维深度学习】多视角场景点云重建模型PointMVS
  7. private的用法,为什么要来一个取值方法和设置值方法
  8. dj鲜生-37-order应用-模型类创建
  9. godaddy最新域名优惠码永久有效
  10. 基于Node.js实现压缩和解压缩的方法