咨询电话
4007001020

Loding the player....

本视频来由慧都学院提供   查看原视频>>

用JPA和Spring管理数据

MyEclipse 3.15 Style——在线购买低至75折!火爆开抢>>

MyEclipse最新版下载

本教程介绍了MyEclipse中的一些基于JPA / Spring的功能。有关设置JPA项目的基础知识,请先阅读JPA教程。 本教程主要关注MyEclipse中的JPA-Spring集成以及如何利用这些函数。您将学习到:

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

持续时间:30分钟

没有MyEclipse? 现在下载

一、使用JPA和Spring Facets创建一个Java项目

将JPA和Spring功能添加到Java或Web项目中是最常见的。 本教程使用Java项目来演示这些技术是如何工作的。

注意:您可以下载本教程中开发的项目,然后导入到工作区中。

1. 创建一个名为SampleJPASpringProject的示例Java项目,并向其添加JPA facet

2. 右键单击该项目,然后选择MyEclipse>Project Facets>Install Spring Facet。

3. 单击Next接受Spring版本和runtime默认值。

设置Spring版本和目标运行时

4. MyEclipse创建一个新的applicationContext.xml文件夹,然后单击Next。

设置bean配置

5. 注意Add Spring-JPA support复选框,它指示MyEclipse在这个JPA项目中生成源,将Spring和JPA集成在一起。 因为您将Spring添加到JPA项目,所以默认情况下会选择此项。 此外默认情况下,支持使用@Transactional Spring注释。单击Finish。

添加Spring-JPA功能

注意:Spring Container-Managed Transactions部分介绍了基于注释的事务支持。

既然该项目已添加了JPA和Spring facets,则可以打开applicationContext.xml Spring bean配置文件,并查看项目是如何配置的。 通过单击编辑器底部的Beans Graph选项打开图形视图。

Spring配置

你可以从Spring bean配置文件中看到不同的bean是如何配置的。 transactionManager使用entitytManagerFactory,后者依次使用JPA持久性单元(在添加JPA facets时创建的)。

二、逆向工程

现在已经建立了项目,您已经准备好将PRODUCTLINE表逆向工程,并开始使用生成的实体。

1. 右键单击src文件夹,然后选择New>Package创建一个用于生成实体的包。

2. 右键单击该包,然后选择MyEclipse>Generate Entities & DAOs。

3. 选择PRODUCTLINE,单击Add,然后单击Next。

选择 PRODUCTLINE 表

4. 填写如下所述的字段。

Java source folder:生成文件的项目文件夹

Java package:您在上面创建的包中放置生成的类的包

Entity Bean Generation:告诉MyEclipse生成的正确标注为用作JPA实体的普通Java类

Create abstract class:如果您想自定义生成的类,而不是每次都覆盖修改,MyEclipse可以生成基本的抽象类以及您可以自定义和使用具体的子类。每次逆向工程时,MyEclipse只覆盖抽象基类,在具体子类中维护您的修改。

Update persistence.xml:与Hibernate类似,您可以列出您在JPA配置文件中使用的所有JPA实体。

Java Data Access Generation:告诉MyEclipse生成DAO实用程序类,使您可以立即保存/查找/更新/删除数据库中的实体。 这段代码包装了JPA实体管理器,使得使用实体和数据库非常容易。

Generate Precise findBy Methods:告诉MyEclipse生成findByXXX方法,其中XXX属于相反实体上的每个属性。 这使得可以使用任何属性轻松访问数据库中的实体,以此作为找到它们的手段。

Generate Java interfaces:告诉MyEclipse生成顶层的DAO接口以及具体的实现(例如IProductlineDAO和ProductlineDAO)

DAO Type:根据生成的DAO的类型,MyEclipse(除了为您生成DAO实现)还可以使用挂接到现有entityManagerFactory的新DAO更新您的Spring bean配置文件。

生成实体

5. 单击Finish完成reverse-engineer表。当逆向工程完成后,您可以再次查看项目的Spring配置并查看更新。

新的Spring DAO

使用更新的Spring视图,您可以看到包含的ProductlineDAO。

三、写一个应用程序

现在MyEclipse已经生成了所有这些代码,您可以快速地编写您的业务逻辑。

JPA教程涵盖了实体和DAO类所做的每个操作以及运行简单场景的主要方法基本概述,其中包括:

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

同样,在本教程中,您将看到如何使用Spring获取和使用DAO以及管理事务。这个演示的起点是RunJPA.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简单地调用每个 “do something”的方法。

3.1 保存一个实体

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

/* 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中检索实体,并显示其值; 这证实了保存操作的工作。

/* 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() + "]");

注意在这个代码中,没有使用事务。 原因是这个代码只执行一个读操作而不是一个写操作。 即使操作失败,也不会影响数据库中的数据。 所以,没有必要保护使用交易的操作。

3.3 更新实体

现在代码的下一部分可能看起来更长,但这是因为会打印出新的值,并确认记录已在数据库中更新。

/* 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() + "]");

注意update调用是用一个事务封装的,因为它必须向数据库写入一些东西,并且需要防止失败。

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

3.4 删除一个实体

删除实体与保存和更新实体几乎相同。 工作被封装在一个交易中,然后DAO被告知要做这项工作。

/* 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实现类似,您会注意到事务用于包装删除调用,然后代码尝试从DB加载实体并确认操作失败。

注意:事务必须封装findById和delete方法调用的原因是因为由JPA管理的对象必须是同一个事务的一部分。 要删除加载的对象,它必须在它被加载的同一个事务中,试图将其删除。

3.5 运行程序

运行它的输出如下所示:

输出

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

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

四、启用Spring容器管理事务

除了用户管理事务外,Spring还通过@Transactional属性支持容器管理事务。 对于容器管理的事务支持,当您添加facets时,必须启用它,在前面的部分已经介绍过。

启用对@Transactional注释的支持

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

注释驱动的配置元素

JPAServiceBean实现如下所示;请注意deleteProductLine方法上的@Transactional注释以及缺少任何用户管理的事务语句。

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的一个实例并按如下所示使用它:

JPAServiceBean bean = (JPAServiceBean) ctx.getBean("JPAServiceBean");
 bean.deleteProductLine(productlineID);

更多资讯敬请访问MyEclipse中文网>>