增加CRUD功能
使用CRUD能干嘛?---->
在页面对模型进行增删改查操作,这样有什么实际意义呢?
不使用CRUD模块的功能,只要模型继承了Model类,就有save(),delete()等方法可以调用了
这个CRUD对开发有什么帮助?
用于快速生成一个基本的管理区域,如初始化一个登陆用户,很方便。
到目前为止,我对CRUD功能的理解只能这样:
提供一个可视化的对象管理界面,就好比数据库的客户端,play在后台执行SQL为我们处理数据
而我们可以在页面进行增删改查的操作,不用再写增删改查的代码了!
为了使用CRUD功能,需要导入play的CRUD依赖
修改yabe\conf\dependencies.yml
在require后面添加依赖的模块
# Application dependencies require: - play -> crud
注意:dependencies文件中不能使用TAB键,只能使用空格键!!!!!!
运行dependencies命令,安装模块
为CRUD模块添加路由
这条路由将把所有CRUD内建路由导入到/admin为前缀的URL路径中
#import CRUD module * /admin module:crud
刷新eclipse工程,可看到新增了一个modules文件夹,其下放了一个crud的文件
该文件存放了一个路径,指向了本地play解压目录中的\modules\crud文件夹
E:\technology-hqh\soft\play-1.2.5\modules\crud
要想将模块导入,还需要重新执行eclipsify命令
E:\technology-hqh\proj\play-framework\yabe>play eclipsify
刷新工程,这时模块才真正被导入到IDE中,项目中才能找到CRUD这个类!
声明模型所对应的控制器
按照默认约定,控制器的名称为对应模型的复数形式,如User--->Users
当然,也可以自定义名称,只需要使用注解标明这个控制器对应的模型即可
但是,一般还是用默认的算了!呵呵,没那么多精力去研究,先跟着例子跑一遍再说!
User实体类对应的控制器
package controllers; public class Users extends CRUD { }
Post实体类对应的控制器
package controllers; public class Posts extends CRUD { }
Comment实体类对应的控制器
package controllers; public class Comments extends CRUD { }
打开http://localhost:9000/admin/,即可看到系统中所有声明控制器的实体对象了
点击User实体,可以查看当前的对象
这些User对象看起来有点不友好,只有一个简单的序号(id?)来区分,可以对其进行定制
在User实体中复写toString()
@Override public String toString() { return "User [" + fullname + "]"; }
刷新页面
为模型添加验证
既然可以在页面操作对象了,对应的数据校验功能也不可少
使用play,对字段进行校验,只需要使用注解即可,连javascript都不用写
得益于play.data.validation.*这个包下的东东!
对User类的email字段和password进行验证
package models; import java.util.ArrayList; import java.util.List; import javax.persistence.Entity; import javax.persistence.OneToMany; import play.data.validation.Email; import play.data.validation.Required; import play.db.jpa.Model; @Entity public class User extends Model { @Email @Required public String email; @Required(message="input your pwd now!") public String password; public String fullname; public boolean isAdmin; //@OneToMany 声明User与Post之间是1对多的关系 //mappedBy="author" 表示将通过对方(User)的author字段来进行关联关系的维护 @OneToMany(mappedBy="author") public List<Post> posts; public User(String email,String password, String fullname) { this.email = email; this.password = password; this.fullname = fullname; this.posts = new ArrayList<Post>(0); } /** * 联合email和password两个条件查询User * @param email * @param password * @return */ public static User connect(String email, String password) { return find("byEmailAndPassword", email, password).first(); } /** * 添加Post的动作放到User中,这样可以把Post设置到User的List<Post>集合中 * 这样实现了双方都持有对方的引用了 * @param title * @param content * @return */ public User addPost(String title, String content) { Post post = new Post(title,content,this).save(); this.posts.add(post); this.save(); return this; } @Override public String toString() { return "User [" + fullname + "]"; } }
什么都不输,保存一个User对象
会提示错误信息到页面的,play真实个大好人啊,什么活都给干了!
为Post实体加入验证
package models; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.Lob; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import play.data.validation.MaxSize; import play.data.validation.Required; import play.db.jpa.Model; @Entity public class Post extends Model { @Required public String title; @Required public Date postedAt; //@Lob标注:声明这是一个超大文本数据类型,用于存储发布的博客内容 @Lob @Required @MaxSize(100000000) public String content; //@ManyToOne:声明Post与User之间是多对一的关系 //一个用户可以发布多个博客,一个博客只能被一个用户所发布 @Required @ManyToOne public User author; //1篇博客对应多个评论 //删除某篇博客,则级联删除其评论 @OneToMany(mappedBy="post", cascade=CascadeType.ALL) public List<Comment> comments; public Post() { System.out.println("create Post"); this.postedAt = new Date(); } public Post(String title, String content, User author) { this.comments = new ArrayList<Comment>(0); this.title = title; this.content = content; this.author = author; this.postedAt = new Date(); } /** * 在Post中实现评论的添加保存操作 * 同时更新Post所持有的Comment的集合! */ public Post addComment(String author, String content) { //保存对方 Comment newComment = new Comment(author, content, this).save(); //把对方加入到自己管理的集合中 this.comments.add(newComment); //同步到数据库 this.save(); return this; } /** * 前一篇博文 */ public Post previous() { return Post.find("postedAt < ? order by postedAt desc", postedAt).first(); } /** * 后一篇博文 */ public Post next() { return Post.find("postedAt > ? order by postedAt asc", postedAt).first(); } }
注意:使用CRUD在页面操作,对象的创建过程:
1.调用默认构造函数生成一个对象
2.查询数据库,把数据赋值到这个对象
3.页面呈现此对象的相关属性
如果在页面新创建一个对象,则不会查询数据库
1.调用默认构造函数生成一个对象
2.为对象赋值(如果默认构造函数中有这样做)
3.页面呈现各个字段为空的对象,如果有为字段设置默认值,可在默认构造函数中操作
4.页面输入数据,保存对象
这里想说的是:对于createTime这样的字段值,一般是后台new Date()创建的,在页面使用CRUD貌似还不能对其进行控制,因为页面会呈现这个字段出现让用户输入(是否可以通过js控制其disabled状态呢?)暂时有这样一个疑问!有人知否?或者play提供了禁止编辑的注解,是什么???
通过message转换窗体显示的Label
在yabe\conf\messages中加入需要转换的字符串
play会自动将页面显示的字符进行替换
# You can specialize this file for each language. # For example, for French create a messages.fr file # title=Title content=Content postedAt=Posted at author=Author post=Related post tags=Tags set name=Common name email=Email password=Password fullname=Full name isAdmin=User is admin
原始的页面
转换后的页面