「Java开发指南」如何在MyEclipse中使用JPA和Spring管理事务?(二)

本教程中介绍一些基于JPA/ spring的特性,重点介绍JPA-Spring集成以及如何利用这些功能。您将学习如何:

  • 为JPA和Spring设置一个项目
  • 逆向工程数据库表来生成实体
  • 实现创建、检索、编辑和删除功能
  • 启用容器管理的事务

在上文中(点击这里回顾>>),我们为大家介绍了如何用JPA和Spring Facets创建一个Java项目以及逆向工程,本文将继续介绍如何创建一个应用并启用容器管理的事务等。

MyEclipse v2023.1.2离线版下载

3. 编写应用程序

现在MyEclipse已经生成了所有这些代码,您可以快速地专注于编写"业务逻辑",或者更具体地说,"实际执行任务的代码"。

JPA教程介绍了每个实体和DAO类的功能,以及运行一个简单场景的主要方法的基本大纲,包括:

  • 创建一个新实体并将其插入数据库
  • 检索实体
  • 更新实体
  • 删除实体

类似地,在本教程中您将看到如何使用Spring获取和使用DAO以及管理事务。

这个演示的起点是RunJPA.java类,看看这个类中的main方法。

java 复制代码
/* 1. Initialize the transactionManager and DAO */
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
txManager = ((JpaTransactionManager) ctx.getBean("transactionManager"));
dao = ProductlineDAO.getFromApplicationContext(ctx);

/* 2. Create a reference to our ID */
String productlineID = "Men Shoes";

/* 3. Save a new productline to the DB */
saveProductline(productlineID);

/* 4. Load the productline from DB to make sure it worked */
loadProductline(productlineID);

/* 5. Update the productline in the DB and check it */
updateProductline(productlineID);

/* 6. Delete the productline from the DB */
deleteProductline(productlineID);

用蓝色标记的代码部分是Spring调用,您可以在其中从bean配置中检索已配置的bean。请注意,由于您正在手动管理事务,因此还需要从bean配置中检索' transactionManager '。

剩下的项目,#2 - #6,简单地调用每个"做某事"的方法。

3.1 保存实体

第一个有趣的方法是"saveProductline",此方法的目的是创建一个新实体并将其存储在DB中。

java 复制代码
/* 1. Create a new Productline instance */
Productline newProductline = new Productline(productlineID,
"Shoes formen.", "<strong>MenShoes</strong>", null);

/* 2. Store our new product line in the DB */
TransactionStatus status = txManager
.getTransaction(new DefaultTransactionDefinition());
dao.save(newProductline);
txManager.commit(status);

首先,用一些基本值创建新的Productline实例。其次使用transactionManager,事务在将实体保存到DB之前开始。在保存实体之后,事务被提交。

手动管理事务的目的是因为作为开发人员,您知道"保存"操作的范围。根据应用程序的编写方式,一些操作的作用域可能包含许多数据库修改,将所有这些都包装在一个事务中是很重要的,以防在工作进行到一半时失败。您肯定不希望让数据处于一种状态,其中一些是正确的,而另一些是过时的。

3.2 检索实体

下一个方法使用分配给实体的ID从DB中检索实体,并显示其值,这确认保存操作成功。

java 复制代码
/* 1. Now retrieve the new product line, using the ID we created */
Productline loadedProductline = dao.findById(productlineID);

/* 2. Print out the product line information */
System.out.println("*NEW* Product Line [productLine="
+ loadedProductline.getProductline() + ", textDescription="
+ loadedProductline.getTextdescription() + "]");

注意在这段代码中,没有使用任何事务。原因是这段代码只执行读操作而不执行写操作,即使操作失败,DB中的任何数据都不会受到影响。因此,不需要使用事务来保护操作。

3.3 更新实体

现在下一段代码看起来可能更长,但这是因为它输出了新值,并确认在DB中更新了记录。

java 复制代码
/* 1. Now retrieve the new product line, using the ID we created */
Productline loadedProductline = dao.findById(productlineID);

/*
* 2. Now let's change same value on the product line, and save the
* change
*/
loadedProductline.setTextdescription("Product line for men's shoes.");

TransactionStatus status = txManager
.getTransaction(new DefaultTransactionDefinition());
dao.update(loadedProductline);
txManager.commit(status);

/*
* 3. Now let's load the product line from the DB again, and make sure
* its text description changed
*/
Productline secondLoadedProductline = dao.findById(productlineID);

System.out.println("*REVISED* Product Line [" + "productLine="
+ secondLoadedProductline.getProductline()
+ ", textDescription="
+ secondLoadedProductline.getTextdescription() + "]");

请注意更新调用被封装在事务中,因为它必须向数据库写入一些内容,并且需要防止失败。

在上面的第3节中,产品线在更新后立即从数据库加载,并通过打印从数据库返回的值来确认更新。

3.4 删除实体

删除实体几乎等同于保存和更新实体,工作被封装在另一个事务中,然后DAO被告知去做这项工作。

java 复制代码
/* 1. Now retrieve the new product line,
using the ID we created */
TransactionStatus status = txManager
.getTransaction(new DefaultTransactionDefinition());
Productline loadedProductline = dao.findById(productlineID);

/* 2. Now let's delete the product line from
the DB */
dao.delete(loadedProductline);
txManager.commit(status);

/*
* 3. To confirm the deletion, try and load it again and make sure it
* fails
*/
Productline deletedProductline = dao.findById(productlineID);

/*
* 4. We use a simple inline IF clause to test for null and print
* SUCCESSFUL/FAILED
*/
System.out.println("Productline deletion: "
+ (deletedProductline == null ? "SUCCESSFUL" : "FAILED"));

与上面的"updateProductline"实现类似,您会注意到一个事务用于封装"delete"调用,然后代码尝试从DB加载实体并确认操作应该失败。

注意:事务必须封装'findById '和'delete '方法调用的原因是因为JPA管理的对象必须是同一事务的一部分,要擦除已加载的对象,它必须处于加载它并尝试擦除它的同一个事务中。

3.5 运行程序

运行此命令的输出如下所示:

输出

红色文本是可以忽略的默认日志消息(如果希望控制日志记录,您可以设置自定义log4j.properties文件),在日志警告下面,您可以看到来自TopLink (JPA实现库)的两条消息,以及来自实现的另外三条消息。

第一个消息打印出添加的新产品线信息,第二个消息更新产品线信息并打印新信息,最后一个消息从DB中删除产品线信息并打印确认消息。

4. 启用Spring容器管理的事务

除了用户管理的事务之外,Spring还通过@Transactional属性支持容器管理的事务。对于容器管理的事务支持,您必须在添加facet时启用它,这是您在本教程前面所做的。

启用对@Transactional注释的支持

启用此功能将向bean配置文件添加以下事务元素,您还应该添加一个JPAServiceBean,它用于使用容器管理的事务删除实体。请参阅下面的实现:

注解驱动的配置元素

JPAServiceBean实现如下所示;注意'deleteProductLine '方法上的'@Transactional '注释和没有任何用户管理的事务语句。

java 复制代码
public class JPAServiceBean
{ private IProductlineDAO dao; @Transactional public void deleteProductLine(String productlineID)

{ /* 1. Now retrieve the new product line, using the ID we created */Productline loadedProductline = dao.findById(productlineID);

/* 2. Now let's delete the product line from the DB */
dao.delete(loadedProductline);

/*
* 3. To confirm the deletion, try and load it again and make sure it * fails
*/
Productline deletedProductline = dao.findById(productlineID);

/*
* 4. We use a simple inline IF clause to test for null and print
* SUCCESSFUL/FAILED
*/
System.out.println("Productline deletion: " + (deletedProductline == null ? "SUCCESSFUL" : "FAILED"));}

public void setProductLineDAO(IProductlineDAO dao) { this.dao = dao; }
}

从应用程序上下文中获取JPAServiceBean实例,并按如下方式使用它:

java 复制代码
JPAServiceBean bean = (JPAServiceBean) ctx.getBean("JPAServiceBean");
bean.deleteProductLine(productlineID);
相关推荐
卓怡学长4 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn4 小时前
Spring 注解使用详解
java·spring
一条小小yu5 小时前
Spring IoC的理解
java·后端·spring
落魄实习生5 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈5 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白7 小时前
核心功能(Service接口)
java·mybatis
乌暮7 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习
大猫和小黄8 小时前
深入理解 Java Optional:从设计哲学到工程实战
java
数据库百宝箱8 小时前
rum&gin索引对比
java·数据库·gin