jpa 删除记录_ActiveJPA – JPA的活动记录模式

jpa 删除记录

ActiveRecord是Ruby on Rails的ORM层,与Java中的Hibernate大致相当。 ActiveRecord基于约定而不是配置,因此与Hibernate一起使用更容易。 在简化用于创建,读取,更新和删除数据的基本操作时,它确实令人眼前一亮。

使用ActiveRecord,您的模型类可以兼作数据访问对象(DAO)来执行CRUD操作。 经过早期调查,ActiveRecord给我留下了深刻的印象,以至于我开始寻找简化基于Java Persistence API(JPA)的ORM使用的解决方案。

大多数JPA应用程序都具有某种与数据库交互的数据访问层(DAL)。 通常,DAL由数据访问对象(DAO)或存储库设计模式的类组成。

虽然DAO通常是与实体对象一对一地实现的,但是存储库是针对每个聚合根实现的。 无论哪种情况,这些应用程序最终都会创建多个类来与数据库进行交互。 正确的抽象方法可能会限制创建的类的数量,但仍然引入了必须在应用程序中维护和测试的附加层。

ActiveJPAMartin Fowler在JPA上的Active Record模式的Java实现。 它包装了JPA,并提供了有用的抽象来简化数据访问。 使用ActiveJPA,模型本身就可以充当DAO并与数据库进行交互,而无需为DAL编写任何其他代码。

由于ActiveJPA使用JPA规范,因此实现JPA的所有ORM实现(Hibernate,EclipseLink,OpenJPA等)都可以与ActiveJPA一起使用。

将现有的JPA模型转换为ActiveJPA

要将模型转换为ActiveJPA,只需从org.activejpa.entity扩展模型实现即可。 模型:

@java.persistence.Entity
public class YourModel extends org.activejpa.entity.Model {
}

执行CRUD操作

您的模型将从ActiveJPA模型类继承一堆CRUD函数。

// Get order by id
Order order = Order.findById(12345L);

// Get all orders for a customer that are shipped
List orders = Order.where("customerEmail", "dummyemail@dummy.com", "status", "shipped");

// Get the first order matching the filter
Long count = Order.first("customerEmail", "dummyemail@dummy.com", "status", "shipped");

// Get the unique order matching the conditions
Long count = Order.one("customerEmail", "dummyemail@dummy.com", "status", "shipped");

// Dump everything
List orders = Order.all();

// Check if order exists with the given identifier
boolean exists = Order.exists(1234L);

// Save order
order.persist();

// Delete order
order.delete();

// Refresh the order

order.refresh();

// Merge order with the one in persistence context

order.merge();

过滤器和分页

您不需要创建JPQL或条件查询来过滤记录。 ActiveJPA公开了一个复杂的过滤器,可以跨不同的操作执行合并:

// Get all orders matching the given email and billing amount greater than 1000 & paginate it
Filter filter = new Filter();
filter.setPageNo(1);
filter.setPerPage(25);
filter.addCondition(new Condition("customerEmail", Operator.eq, "dummyemail@dummy.com");

filter.addCondition(new Condition("billingAmount", Operator.gt, 1000.00);
List orders = Order.where(filter);

// Count of orders matching the filter
Long count = Order.count(filter);

// Delete all orders matching the filter
Long count = Order.deleteAll(filter);

嵌套查询

ActiveJPA允许嵌套过滤器参数。 这使动态创建动态查询变得更加容易。 例如,您可以从“书”类别的产品中获得至少创建了一个订单商品的所有订单。

// Get all orders containing at the least one book item
Filter filter = new Filter();
filter.setPageNo(1);
filter.setPerPage(25);
filter.addCondition(new Condition("orderItems.product.category", Operator.eq, "books");
List orders = Order.where(filter);

使用集合

上面讨论的所有CRUD操作也可以在收集级别执行。 在以下情况下,查询范围设置为集合类:

// Find order item by id within an order
order.collections("orderItems").findById(123L);

// Get the first order item that is shipped:
order.collections(“orderItems”).first(“status”, “shipped”);

// Get all order items that are cancelled
order.collections(“orderItems”).where(“status”, “cancelled”);

// Get all the items in the collection
order.collections(“orderItems”).all();

// Add an item to the collection
order.collections(“orderItems”).add(orderItem);

// Add an item to the collection
order.collections(“orderItems”).remove(orderItem);

过滤器和分页也可以应用于集合。

// Search order items by filter within an order and paginate it

Filter filter = new Filter();
filter.setPageNo(1);
filter.setPerPage(25);

filter.addCondition(new Condition(“status”, “shipped”);
order.collections("orderItems").where(filter);

// Get count of order items matching the filter in the order

order.collections(“orderItems”).count(filter);

动态更新

ActiveJPA支持动态更新模型。 这在例如用户从浏览器更新表单的情况下非常有用。 您可以传递属性映射进行更新,而不必为每个单独的属性调用setter方法:

// Update attributes
Map attributes = new HashMap();
attributes.put("billingAmount", 1000.0);
order.updateAttributes(attributes);

您还可以通过将映射传递给非原始/非包装器字段来更新这些对象。 以下示例显示了更新订单的送货地址和账单金额。

// Update billing amount and shipping address of an order
Map attributes = new HashMap();
Map address = new HashMap();
address.put(“city”, “Bangalore”);
address.put(“state”, “Karnataka”);
attributes.put(“shippingAddress”, address);
attributes.put("billingAmount", 1000.0);
order.updateAttributes(attributes);

注意 :尚不支持更新列表/集合/数组字段。 将来的版本将支持

交易处理

默认情况下,如果尚不存在ActiveJPA的所有更新操作,它将启动一个事务,但是您也可以按如下所示将一个工作单元包装在一个事务下:

JPAContext context = JPA.instance.getDefaultConfig().getContext();
context.beginTxn();
boolean failed = true;
try {
// Your unit of work here
failed = false;
} finally {
// Commit or rollback the transaction
context.closeTxn(failed);
}

如果外部事务已经存在,ActiveJPA将使用该外部事务,但不会提交或回滚该事务。 关闭交易将由应用程序负责。

测试模型

ActiveJPA为TestNG提供了基础测试类,该类将ActiveJPA挂接到测试运行时。 只要确保您的测试类扩展了org.activejpa.entity.testng.BaseModelTest类即可。 以下是示例代码,

public class OrderTest extends BaseModelTest {
@Test
public void testCreateOrder() {
Order order = new Order();
order.setCustomerEmail("dummyemail@dummy.com");
...
...
order.persist();
Assert.assertEquals(Order.where("customerEmail", "dummyemail@dummy.com").get(0), order);
}
}
}

入门

设置Maven

ActiveJPA可以作为Maven工件使用,并且应该很容易与您的应用程序集成。 只需将以下maven依赖项添加到pom.xml文件中

<dependencies>
<dependency>
<groupId>org.activejpa</groupId>
<artifactId>activejpa-core</artifactId>
<version>0.1.5</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>activejpa-repo</id>
<url>https://raw.github.com/ActiveJpa/activejpa/mvn-repo/releases</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>

与您的应用程序挂钩

在加载实体类之前,需要将ActiveJPA挂接到您的应用程序中。 如果您正在运行Tomcat服务器,则理想的位置是ServletContextListener。 下面是您可以在上下文侦听器contextInitialized()方法中编写的代码。

// Loads the Java agent dynamically
ActiveJpaAgentLoader.instance().loadAgent();

// Add the persistence unit defined by persistence.xml identified by the name 'order'. The persistence.xml should be available in the classpath
JPA.addPersistenceUnit("order");

// If you have entity manager factory already created, you can attach the same to ActiveJpa
// JPA.addPersistenceUnit("order", entityManagerFactory);

与Spring框架集成

将ActiveJPA与Spring之类的框架集成起来非常简单。 大多数应用程序使用Spring来配置JPA并使用批注管理事务。 ActiveJPA可以通过两种方式进行配置-您可以让它创建实体管理器工厂,也可以传递已经存在的工厂。 对于Spring配置的JPA,我们可以使用Spring创建的实体管理器工厂。 这可以确保ActiveJPA使用与Spring创建的相同的连接和事务,并提供无缝集成。

下面的代码演示了如何将ActiveJPA与部署在servlet容器上的Spring应用程序集成。 它使用自定义上下文加载器侦听器将ActiveJPA挂接到应用程序中。 请注意,它与上面的servlet示例相似,不同之处在于它使用Spring Framework ContextLoaderListener:

public class CustomContextListener extends ContextLoaderListener {
@Override
public void contextInitialized(ServletContextEvent event) {
try {
// This loads the javaagent dynamically
ActiveJpaAgentLoader.instance().loadAgent();
} catch (Exception e) {
throw new RuntimeException(e);
}
super.contextInitialized(event);
JPA.instance.addPersistenceUnit("default", getCurrentWebApplicationContext().getBean(EntityManagerFactory.class), true);
}
}

样品申请

GitHub上的ActiveJPA Project Page的示例应用程序中有很多更具体的示例,展示了Spring-ActiveJPA集成。

翻译自: https://www.infoq.com/articles/ActiveJPA/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

jpa 删除记录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值