Welcome 微信登录

首页 / 软件开发 / JAVA / ActiveJPA:针对JPA的活动记录模式

ActiveJPA:针对JPA的活动记录模式2015-02-09 infoq 译:张卫滨ActiveRecord是Ruby on Rails的ORM层,大体上类似于Java中的Hibernate。ActiveRecord基于约定优于配置的原则,所以它使用起来比Hibernate更容易。在简化基本的数据操作方面,如创建、读取、更新和删除,它确实是非常棒的。

借助于ActiveRecord,你的模型类也会作为数据访问对象(Data Access Object,DAO)来执行CRUD操作。在初步探究之后,我对ActiveRecord产生了浓厚的兴趣,因此开始寻找一种解决方案来简化基于Java持久化API(Java Persistence API,JPA)的ORM框架的使用。

大多数JPA应用都会有某种类型的数据访问层(Data Access Layer,DAL)来与数据库进行交互。通常DAL会包含数据访问对象或符合Repository设计模式的类。

DAO的实现与实体对象通常是一对一的关系,而Repository则是针对每个聚合根(aggregate root)实现一个。不管是哪种场景,应用最后都会创建多个类与数据库进行交互。尽管适当的抽象能够有效限制所创建类的数量,但是它终究还是会在应用中引入一个额外的层,这都是需要维护和测试的。

ActiveJPA基于JPA,提供了Martin Fowler所提出的活动记录模式(Active Record pattern)的Java实现。借助于ActiveJPA,模型本身会作为DAO并与数据库交互,这样就不需要额外的代码作为数据访问层了。

ActiveJPA使用到了JPA规范,因此所有JPA的ORM实现(Hibernate、EclipseLink、OpenJPA等)都可以与ActiveJPA协同使用。

将已有的JPA模型转换为ActiveJPA

要将已有的模型转换为ActiveJPA,只需让你的模型实现扩展org.activejpa.entity. Model即可:

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

执行CRUD操作

你的模型将会从ActiveJPA的模型类中继承得到很多的CRUD功能。

//根据id获得订单Order order = Order.findById(12345L);// 根据customer获得其已发货的订单 List orders = Order.where("customerEmail", "dummyemail@dummy.com", "status", "shipped");// 得到匹配过滤条件的第一条订单记录 Long count = Order.first("customerEmail", "dummyemail@dummy.com", "status", "shipped");// 得到匹配过滤条件的唯一一条订单记录Long count = Order.one("customerEmail", "dummyemail@dummy.com", "status", "shipped");// 得到所有的记录 List orders = Order.all();// 检查指定标识符的订单是否存在 boolean exists = Order.exists(1234L);// 保存订单 order.persist();// 删除订单 order.delete();// 刷新订单order.refresh();// 与持久化上下文中已有的订单进行合并order.merge();

过滤与分页

对记录进行过滤时,你并不需要创建JPQL或criteria查询。ActiveJPA提供了一个复杂的过滤器,用于在不同的操作间进行连接(conjunction):

// 获取匹配指定Email地址且账单额大于1000的所有订单,并且要进行分页 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);// 对满足过滤条件的订单进行计数 Long count = Order.count(filter);// 删除匹配这个过滤器的订单 Long count = Order.deleteAll(filter);