Spring使用JPA进行Dao层的数据访问以及事务管理

Spring使用JPA进行Dao层的数据访问以及事务管理

在上篇文章中,我们完成了SSH+JPA+Mysql的整合:

https://blog.csdn.net/a745233700/article/details/81413306

在这篇文章中,我们主要介绍如何通过Spring使用JPA进行Dao层的数据访问以及事务管理:

 

一、前言:

1、在SSH整合项目中,获取hibernate中的sessionFactory有两种方式:

(1)第一种是手动获取src目录下hibernate.cfg.xml配置文件:(在dao层的代码)

SessionFactory sessionFactory = new Configuration().configure(“hibernate.cfg.xml”).buildSessionFactory();

(2)第二种是使用spring注入:

在spring的配置文件applicationContext.xml文件中进行sessionFactory和dataSource的bean的配置,之后在dao层的实现类中定义一个属性为SessionFactory,使用spring注入。

(3)在JPA中的EntityManagerFactory类似于Hibernate中的SessionFactory;EntityManager类似于Session,EntityManager是实体类管理器,是由EntityManagerFactory创建,每一个EntityManagerFactory称为一个持久化单元,每个持久化单元可以认为是一个数据源的映射(数据源可以理解为一个数据库,我们可以在应用服务器中配置不同的数据源,即使用不同的persistenceUtil来映射这些数据源,从而可以实现不同的数据库之间的操作。)       

2、同理,在JPA中,获取EntityManagerFactory也是使用这两种方式来实现:

(1)第一种是通过persistence.xml文件手动获取EntityManagerFactory(可以参考上一篇博客,链接在最顶端)

(2)第二种是使用spring注入的方式是实现获取EntityManagerFactory。

 

 

二、使用spring注入的方式是实现获取EntityManagerFactory。

1、在spring配置文件创建一个bean标签,目的创建一个EntityManagerFactory,这里不同于sessionFactory的bean,因为这里读取的是src目录下的META-INF目录下的persistence.xml 即JPA的配置文件,所以在下面设置的是持久化单元名”myjpa”,对应JPA配置文件中的单元名字。

	<!-- SSH与JPA整合:FactoryBean,由LocalSessionFactoryBean改成LocalContainerEntityManagerFactoryBean -->
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<!-- 读取src目录下META-INF下的persistence.xml,value值是persistence-unit标签的name的值 -->
		<property name="persistenceUnitName" value="myjpa"/>  
		<!-- 数据源 -->
		<property name="dataSource" ref="dataSource" />
		<!-- 配置JPA提供商的适配器 -->
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
		</property>
		<!-- 配置JPA基本属性 -->
		<property name="jpaProperties">
                    <props>
                        <prop key="hibernate.show_sql">true</prop>
                        <prop key="hibernate.format_sql">true</prop>
                        <prop key="hibernate.hbm2ddl.auto">update</prop>
                    </props>
                </property>
                <!-- 配置实体类所在的路径 -->
		<property name="packagesToScan" value="com.zwp.jpa.domain" />
	</bean>

2、persistence.xml文件:(因为数据源在其他地方配置,所有该文件很简洁)

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">  
  
	<persistence-unit name="myjpa" transaction-type="RESOURCE_LOCAL">  
	   <properties>  
		    <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />  
		    <property name="hibernate.max_fetch_depth" value="3" />  
	   </properties>  
	</persistence-unit>
</persistence>

3、在Dao层设置并注入EntityManagerFactory对象,注入之后,我们就可以获取到EntityManager并直接使用了:

//JPA的Dao层
public class JpaDaoImpl implements JpaDao {
	//注入EntityManagerFactory对象
	@Autowired
	@Qualifier("entityManagerFactory")
	private EntityManagerFactory entityManagerFactory;
	
	@Override
	public void jpaTest() {
		EntityManager em= entityManagerFactory.createEntityManager();
		em.getTransaction().begin();
		
		//业务逻辑开始
		Orders orders=new Orders();
		orders.setAmount(34f);
		orders.setOrderid("999");
		
		OrderItem orderItem1=new OrderItem();
		orderItem1.setProductName("篮球");
		orderItem1.setSellPrice(150f);
		OrderItem orderItem2=new OrderItem();
		orderItem2.setProductName("足球");
		orderItem2.setSellPrice(90f);
		
		orders.addOrderItem(orderItem1);
		orders.addOrderItem(orderItem2);
		
		em.merge(orders);
		//业务逻辑开始结束
		
		em.getTransaction().commit();
		em.close();
		//entityManagerFactory.close();//这里不需要我们进行关闭
	}
}

(1)@Qualifier(“entityManagerFactory”)注解中的entityManagerFactory对应的是spring配置文件中JPA配置的entityManagerFactory的id属性值。

 (2)在这里,可以使用spring的注解,或者是使用bean注入的方式,这里使用的spring的注入进行注入。使用spring注解需要在spring配置文件中添加一个注解的解析器:<context:annotation-config></context:annotation-config>

(3)至此,使用Spring注入EntityManagerFactory,并精心Dao层的数据访问程序就完成了。

 

 

三、JPA的事务管理:

首先建立在上面使用的spring注入JPA的基础之上,再加入JPA的事务管理。好处是我们自己不需要手动开启、提交事务和关闭资源,因为这些都是重复的代码,做的事情都是同一样的。所以可以交给事务来管理。

1、在spring配置文件applicationContext.xml中添加事务管理:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>

<!-- 开启事务注解 -->
<!-- 第一步:开启注解驱动;第二步:在service上使用注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

2、在Dao层的类上面加上@Transactional注解,并在类里面定义EntityManager对象,并在其上面使用@PersistenceContext注解,之后就可以直接使用这个EntityManager进行CURD操作。

这个属性的定义是建立在JPA的事务管理之上的,当web容器读取spring配置文件中的EntityManagerFactory后会自动创建一个EntityManager,然后根据在dao类中定义的这个属性进行注入。代码如下:

//JPA的Dao层
@Transactional
public class JpaDaoImpl implements JpaDao {
	//注入EntityManagerFactory对象
	@Autowired
	@Qualifier("entityManagerFactory")
	private EntityManagerFactory entityManagerFactory;
	
	//事务管理
	@PersistenceContext
	private EntityManager em;
	
	@Override
	public void jpaTest() {
		Orders orders=new Orders();
		orders.setAmount(34f);
		orders.setOrderid("999");
		
		OrderItem orderItem1=new OrderItem();
		orderItem1.setProductName("篮球");
		orderItem1.setSellPrice(150f);
		OrderItem orderItem2=new OrderItem();
		orderItem2.setProductName("足球");
		orderItem2.setSellPrice(90f);
		
		orders.addOrderItem(orderItem1);
		orders.addOrderItem(orderItem2);
		
		em.merge(orders);
	}
}

加入事务管理之后,我们的Dao层代码就可以减少为上面这样子了,不需要由我们手动开启、提交事务和关闭资源这些重复性工作了,全部交由事务进行管理。

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/114705.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 无刷直流电机模糊PID控制「建议收藏」

    无刷直流电机在克服了有刷直流电机机械换相缺点的同时,又具有结构简单、运行可靠以及调速性能好等优点,在很多领域中得到了广泛的应用。本次课题阐述了无刷直流电机的基本结构、运行原理和数学模型,并以无刷直流电机为被控对象,根据电机的特点和控制要求确定了三闭环控制策略,分别是位置、转速及电流环控制三者之间实行串级连接。采用模糊PID控制理论,搭建无刷直流电机和控制器的仿真模型来验证电机控制策略的可行性,使要能使伺服控制器的具体性能满足:无静差,响应快,超调量小的设计要求。结合三闭环控制结构的特点,在位置环中采用模

  • query指定范围提取数据_嵌套查询和子查询

    query指定范围提取数据_嵌套查询和子查询repeater嵌套查询。代码如下:代码usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Web;usingSystem.Web.UI;usingSystem.Web.UI.WebControls;usingSystem.Data;namespa…

    2022年10月10日
  • openwrt 通过scp命令传文件到windows

    openwrt 通过scp命令传文件到windows1、在windows上安装winsshd软件,用于打开ssh服务。2、从linux系统复制文件到windows系统:scp-r/home/yu/testyulir@192.168.200.230:/d:/3、在linux环境下,将windows下的文件复制到linux系统中:scp-ryulir@192.168.200.230:/d:/test/home/yu/感觉上述麻烦…

  • 求两个向量的夹角_数量积和向量积的公式

    求两个向量的夹角_数量积和向量积的公式如图所示,我们要计算任意两个向量之间的夹角。(图中的坐标数字是估计值,随手给定)python代码如下importmathAB=[1,-3,5,-1]CD=[4,1,4.5,4.5]EF=[2,5,-2,6]PQ=[-3,-4,1,-6]defangle(v1,v2):dx1=v1[2]-v1[0]dy1=v1[3]-v1[1]dx2=v2[2]-v2[…

  • dataset数据集有哪些_数据集类型

    dataset数据集有哪些_数据集类型datasets数据集​ 分享一些学习到的知识​ sklearn的数据集库datasets提供很多不同的数据集,主要包含以下几大类:玩具数据集真实世界中的数据集样本生成器样本图片svmlight或libsvm格式的数据从openml.org下载的数据从外部加载的数据用的比较多的就是1和3,这里进行主要介绍,其他的会进行简单介绍,但是不建议使用。玩具数据集​ scikit-learn内置有一些小型标准数据集,不需要从某个外部网站下载任何文件,用

  • 通过和resnet18和resnet50理解PyTorch的ResNet模块

    通过和resnet18和resnet50理解PyTorch的ResNet模块文章目录模型介绍resnet18模型流程总结resnet50总结resnet和resnext的框架基本相同的,这里先学习下resnet的构建,感觉高度模块化,很方便。本文算是对PyTorch源码解读之torchvision.modelsResNet代码的详细理解,另外,强烈推荐这位大神的PyTorch的教程!模型介绍resnet的模型可以直接通过torchvision导入,可以通过pretr…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号