play手把手教你创建一个博客项目06.增加特征(tagging)支持_如何创建一个博客

其他范文 时间:2020-02-29 00:03:42 收藏本文下载本文
【www.daodoc.com - 其他范文】

play手把手教你创建一个博客项目06.增加特征(tagging)支持由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“如何创建一个博客”。

06.增加特征(tagging)支持

我们的博客上线运行后将包含非常多的博文,那么,要想快速找到某篇博文将越来越困难。为了能按主题进行分类,我们将为博客增加tagging支持。

创建Tag(以下简称特征)模型对象

Tag模型类自身其实非常简单:

package models;

import java.util.*;import javax.persistence.*;

import play.db.jpa.*;

@Entity public cla Tag extends Model implements Comparable {

public String name;

private Tag(String name){ this.name = name;}

public String toString(){ return name;}

public int compareTo(Tag otherTag){ return name.compareTo(otherTag.name);} } 由于我们打算用findOrCreateByName(String name)工厂方法来实现懒散式特征创建或得到这些特征。那么,让我们把它添加到Tag类里: public static Tag findOrCreateByName(String name){ Tag tag = Tag.find(“byName”, name).first();if(tag == null){ tag = new Tag(name);} return tag;} Tagging posts 是时候创建Tag模型与Post模型的关系了,让我们在Post类里创建正确的关系: …

@ManyToMany(cascade=CascadeType.PERSIST)public Set tags;

public Post(User author, String title, String content){ this.comments = new ArrayList();this.tags = new TreeSet();this.author = author;this.title = title;this.content = content;this.postedAt = new Date();} …

请注意,在这里我们使用了TreeSet以可预知的顺序来保存特征列表(事实上是按字母顺序的,这是基于我们之前compareTo实现)。在这里,我们仅使用单向关系。

同时,我们将添加很多帮助方法来使特征管理简单化,第一个用于tag一个Post: …

public Post tagItWith(String name){ tags.add(Tag.findOrCreateByName(name));return this;} …

下一个用于通过指定的tag找回所有的博文:

public static List findTaggedWith(String tag){ return Post.find(“select distinct p from Post p join p.tags as t where t.name = ?”, tag).fetch();} … 是时候测试这些新代码了,让我们重新启动服务器到测试模式: $ play test 在basicTest类里添加@Test:

@Test public void testTags(){ // Create a new user and save it User bob = new User(“bob@gmail.com”, “secret”, “Bob”).save();

// Create a new post Post bobPost = new Post(bob, “My first post”, “Hello world”).save();Post anotherBobPost = new Post(bob, “Hop”, “Hello world”).save();

// Well aertEquals(0, Post.findTaggedWith(“Red”).size());

// Tag it now bobPost.tagItWith(“Red”).tagItWith(“Blue”).save();anotherBobPost.tagItWith(“Red”).tagItWith(“Green”).save();

// Check aertEquals(2, Post.findTaggedWith(“Red”).size());aertEquals(1, Post.findTaggedWith(“Blue”).size());aertEquals(1, Post.findTaggedWith(“Green”).size());} 检查其是否正常工作。

下面的内容比上面的要难一点

好了,如果打算用多个tag来找回博文又该怎么做?看起来,这样难一点!下面我将给你一些非常有用的JPQL查询,这些查询可能对你的web项目有用: …

public static List findTaggedWith(String...tags){ return Post.find(“select distinct p from Post p join p.tags as t where t.name in(:tags)group by p.id, p.author, p.title, p.content,p.postedAt having count(t.id)= :size”).bind(“tags”, tags).bind(“size”, tags.length).fetch();} …

最棘手的部分就是我们必须使用having count语句来对联合查询视图进行过滤,仅让完全拥有全部tag的博文通过。

请注意,在这里我们不能使用Post.find(“…”, tags, tags.count)签名进行查询。这是因为tags已经是变量参数(vararg)了。测试程序如下: …

aertEquals(1, Post.findTaggedWith(“Red”, “Blue”).size());aertEquals(1, Post.findTaggedWith(“Red”, “Green”).size());aertEquals(0, Post.findTaggedWith(“Red”, “Green”, “Blue”).size());aertEquals(0, Post.findTaggedWith(“Green”, “Blue”).size());…

特征(tag)云

哪里有tags,哪里就需要一个tag云。让我们在Tag类里添加一个方法来生成tag云:

public static List getCloud(){ List result = Tag.find(“select new map(t.name as tag, count(p.id)as pound)from Post p join p.tags as t group by t.name order by t.name”).fetch();return result;} 在这里,我们使用了hibernate的一个现成特性,这个特性允许我们从一个JPA查询里返回一个定制对象。这个在List里的结果包含了一个Map,Map中的每个tag都带有两个key:tag用作tag名称,pound用作tag统计结果。测试代码为:

List cloud = Tag.getCloud();aertEquals(“[{tag=Blue, pound=1}, {tag=Green, pound=1}, {tag=Red, pound=2}]”, cloud.toString());为博客UI添加tags(特征)现在,我们就可以用新的特征填充物来为浏览博客增加一个新的途径。和以前一样,为了高效工作,我们需要在最初的数据集里添加许多tags。修改/yabe/conf/initial-data.yml文件,添加一些tags用于测试: …

Tag(play): name: Play

Tag(architecture): name: Architecture

Tag(test): name: Test

Tag(mvc): name: MVC …

把这些tag添加到post的数据描述里: …

Post(jeffPost): title: The MVC application postedAt: 2009-06-06 author: jeff tags: architecture Tagged #{list items:_post.tags, as:'tag'} ${tag}${tag_isLast ? '' : ', '} #{/list} #{/elseif} …

创建‘特征相关(tagged with)’页面

现在,我们就可以通过tags(特征)来列出发表的博文。在上面的#{display /} 标签里,我们把链接暂时留为空链接(用#),下面我们将通过一个链接到新创建的listTagged action替换他们: …

-Tagged #{list items:_post.tags, as:'tag'} ${tag}${tag_isLast ? '' : ', '} #{/list} …

在Application控制器里创建listTagged(String tag)action方法: …

public static void listTagged(String tag){ List posts = Post.findTaggedWith(tag);render(tag, posts);} …

和以前一样,让我们创建一条指定路由以保持URI清晰:

GET /posts/{tag} Application.listTagged 在这里存在一个问题,之前我们创建的路由和上面这条路由有冲突,这两条路由都能匹配同一个URI: GET /posts/{id} Application.show GET /posts/{tag} Application.listTagged 然后,由于我们假定id是数字型的,而tag不是,那么我们就可以很容易的使用正则表达式来限制第1条路由,从而解决这个问题:

GET /posts/{id} Application.show GET /posts/{tag} Application.listTagged 最后,我们只需要创建/yabe/app/views/Application/listTagged.html模板,以用于新的listTagged action:

#{extends 'main.html' /} #{set title:'Posts tagged with ' + tag /}

*{********* Title ********* }*

#{if posts.size()> 1} There are ${posts.size()} posts tagged '${tag}' #{/if} #{elseif posts} There is 1 post tagged '${tag}' #{/elseif} #{else} No post tagged '${tag}' #{/else}

*{********* Posts list *********}*

#{list items:posts, as:'post'} #{display post:post, as:'teaser' /} #{/list}

下载play手把手教你创建一个博客项目06.增加特征(tagging)支持word格式文档
下载play手把手教你创建一个博客项目06.增加特征(tagging)支持.doc
将本文档下载到自己电脑,方便修改和收藏。
点此处下载文档

文档为doc格式

    热门文章
      整站推荐
        点击下载本文