CRUD模块

CRUD是指数据处理的通用操作,是增加、查询(重新得到数据)、更新和删除几个单词的首字母简写,主要描述软件系统中数据库或者持久层的基本操作功能。 Play的 CRUD模块集成大量Web接口,用于操作JPA模型对象。本节将简单地介绍如何使用 CRUD模块。


11.2.1 使用CRUD模块#

启用CRUD模块

      CRUD是Play内置的模块,不用进行安装,只需在/conf/application.conf文件中添加如下配置,就可以将其引入:

#The CRUD module
module.crud=${play.path}/modules/crud


引入默认CRUD路由

      配置/conf/routes文件,引入CRUD模块默认路由:

# Import CRUD routes
*     /admin           module:crud


注意:

并不是只能采用默认的路由配置,还可以自定义路由或者两者混用。


创建User类

      CRUD模块为域模型提供方法接口,首先创建User类:

package models;
 
import play.*;
import play.db.jpa.*;
 
import javax.persistence.*;
import java.util.*;
 
@Entity
public class User extends Model {
        
        public String name;
        public String email;
        public String address;
        
}


创建Users控制器

      创建简单的控制器Users,继承CRUD模块提供的父类控制器,CRUD模块将通过Users进行路由调度:

package controllers;
 
public class Users extends CRUD {
   
}


注意:

继承CRUD时,可能会出现无法引入模块的错误。错误的原因是由IDE导致的,并不影响模块的使用。

解决方案(Eclipse中引入CRUD模块为例):手动配置IDE引入模块。右击应用程序 -> New->Folder -> Folder name中输入crud -> 点击Advanced -> 选择Link to folder in the file system -> 路径选择modules\crud\app -> 单击Finish -> 使用play eclipsify命令使项目重新工程化。重启Eclipse后错误消失。


      访问http://localhost:9000/admin就可以看到管理域,如图11.1所示。

图片资源/User控制器.png

(图11.1 管理域)

      控制器(Users)默认采用域模型复数形式命名,即域模型名(User)结尾加上字母“s”。如果想使用其他的名称,需要用到@CRUD注解:

package controllers;
 
import models.User;
 
@CRUD.For(User.class)
public class AdminUsers extends CRUD {
   
}


User表单

      点击管理域中的Add按钮,会呈现添加User的表单,如图11.2所示:

图片资源/User表单.png

(图11.2 User表单)

      目前添加User的功能并不完善,需要为User类增加一些验证规则:

package models;
 
import play.*;
import play.db.jpa.*;
 
import javax.persistence.*;
import java.util.*;
 
import play.data.validation.*;
 
@Entity
public class User extends Model {
        
   @Required
   @MinSize(8)
   public String name;
        
   @Required
   @Email
   public String email;
        
   @Required
   @MaxSize(1000)
   public String address;
 
   public String toString() {
      return email;
   }
        
}

      刷新浏览器,就可以看到验证已经自动生效,如图11.3所示。

图片资源/刷新User表单.png

(图11.3 添加验证的User表单)


改变表单的label

      在应用的conf/messages文件中增加如下配置,定制表单的label:

name=Name
email=Email address
address=Postal address

      刷新浏览器,定制效果如图11.4所示。

图片资源/twice_refresh.png

(图11.4 定制label后的User表单)


自定义列表视图

      使用CRUD管理域创建一个User。User实体的name属性值为:Guillaume,email属性值为:guillaume.bort@gmail.com。默认的列表视图中只有一列,如图11.5所示。这是因为CRUD模块默认调用模型对象的toString()方法显示返回结果。

图片资源/crud5.png

(图11.5 默认视图)

      如要希望增加列表视图中显示的属性列的个数,需要在应用中创建/app/views/Users/list.html模板。Play提供的play crud:ov命令可以完成这个操作,打开控制台,进入应用目录并输入play crud:ov命令(例子中应用名为test,在D:\play\路径下):

D:\play>cd test

D:\play\test>play crud:ov --template Users/list
~        _            _
~  _ __ | | __ _ _  _| |
~ | '_ \| |/ _' | || |_|
~ |  __/|_|\____|\__ (_)
~ |_|            |__/
~
~ play! 1.2, http://www.playframework.org
~
~ Copied D:\play\modules\crud\app/views/CRUD/list.html to D:\play\test\a
pp/views/Users/list.html
~

      play crud:ov命令将CRUD模块中的默认模板list.html复制到应用的app/views/Users/目录下。如果该文件已经存在,会将其覆盖。修改app/views/Users/list.html模板:

#{extends 'CRUD/layout.html' /}
 
<div id="crudList" class="${type.name}">
        
        <h2 id="crudListTitle">&{'crud.list.title', type.name}</h2>
 
        <div id="crudListSearch">
                #{crud.search /}
        </div>
 
        <div id="crudListTable">
                #{crud.table fields:['email', 'name'] /}
        </div>
        
        <div id="crudListPagination">
                #{crud.pagination /}
        </div>
        
        <p id="crudListAdd">
                <a href="@{blank()}">&{'crud.add', type.modelName}</a>
        </p>
</div>

      修改#{crud.table}标签,列表视图将显示email,name两个属性列。刷新浏览器,效果如图11.6所示。

图片资源/refresh_list.png

(图11.6 自定义列表视图)


使用#{crud.custom}标签定义更多功能

      CRUD模块提供的#{crud.custom}标签可以对User实体中的每个字段进行定义,并以此控制列表视图和表单视图的显示方式:

#{crud.table fields:['name', 'company']}
 
   #{crud.custom 'company'}
     <a href="@{Companies.show(object.company.id)}">
         ${object.company.name}
     </a>
   #{/crud.custom}
 
#{/crud.table}

      也可以为列表视图定义额外的显示列,或者为表单视图中定义额外的表单输入:

#{crud.table fields:['name', 'company', 'edit']}
 
   #{crud.custom 'company'}
      <a href="@{Companies.show(object.company.id)}">${object.company.name}</a>
   #{/crud.custom}
 
   #{crud.custom 'edit'}
      <a href="@{Users.edit(object.id)}">Edit</a>
   #{/crud.custom}
 
#{/crud.table}


11.2.2 集合或数组的显示方式#

      CRUD模块在列表视图中以文本字段的形式显示实体属性,如果实体属性是数组或者集合的形式,将以逗号分隔:

@Entity
public class Account extends Model {
 
      @CollectionOfElements
      public Set<ContentType> contentTypes;
 
      @CollectionOfElements
      public Set<String> usernames;
 
      public Account(Set<String> usernames) {
            super();
            this.usernames = usernames;
      }
}

      在视图列表中,contentTypes属性将会显示为:myEnumId1,myEnumId2,usernames属性将会显示为string1,string2。


11.2.3 自定义show视图和blank视图#

      ObjectType类在 CRUD模块中的影响至关重要,它可以控制视图行为。因此如果希望改变 CRUD模块行为,可以创建自己的ObjectType类,并在控制器或者控制器的父类中定义相应的静态方法。
protected static ObjectType createObjectType(Class<? extends Model> type) {
   return new VersionObjectType(type);
}

      下例将创建自己的ObjectType类,使用@Version注解将域隐藏:

public class CustomAdminCompany extends CRUD {
   protected static ObjectType createObjectType(Class<? extends Model> type) {
      return new VersionObjectType(type);
   }
   
   public static class VersionObjectType extends ObjectType {
      
      private final String versionColumn;
      
      public VersionObjectType(Class<? extends Model> modelClass) {
         super(modelClass);
         versionColumn = getVersionColumnName(modelClass);
      }
      private String getVersionColumnName(Class modelClass) {
         Class c = modelClass;
         try {
            while (!c.equals(Object.class)) {
               for (Field field : c.getDeclaredFields()) {
                  if (field.isAnnotationPresent(Version.class)) {
                     return field.getName();
                  }
               }
               c = c.getSuperclass();
            }
         } catch (Exception e) {
            throw new UnexpectedException("Error while determining the "
               + "object @Version for an object of type " + modelClass);
         }
         return null;
      }
 
      @Override
      public List<ObjectField> getFields() {
         List<ObjectField> result = super.getFields();
         for (ObjectField objectField : result) {
            if (objectField.name.equals(versionColumn)) {
               objectField.type = "hidden";
            }
         }
         return result;
      }
   }   
}

      到此并没有结束,还可以自定义findPage()等其他方法。


11.2.4 CRUD模块命令#

      CRUD模块提供了crud:override命令,用于重写默认的模板。执行该命令CRUD会自动加载模块模板,如果应用程序模板已存在,会将其覆盖。crud:ov命令与crud:override命令等价,可以替代使用。

      以下命令会将指定模板(如Users/list.html)拷贝至应用程序的app/views/CRUD/目录。可以使用-t替代--template,简化命令的使用。

play crud:override --template [path]


      以下命令重写主页面中的布局模板layout.html。

play crud:override –-layout


      以下命令重写样式表crud.css,并将其拷贝至public/stylesheets/目录。

play crud:override –-css


11.2.5局限性#

      CRUD模块虽然提供强大的功能,但还是有自身的局限性。如果两个实体之间存在双向关系,CRUD模块只能表现其中的一个(没有标注mappedBy属性)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值