文档章节

Play框架拾遗之四:域模型与JPA支持

奋斗到天明
 奋斗到天明
发布于 2015/08/27 16:24
字数 1340
阅读 973
收藏 0
JPA

1、属性模拟

对于model,Play中字段都是public修饰符,但框架会自动生成setter与getter如:

@Entity
@Table(name="product ")
public class Product extends BaseModel{
  @Id
  public Long id;
  public String name;
}

运行play 得到class文件,用javap命令可以看到:

E:\>javap PrintTemplateType
Compiled from "Product .java"
public class models.Product extends models.BaseModel{
public java.lang.Long id;
public java.lang.String name;
public models.Product ();
public java.lang.Long getId();
public void setId(java.lang.Long);
public java.lang.String getName();
public void setName(java.lang.String);
... //后面省略一些继承父类的方法
}

另外其他地方有引用这样字段也会替换成setter与getter。 如果有已经有自定义方法,那么会框架会优先选择手动编写的方法。

2、数据持久化

Play 1.x持久层采用的是Hibernate,在使用注解实体时,应该使用JPA包中的@Entity而不是Hibernate中的。 可以直接从play.db.jpa.JPA对象中得到实体管理器,通过实体管理器可以将Model持久化到数据库或者执行HQL语句,例如:

EntityManager em = JPA.em();
em.persist(product);
em.createQuery("from Product where price > 50").getResultList();

Play实体采用ActiveRecord模式,将Struts中的dao与pojo合并,ActiveRecord也属于ORM层,由Rails最早提出,遵循标准的ORM模型:表映射到记录,记录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快速实现模型的操作,而且简洁易懂。Play也提倡使用ActiveRecord模式进行快速开发,其主要思想是:

  • 每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录;通常表的每个字段在类中都有相应的Field;

  • ActiveRecord同时负责把自己持久化,在ActiveRecord中封装了对数据库的访问,即CURD;

  • ActiveRecord是一种领域模型(Domain Model),封装了部分业务逻辑。

3、无状态模型

Play被设计成为“无共享”的架构,目的就是为了保持应用的完全无状态化。这样做的好处在于可以让一个应用同一时刻在多个服务器节点上运行。lay为了保持模型无状态化,需要避免一些常见的陷阱,最重要的就是不要因为多请求而将对象保存到Java堆中。使用缓存可以是一种非常好的选择,也是Java Servlet Session的良好的替代方案。

4、JPA支持

JPA(Java Persistence API)是Java持久化的规范,但JPA本身并不是持久化的具体实现。目前JPA的实现主要有:Hibernate,OpenJPA, Toplink,JDO等。Play默认使用了Hibernate的实现,JPA作为一种规范,因此也可以使用其他任意的JPA实现来替代Hibernate。 JPA实体管理器启动后,程序代码中就可以通过JPA辅助类来取得被管理的实体。例如:

public static void index(){
  Query query = JPA.em().createQuery("from Article");
  List<Article> articles = query.getResultList();
  render(articles);
}

事务(Transaction)是访问并可能更新数据库中各种数据项的程序执行单元。Play会自动进行事务管理,在每次发送HTTP请求时自动开启事务,发送HTTP响应完毕后提交事务。如果程序在request/response过程中抛出了异常,事务会自动回滚。当然也可以显式调用JPA.setRollbackOnly()方法通知JPA不要提交当前事务,而在代码中对事务进行强制回滚。 play.db.jpa.Model 类提供多种方法用于数据查找, 采用以下写法可以对查询结果进行分页:

// 最多匹配100篇 post
List<Post> posts = Post.all().fetch(100);

//从第50篇post开始查找,并且最多匹配到第100篇post
List<Post> posts = Post.all().from(50).fetch(100);

Play提供的count()方法具有统计查询对象结果的功能:
long postCount = Post.count();
long userPostCount = Post.count("author = ?", connectedUser);

在Play中也可以书写完整的JPQL语句进行查询:

Post.find(
"select p from Post p, Comment c " +
"where c.post = p and c.subject like ?", "%hop%"
);

也可以在JPQL语句中只写条件部分的查询:

Post.find("title", "My first post").fetch();
Post.find("title like ?", "%hello%").fetch();
Post.find("author is null").fetch();
Post.find("title like % and author is null", "%hello%").fetch();
Post.find("title like % and author is null order by postDate", "%hello%").fetch();
Post.find("order by postDate desc").fetch();

Hibernate会将数据库中查询到的结果以对象缓存的形式维护起来。当实体管理器在进行查询匹配等操作的过程中,数据一直作为持久对象存在。这意味着如果事务没有提交,对象的任何改变都将自动持久化到数据库中。JPA的规范是这样定义的:对象的修改默认与事务过程一致,所以无需显式地调用任何方法就可以持久化修改后的数据。 这种全自动的持久化管理,也有不足的地方,因为我们并不总是希望对象一旦修改就被持久化。所以与其通知实体管理器更新一个对象,还不如告诉它哪些对象不需要更新。refresh()方法可以回滚单个实体,在事务提交之前调用,对象将不被持久化。如:

public static void save(Long id) {
  User user = User.findById(id);
  user.edit("user", params.all()); //修改持久化的对象
  validation.valid(user);
  if(validation.hasErrors()) {
    // 需要显式抛弃user对象
    user.refresh();
    edit(id);
  }
  show(id);
}

© 著作权归作者所有

共有 人打赏支持
奋斗到天明
粉丝 18
博文 112
码字总数 82707
作品 0
昌平
程序员
私信 提问
J2EE规范系列之 JMS1.1 (一) 基本概念

什么是JMS JMS(Java Message Service) 即Java消息服务。它提供标准的产生、发送、接收消息的接口简化企业应用的开发。它是J2EE规范的一部分,定义的接口标准,针对不同的厂商有不同的实现库。...

Garrry
2015/07/06
0
0
apache和tomcat区别

经常在用apache和tomcat等这些服务器,可是总感觉还是不清楚他们之间有什么关系,在用tomcat的时候总出现apache,总感到迷惑,到底谁是主谁是次,因此特意在网上查询了一些这方面的资料,总结...

Yamazaki
2012/09/26
0
0
【科普】JavaEE的核心技术

java的大方向就是JavaEE,JavaEE不仅仅是socket编程,具体包括13种核心技术。 JAVAEE的核心API与组件 JAVAEE平台由一整套服务(Services)、应用程序接口(APIs)和协议构成,它对开发基于W...

花的鱼
06/26
0
0
开发出一个高质量的J2EE系统解析

首先说下, 这篇文章我觉得很强大,很给力,概念性的东西蛮多的,所以需要慢慢的去读,可以加深你对j2ee的理解和应用。值得大家阅读。 J2EE学习者越来越多,J2EE本身技术不断在发展,涌现出各...

dengzhangtao
2010/12/06
0
0
JavaEE的核心API与组件

JAVAEE平台由一整套服务(Services)、应用程序接口(APIs)和协议构成,它对开发基于Web的多层应用提供了功能支持,下面对JAVAEE中的13种技术规范进行简单的描述(限于篇幅,这里只进行简单的...

明理萝
08/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

小白创建一个spring boot项目

进入 https://start.spring.io/

lilugirl
今天
2
0
Alibaba Java诊断利器Arthas实践--使用redefine排查应用奇怪的日志来源

背景 随着应用越来越复杂,依赖越来越多,日志系统越来越混乱,有时会出现一些奇怪的日志,比如: [] [] [] No credential found 那么怎样排查这些奇怪的日志从哪里打印出来的呢?因为搞不清...

hengyunabc
今天
2
0
home hosts

home hosts lwk@qwfys:~$ cat /etc/hosts127.0.0.1 localhost127.0.1.1 qwfys192.168.56.101vm600.qwfys.com39.108.212.91alpha1.ppy.com39.108.117.122alpha2.p......

qwfys
今天
3
0
大数据教程(6.1)hadoop生态圈介绍及就业前景

1. HADOOP背景介绍 1.1、什么是HADOOP 1.HADOOP是apache旗下的一套开源软件平台 2.HADOOP提供的功能:利用服务器集群,根据用户的自定义业务逻辑,对海量数据进行分布式处理 3.HADOOP的核心组...

em_aaron
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部