play手把手教你创建一个博客项目06增加特征tagging支持.docx
- 文档编号:2791260
- 上传时间:2022-11-15
- 格式:DOCX
- 页数:10
- 大小:277.52KB
play手把手教你创建一个博客项目06增加特征tagging支持.docx
《play手把手教你创建一个博客项目06增加特征tagging支持.docx》由会员分享,可在线阅读,更多相关《play手把手教你创建一个博客项目06增加特征tagging支持.docx(10页珍藏版)》请在冰豆网上搜索。
play手把手教你创建一个博客项目06增加特征tagging支持
06.增加特征(tagging)支持
我们的博客上线运行后将包含非常多的博文,那么,要想快速找到某篇博文将越来越困难。
为了能按主题进行分类,我们将为博客增加tagging支持。
创建Tag(以下简称特征)模型对象
Tag模型类自身其实非常简单:
packagemodels;
importjava.util.*;
importjavax.persistence.*;
importplay.db.jpa.*;
@Entity
publicclassTagextendsModelimplementsComparable
publicStringname;
privateTag(Stringname){
this.name=name;
}
publicStringtoString(){
returnname;
}
publicintcompareTo(TagotherTag){
returnpareTo(otherTag.name);
}
}
由于我们打算用findOrCreateByName(Stringname)工厂方法来实现懒散式特征创建或得到这些特征。
那么,让我们把它添加到Tag类里:
publicstaticTagfindOrCreateByName(Stringname){
Tagtag=Tag.find("byName",name).first();
if(tag==null){
tag=newTag(name);
}
returntag;
}
Taggingposts
是时候创建Tag模型与Post模型的关系了,让我们在Post类里创建正确的关系:
…
@ManyToMany(cascade=CascadeType.PERSIST)
publicSet
publicPost(Userauthor,Stringtitle,Stringcontent){
ments=newArrayList
this.tags=newTreeSet
this.author=author;
this.title=title;
this.content=content;
this.postedAt=newDate();
}
…
请注意,在这里我们使用了TreeSet以可预知的顺序来保存特征列表(事实上是按字母顺序的,这是基于我们之前compareTo实现)。
在这里,我们仅使用单向关系。
同时,我们将添加很多帮助方法来使特征管理简单化,第一个用于tag一个Post:
…
publicPosttagItWith(Stringname){
tags.add(Tag.findOrCreateByName(name));
returnthis;
}
…
下一个用于通过指定的tag找回所有的博文:
…
publicstaticList
returnPost.find(
"selectdistinctpfromPostpjoinp.tagsastwheret.name=?
",tag
).fetch();
}
…
是时候测试这些新代码了,让我们重新启动服务器到测试模式:
$playtest
在basicTest类里添加@Test:
@Test
publicvoidtestTags(){
//Createanewuserandsaveit
Userbob=newUser("bob@","secret","Bob").save();
//Createanewpost
PostbobPost=newPost(bob,"Myfirstpost","Helloworld").save();
PostanotherBobPost=newPost(bob,"Hop","Helloworld").save();
//Well
assertEquals(0,Post.findTaggedWith("Red").size());
//Tagitnow
bobPost.tagItWith("Red").tagItWith("Blue").save();
anotherBobPost.tagItWith("Red").tagItWith("Green").save();
//Check
assertEquals(2,Post.findTaggedWith("Red").size());
assertEquals(1,Post.findTaggedWith("Blue").size());
assertEquals(1,Post.findTaggedWith("Green").size());
}
检查其是否正常工作。
下面的内容比上面的要难一点
好了,如果打算用多个tag来找回博文又该怎么做?
看起来,这样难一点!
下面我将给你一些非常有用的JPQL查询,这些查询可能对你的web项目有用:
…
publicstaticList
returnPost.find(
"selectdistinctpfromPostpjoinp.tagsastwheret.namein(:
tags)groupbyp.id,p.author,p.title,p.content,p.postedAthavingcount(t.id)=:
size"
).bind("tags",tags).bind("size",tags.length).fetch();
}
…
最棘手的部分就是我们必须使用havingcount语句来对联合查询视图进行过滤,仅让完全拥有全部tag的博文通过。
请注意,在这里我们不能使用Post.find("…",tags,tags.count)签名进行查询。
这是因为tags已经是变量参数(vararg)了。
测试程序如下:
…
assertEquals(1,Post.findTaggedWith("Red","Blue").size());
assertEquals(1,Post.findTaggedWith("Red","Green").size());
assertEquals(0,Post.findTaggedWith("Red","Green","Blue").size());
assertEquals(0,Post.findTaggedWith("Green","Blue").size());
…
特征(tag)云
哪里有tags,哪里就需要一个tag云。
让我们在Tag类里添加一个方法来生成tag云:
publicstaticList
List
"selectnewmap(t.nameastag,count(p.id)aspound)fromPostpjoinp.tagsastgroupbyt.nameorderbyt.name"
).fetch();
returnresult;
}
在这里,我们使用了hibernate的一个现成特性,这个特性允许我们从一个JPA查询里返回一个定制对象。
这个在List里的结果包含了一个Map,Map中的每个tag都带有两个key:
tag用作tag名称,pound用作tag统计结果。
测试代码为:
…
List
assertEquals(
"[{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:
TheMVCapplication
postedAt:
2009-06-06
author:
jeff
tags:
-play
-architecture
-mvc
content:
>
APlay
…
注意:
一定要把这些Tags数据描述添加到YAML文件头部,这是因为这些数据需要在任何Post引用它们时进行创建。
现在重新启动应用程序,强制加载这些新的数据集。
请注意,play甚至会告诉你在YAML文件里存在的问题:
然后修改#{display/}标签来显示这些tag集(在full博文视图下)。
修改/yabe/app/views/tags/display.html文件:
…
#{if_as!
='full'}
| ${_ments.size()?
:
'no'}
comment${_ments.size().pluralize()}
#{if_ments}
latestby${_ments[0].author}
#{/if}
#{/if}
#{elseif_post.tags}
-Tagged
#{listitems:
_post.tags,as:
'tag'}
'':
','}
#{/list}
#{/elseif}
…
创建‘特征相关(taggedwith)’页面
现在,我们就可以通过tags(特征)来列出发表的博文。
在上面的#{display/}标签里,我们把链接暂时留为空链接(用#),下面我们将通过一个链接到新创建的listTaggedaction替换他们:
…
-Tagged
#{listitems:
_post.tags,as:
'tag'}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- play 手把手 创建 一个 博客 项目 06 增加 特征 tagging 支持