Spring ORM 示例 - JPA、Hibernate、事务

欢迎来到春 ORM 示例教程. 今天我们将使用 Hibernate JPA 交易管理来研究春 ORM 示例。

  • 依赖注射 (@Autowired 注释)
  • JPA EntityManager (由Hibernate提供)
  • 注释的交易方法 (@交易注释)

春天的例子

spring orm example, spring orm, spring jpa hibernate example, spring hibernate transaction management, spring hibernate jpa I have used in-memory database for Spring ORM example, so no need for any database setup (but you can change it to any other database in the spring.xml datasource section). This is a Spring ORM standalone application to minimize all dependencies (but you can easily change it to a web project by configuration if you get familiar with spring). NOTE: For Spring AOP based Transactional (without @Transactional annotation) method resolution approach please check this tutorial: Spring ORM AOP Transaction Management. Below image shows our final Spring ORM example project. Spring ORM, Spring ORM Example, Spring ORM JPA Hibernate Let's go through each of the Spring ORM example project components one by one.

春季依赖性 ORM Maven

下面是我们最后的 pom.xml 文件有春 ORM 依赖性. 我们在我们的春 ORM 示例中使用了春 4 和冬眠 4。

 1<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 2    <modelVersion>4.0.0</modelVersion>
 3
 4    <groupId>hu.daniel.hari.learn.spring</groupId>
 5    <artifactId>Tutorial-SpringORMwithTX</artifactId>
 6    <version>0.0.1-SNAPSHOT</version>
 7    <packaging>jar</packaging>
 8
 9    <properties>
10    	<!-- Generic properties -->
11    	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
12    	<java.version>1.7</java.version>
13
14    	<!-- SPRING & HIBERNATE / JPA -->
15    	<spring.version>4.0.0.RELEASE</spring.version>
16    	<hibernate.version>4.1.9.Final</hibernate.version>
17
18    </properties>
19
20    <dependencies>
21    	<!-- LOG -->
22    	<dependency>
23    		<groupId>log4j</groupId>
24    		<artifactId>log4j</artifactId>
25    		<version>1.2.17</version>
26    	</dependency>
27
28    	<!-- Spring -->
29    	<dependency>
30    		<groupId>org.springframework</groupId>
31    		<artifactId>spring-context</artifactId>
32    		<version>${spring.version}</version>
33    	</dependency>
34    	<dependency>
35    		<groupId>org.springframework</groupId>
36    		<artifactId>spring-orm</artifactId>
37    		<version>${spring.version}</version>
38    	</dependency>
39
40    	<!-- JPA Vendor -->
41    	<dependency>
42    		<groupId>org.hibernate</groupId>
43    		<artifactId>hibernate-entitymanager</artifactId>
44    		<version>${hibernate.version}</version>
45    	</dependency>
46
47    	<!-- IN MEMORY Database and JDBC Driver -->
48    	<dependency>
49    		<groupId>hsqldb</groupId>
50    		<artifactId>hsqldb</artifactId>
51    		<version>1.8.0.7</version>
52    	</dependency>
53
54    </dependencies>
55
56    <build>
57    	<plugins>
58    		<plugin>
59    			<groupId>org.apache.maven.plugins</groupId>
60    			<artifactId>maven-compiler-plugin</artifactId>
61    			<version>3.1</version>
62    			<configuration>
63    				<source>${java.version}</source>
64    				<target>${java.version}</target>
65    			</configuration>
66    		</plugin>
67    	</plugins>
68    </build>
69
70</project>

*我们需要春季背景春季蠕虫作为春季依赖 *我们使用 Hibernate-entitymanager作为JPA实现。hibernate-entitymanager依赖hibernate-core,这就是为什么我们不必明确地将 hibernate-core放入pom.xml中。

春季 ORM 模型类

我们可以在模型豆中使用标准的JPA注释来绘制,因为Hibernate提供了JPA实现。

 1package hu.daniel.hari.learn.spring.orm.model;
 2
 3import javax.persistence.Entity;
 4import javax.persistence.Id;
 5
 6@Entity
 7public class Product {
 8
 9    @Id
10    private Integer id;
11    private String name;
12
13    public Product() {
14    }
15
16    public Product(Integer id, String name) {
17    	this.id = id;
18    	this.name = name;
19    }
20    public Integer getId() {
21    	return id;
22    }
23    public void setId(Integer id) {
24    	this.id = id;
25    }
26    public String getName() {
27    	return name;
28    }
29    public void setName(String name) {
30    	this.name = name;
31    }
32
33    @Override
34    public String toString() {
35    	return "Product [id=" + id + ", name=" + name + "]";
36    }
37
38}

我们使用@Entity@Id JPA 注释来将我们的 POJO 定义为实体并定义其主要密钥。

春季 DAO 班级

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

 1package hu.daniel.hari.learn.spring.orm.dao;
 2
 3import hu.daniel.hari.learn.spring.orm.model.Product;
 4
 5import java.util.List;
 6
 7import javax.persistence.EntityManager;
 8import javax.persistence.PersistenceContext;
 9
10import org.springframework.stereotype.Component;
11
12@Component
13public class ProductDao {
14
15    @PersistenceContext
16    private EntityManager em;
17
18    public void persist(Product product) {
19    	em.persist(product);
20    }
21
22    public List<Product> findAll() {
23    	return em.createQuery("SELECT p FROM Product p").getResultList();
24    }
25
26}
  • @Component 是 Spring 注释,告诉 Spring 容器,我们可以通过 Spring IoC (Dependency Injection) 使用这个类。
  • 我们使用 JPA @PersistenceContext 注释,表示 EntityManager 的依赖注入。

春季服务班级

我们的简单服务类有2种写法和1种读法 - 添加,添加All和列表All。

 1package hu.daniel.hari.learn.spring.orm.service;
 2
 3import hu.daniel.hari.learn.spring.orm.dao.ProductDao;
 4import hu.daniel.hari.learn.spring.orm.model.Product;
 5
 6import java.util.Collection;
 7import java.util.List;
 8
 9import org.springframework.beans.factory.annotation.Autowired;
10import org.springframework.stereotype.Component;
11import org.springframework.transaction.annotation.Transactional;
12
13@Component
14public class ProductService {
15
16    @Autowired
17    private ProductDao productDao;
18
19    @Transactional
20    public void add(Product product) {
21    	productDao.persist(product);
22    }
23    
24    @Transactional
25    public void addAll(Collection<Product> products) {
26    	for (Product product : products) {
27    		productDao.persist(product);
28    	}
29    }
30
31    @Transactional(readOnly = true)
32    public List<Product> listAll() {
33    	return productDao.findAll();
34
35    }
36
37}
  • 我们使用春季 @Autowired 注释将 ProductDao 注入我们的服务类 *我们希望使用交易管理,所以方法被注释为 @Transactional 春季注释。

春季 ORM 示例 Bean 配置 XML

我们的春 ORM 示例项目 java 课程已经准备好了,让我们现在看看我们的春豆配置文件。

 1<?xml version="1.0" encoding="UTF-8"?>
 2<beans xmlns="https://www.springframework.org/schema/beans" 
 3    xmlns:p="https://www.springframework.org/schema/p"
 4    xmlns:context="https://www.springframework.org/schema/context" 
 5    xmlns:tx="https://www.springframework.org/schema/tx" 
 6    xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
 7    xsi:schemaLocation="
 8    	https://www.springframework.org/schema/beans
 9    	https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
10    	https://www.springframework.org/schema/context
11    	https://www.springframework.org/schema/context/spring-context-3.0.xsd
12    	https://www.springframework.org/schema/tx
13    	https://www.springframework.org/schema/tx/spring-tx.xsd
14    	">
15    
16    <!-- Scans the classpath for annotated components that will be auto-registered as Spring beans -->
17    <context:component-scan base-package="hu.daniel.hari.learn.spring" />
18    <!-- Activates various annotations to be detected in bean classes e.g: @Autowired -->
19    <context:annotation-config />
20
21    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
22    	<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
23    	<property name="url" value="jdbc:hsqldb:mem://productDb" />
24    	<property name="username" value="sa" />
25    	<property name="password" value="" />
26    </bean>
27    
28    <bean id="entityManagerFactory" 
29    		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
30    		p:packagesToScan="hu.daniel.hari.learn.spring.orm.model"
31            p:dataSource-ref="dataSource"
32    		>
33    	<property name="jpaVendorAdapter">
34    		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
35    			<property name="generateDdl" value="true" />
36    			<property name="showSql" value="true" />
37    		</bean>
38    	</property>
39    </bean>
40
41    <!-- Transactions -->
42    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
43    	<property name="entityManagerFactory" ref="entityManagerFactory" />
44    </bean>
45    <!-- enable the configuration of transactional behavior based on annotations -->
46    <tx:annotation-driven transaction-manager="transactionManager" />
47
48</beans>
  1. 联合国 首先,我们告诉Spring,我们希望对Spring组件(Services,DAOs)使用类路径扫描,而不是在Spring xml中逐一定义. 我们还启用了 Spring 注解检测.
  2. 正在添加数据源, 即目前 HSQLDB 的模组数据库 。 (_) (英语). 我们建立了一个联合企业管理局 " 实体经理Factory " ,该应用程序将用来获得实体经理。 Spring支持3种不同的方式来做到这一点,我们使用了地方集装箱实体经理FactoryBean来充分发挥联合行动计划的能力。 我们设置了 本地建筑实体管理 FactoryBean 属性为:
  3. 包 ToScan 属性指向我们的示范类包。 (_) ) 2. 春季配置文件早些时候定义的数据源.
  4. jpa范多尔 适配器为Hibernate并设置一些休眠属性.
  5. 我们创建了"春天"平台 作为 Jpa 交易管理器的管理者实例 。 此交易管理器适用于使用单个 JPA 实体管理器Factory 进行交易数据访问的应用程序. ( (英语). 5. 我们能根据说明来配置交易行为,我们设置了我们创建的交易管理器. (单位:千美元) (英语)

春季ORM Hibernate JPA示例测试计划

我们的春季ORM JPA Hibernate示例项目已经准备好了,所以让我们为我们的应用程序写一个测试计划。

 1public class SpringOrmMain {
 2    
 3    public static void main(String[] args) {
 4    	
 5    	//Create Spring application context
 6    	ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/spring.xml");
 7    	
 8    	//Get service from context. (service's dependency (ProductDAO) is autowired in ProductService)
 9    	ProductService productService = ctx.getBean(ProductService.class);
10    	
11    	//Do some data operation
12    	
13    	productService.add(new Product(1, "Bulb"));
14    	productService.add(new Product(2, "Dijone mustard"));
15    	
16    	System.out.println("listAll: " + productService.listAll());
17    	
18    	//Test transaction rollback (duplicated key)
19    	
20    	try {
21    		productService.addAll(Arrays.asList(new Product(3, "Book"), new Product(4, "Soap"), new Product(1, "Computer")));
22    	} catch (DataAccessException dataAccessException) {
23    	}
24    	
25    	//Test element list after rollback
26    	System.out.println("listAll: " + productService.listAll());
27    	
28    	ctx.close();
29    	
30    }
31}

您可以看到我们如何轻松地从一个主要方法开始 Spring 容器。我们正在获得我们的第一个依赖注入入点,服务类实例。 ProductDao 类引用注入到 ProductService 类之后,春节背景被初始化。我们获得了 ProducService 实例后,我们可以测试它的方法,所有方法调用将是由于春节的代理机制的交易。我们也在这个例子中测试回归。

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

请注意,第二个交易被滚回来,这就是为什么产品列表没有改变的原因。 如果您使用来自附加源的 log4j.properties 文件,您可以看到在帽子下发生了什么。 参考: https://docs.spring.io/spring/docs/current/spring-framework-reference/html/orm.html您可以从下面的链接下载最后的 Spring ORM JPA Hibernate 示例项目,并与它一起玩,以了解更多。

下载 春季 ORM 与交易项目

Published At
Categories with 技术
Tagged with
comments powered by Disqus