2022年play框架手册-.JPA持久化 .pdf

上传人:Che****ry 文档编号:27255273 上传时间:2022-07-23 格式:PDF 页数:8 大小:73.94KB
返回 下载 相关 举报
2022年play框架手册-.JPA持久化 .pdf_第1页
第1页 / 共8页
2022年play框架手册-.JPA持久化 .pdf_第2页
第2页 / 共8页
点击查看更多>>
资源描述

《2022年play框架手册-.JPA持久化 .pdf》由会员分享,可在线阅读,更多相关《2022年play框架手册-.JPA持久化 .pdf(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、1 07.JPA 持久化play 提供了一些非常有用的帮助类来简单管理jpa 实体。注意: 如果需要,你仍旧可以继续使用原始的JPA API。启动 JPA实体管理器当 play 找到至少一个注释了 javax.persistence.Entity标识的类时, play 将自动启动 hibernate实体管理器。前提是已经有一个正确的JDBC数据源配置,否则会导致失败。获取 JPA实体管理器当 JPA实体管理器启动后,就可以在应用程序代码中得到管理器,并使用JPA帮助类了,比如:public static index() Query query = JPA.em().createQuery(se

2、lect * from Article); List articles = query.getResultList(); render(articles); 事务管理play 会自动管理事务。当http 请求到达, play 就会为每个 http 请求启动一个事务。当 http response 发送的时候,就会把事务提交。如果代码抛出异常,事务将会自动回滚。如果需要在代码中强制回滚事务,可以使用JPA.setRollbackOnly()方法,以告诉 JPA不要提交当前事务。也可使用注释明确哪些事务要进行处理。如果在控制器里用 play.db.jpa.Transactional(readOnl

3、y=true)注释了控制器的某个方法,那么这个事务是只读的。如果不想让 play 启动事务,可以使用以下注释play.db.jpa.NoTransaction。如果不想让类的所有方法执行事务,可以对控制器类进行注释:play.db.jpa.NoTransaction. 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 8 页 - - - - - - - - - 2 当使用 play.db.jpa.NoTransaction注释时, Play 不会从连接池中获取连接,以提高运

4、行速度。play.db.jpa.Model支持类在 play 中, 这是最主要的帮助类, 如果你的 jpa 实体继承了 play.db.jpa.Model类,那么这个实体类将得到许多非常有用的方法来管理jpa 访问。比如下面的 Post 模型对象:Entity public class Post extends Model public String title; public String content; public Date postDate; ManyToOne public Author author; OneToMany public List comments; play.db

5、.jpa.Model类自动提供了一个自增长的Long id 域。采用自增长的 Long id 主键对 jpa 模型来说是个好主意。注意,我们事实上已经使用了play 中的一特性,也就是说play 会自动把 Post类中的 public成员认作属性。因此, 我们不需要为这些成员书写setter/getter。为 GenreicModel 定制 id 映射play 并不强制使用 play.db.jpa.Model。你的 JPA实体也可以继承play.db.jpa.GenericModel,如果不打算使用Long类型的 id 作为主键,就必须这样做。比如,下面是一个非常简单的User 实体类。它的

6、id 是 UUID , name 和 mail 属性都是非空值,我们使用Play 验证进行强制检测:Entity public class User extends GenericModel Id GeneratedValue(generator = system-uuid) GenericGenerator(name = system-uuid, strategy = uuid) public String id; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 8 页

7、 - - - - - - - - - 3 Required public String name; Required MaxSize(value=255, message = “email.maxsize ”) play.data.validation.Email public String mail; Finding 对象play.db.jpa.Model提供了几种方式来查找数据,比如:Find by ID 这是查找对象最简单的方式:Post aPost = Post.findById(5L); Find all List posts = Post.findAll(); 这是获取所有 pos

8、ts 对象最简单的方式,类似的应用还有:List posts = Post.all().fetch(); 下面对结果进行分页:/ 最多 100 条List posts = Post.all().fetch(100); 或/ 50至 100条List posts = Post.all().from(50).fetch(100); 使用简单查询进行查找以下方式允许你创建一些非常有用的查询,但仅限于简单查询:Post.find(byTitle, My first post).fetch(); Post.find(byTitleLike, %hello%).fetch(); Post.find(byA

9、uthorIsNull).fetch(); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 8 页 - - - - - - - - - 4 Post.find(byTitleLikeAndAuthor, %hello%, connectedUser).fetch(); 简单查询遵循以下语法 属性 比较And?,比较可取以下值:LessThan 小于给定值LessThanEquals小于等于给定值GreaterThan大于给定值GreaterThanEquals大于等于给定

10、值Like 等价于 SQL的 like 表达式,但属性要为小写。Ilike和 Like相似,大写不敏感,也就是说参数要转换成小写。Elike -等价于 SQL的 like 表达式,不进行转换。NotEqual不等于Between两个值之间(必须带2 个参数)IsNotNull 非空值(不需要任何参数)IsNull 空值(不需要任何参数)使用 JPQL 查询进行查找如:Post.find( select p from Post p, Comment c + where c.post = p and c.subject like ?, %hop% ); 或仅查询某部分 : Post.find(ti

11、tle, 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(); 也可仅有 order by语句:Post.find(order by postDate desc).fetc

12、h(); Counting 统计对象统计对象非常容易:long postCount = Post.count(); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 8 页 - - - - - - - - - 5 或使用查询进行统计:long userPostCount = Post.count(author = ?, connectedUser); 用 play.db.jpa.Blob存储上传文件使用 play.db.jpa.Blob类型可以存储上传的文件到文件系统里(不

13、是数据库) 。在服务器端,Play 以文件方式存储上传的图片到应用程序目录下的attachments文件夹下。文件名 (一个 UUID是指在一台机器上生成的数字,通用唯一识别码,用来唯一标识不同的文件)和 MIME类型将存储到数据库的属性中 (SQL数据类型为 VARCHAR)。在 play 里上传、存储、下载文件非常容易。这是因为框架自动对html 窗体到jpa 模型进行了文件上传绑定 , 而且 play 还提供了便利的方法来操作二进制数据,就像操作普通文本一样简单。为了在模型里存储上传文件,需要增加一个play.db.jpa.Blob类型的属性import play.db.jpa.Blob

14、; Entity public class User extends Model public String name; public Blob photo; 为了上传文件,需要在视图模板里添加一个窗体,在窗体里使用文件上传组件,组件名称应为模型的Blob 属性,如 user.photo :#form addUser(), enctype:multipart/form-data #/form 之后,在控制器里增加一个方法用于存储上传的文件:public static void addUser(User user) user.save(); index(); 这些代码除了 jpa 实体的存储操作

15、外,好像什么都没做,这是因为play 自动对上传文件进行了处理。首先,在启动action方法之前,上传的文件已经存储到应用程序的 tmp/uploads/ 文件夹下,接着,当实体存储完成后,上传的文件会名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 8 页 - - - - - - - - - 6 被复制到应用程序的attachments/ 目录,文件的名称为UUID 。最后,当 action完成后,临时文件将被删除。如果同一用户上传另外一个文件,服务器将把上传的文件当作新

16、文件进行存储,并为新文件生成一个新的UUID文件名,也就是说之前上传的文件无效。要实现多文件上传,就必须自行去实现,比如采用异步job 方式。如果 http 请求没有指定文件的MIME类型,你可以使用文件名称扩展。要想把文件存储到不同的目录,需要配置attachments.path。要想下载存储的文件,需要给控制器的renderBinary()方法传递 Blob.get()参数。强制保存Hibernate 负责维护从数据库查询出来的对象缓存,这些对象将被当作持久化对象进行对待, 其时限和 EntityManager生命周期一样长。 也就是说所有绑定了事务的对象的任何改变都会在事务提交时自动进行

17、持久化。在标准的 JPA里,更新操作属于事务范围,也就不需要强制调用任何方法来持久化值。负面影响就是你必须手工管理所有的对象,而不是告诉 EntityManager 去更新对象(哪种更直观)。我们必须告诉EntityManager 哪个对象不需要更新,这个操作是通过调用 refresh()来实现的,本质上是回滚一个单实体。我们在提交事务之前调用 refresh()方法的目的就是为了让某些对象不被更新。下面是一个通用情况,在窗体已经提交后,对一个持久化对象进行编辑:public static void save(Long id) User user = User.findById(id); us

18、er.edit(user, params.all(); validation.valid(user); if(validation.hasErrors() /这里我们必须丢弃用户的编辑 user.refresh(); edit(id); show(id); 这里我们看到, 许多开发者并未意识到这个问题,总是忘记在错误的情况下丢弃对象现有状态。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 8 页 - - - - - - - - - 7 因此,应该知道我们在play 里修改

19、了什么?所有继承自JPASupport/JPAModel的持久化对象在没有明白调用save() 方法时都不会进行存储。因此,你可以重新书写上面的代码:public static void save(Long id) User user = User.findById(id); user.edit(user, params.all(); validation.valid(user); if(validation.hasErrors() edit(id); else user.save(); / 强制保存 show(id); 这样就更加直观。 但是,如果在一个比较大的对象视图里每次都明确调用sav

20、e()方法将变得乏味,这时可使用关系注释的cascade=CascadeType.ALL属性来自动调用 save() 方法。更多公共类型 generic typing问题play.db.jpa.Model定义了许多公共方法。 这些方法使用一种类型参数来指定方法的返回值类型。 在使用这些方法的时候, 返回值的具体类型由调用的上下文类型接口确定。比如, findAll定义如下: List findAll(); 使用情况为:List posts = Post.findAll(); 在这里, java 编译器使用你分配给结果方法List 的类型作为 T 的实际类型。因此, T的结果类型为 Post。遗

21、憾的是,如果通用方法的返回值直接作为另外一个方法调用的参数时,或用作循环时,这些方法将不能正常工作。因此,下面的代码将抛出编译错误“Type mismatch: cannot convert from element type Object to Post”: for(Post p : Post.findAll() p.delete(); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 8 页 - - - - - - - - - 8 当然可以使用临时局部变量来解决这个问题

22、:List posts = Post.findAll(); /类型引用在这里实现!for(Post p : posts) p.delete(); 请等一等,还有更好的方式,你可以使用已经实现的但不太广泛使用的java 语言特性来解决该问题,这样可以使代码更短小易读:for(Post p : Post.findAll() p.delete(); 很重要的一点就是play 不支持 XA(两阶段提交 )。如果你在同一请求里使用多个不同的 jpa 配置,play 将试着提交更多的事务 。如果在第一个数据库成功提交,而在第二个数据库提交失败, 那么第一个数据库提交的数据将不会回滚。当在同一个请求里使用多个jpa 配置时一定要牢记这一点。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 8 页 - - - - - - - - -

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 高考资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁