play手把手教你创建一个博客项目-06.增加特征(tagging)支持
play手把手教你创建一个博客项目-基于play1.2.4官方文档翻译而来
06.增加特征(tagging)支持
我们的博客上线运行后将包含非常多的博文,那么,要想快速找到某篇博文将越来越困难。为了能按主题进行分类,我们将为博客增加tagging支持。 创建Tag(以下简称特征)模型对象
Tag模型类自身其实非常简单:
package models;
import java.util.*;
import javax.persistence.*;
import play.db.jpa.*;
@Entity
public class Tag extends Model implements Comparable<Tag> {
public String name;
private Tag(String name) {
http://doc.guandang.net = name;
}
public String toString() {
return name;
}
public int compareTo(Tag otherTag) {
return http://doc.guandang.netpareTo(http://doc.guandang.net);
}
}
由于我们打算用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;
play手把手教你创建一个博客项目-基于play1.2.4官方文档翻译而来
}
Tagging posts
是时候创建Tag模型与Post模型的关系了,让我们在Post类里创建正确的关系: …
@ManyToMany(cascade=CascadeType.PERSIST)
public Set<Tag> tags;
public Post(User author, String title, String content) {
http://doc.guandang.netments = new ArrayList<Comment>();
this.tags = new TreeSet<Tag>();
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<Post> findTaggedWith(String tag) {
return Post.find(
"select distinct p from Post p join p.tags as t where http://doc.guandang.net = ?", tag
).fetch();
}
…
play手把手教你创建一个博客项目-基于play1.2.4官方文档翻译而来
是时候测试这些新代码了,让我们重新启动服务器到测试模式:
$ play test
在basicTest类里添加@Test:
@Test
public void testTags() {
// Create a new user and save it
User bob = new User("bob@http://doc.guandang.net", "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
assertEquals(0, Post.findTaggedWith("Red").size());
// Tag it now
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项目有用: …
public static List<Post> findTaggedWith(String... tags) {
return Post.find(
"select distinct p from Post p join p.tags as t where http://doc.guandang.net 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();
}
play手把手教你创建一个博客项目-基于play1.2.4官方文档翻译而来
…
最棘手的部分就是我们必须使用having count语句来对联合查询视图进行过滤,仅让完全拥有全部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云:
public static List<Map> getCloud() {
List<Map> result = Tag.find(
"select new map(http://doc.guandang.net as tag, count(p.id) as pound) from Post p join p.tags as t group by http://doc.guandang.net order by http://doc.guandang.net"
).fetch();
return result;
}
在这里,我们使用了hibernate的一个现成特性,这个特性允许我们从一个JPA查询里返回一个定制对象。这个在List里的结果包含了一个Map,Map中的每个tag都带有两个key:tag用作tag名称,pound用作tag统计结果。 测试代码为:
…
List<Map> cloud = Tag.getCloud();
assertEquals(
"[{tag=Blue, pound=1}, {tag=Green, pound=1}, {tag=Red, pound=2}]", cloud.toString()
);
为博客UI添加tags(特征)
play手把手教你创建一个博客项目-基于play1.2.4官方文档翻译而来
现在,我们就可以用新的特征填充物来为浏览博客增加一个新的途径。和以前一样,为了高效工作,我们需要在最初的数据集里添加许多tags。
修改/yabe/conf/initial-data.yml文件,添加一些tags用于测试: …
Tag(play):
name: Play
Tag(architecture):
相关推荐:
- [实用文档]李践-有效提升销售的12大黄金法则8-大
- [实用文档]党支部换届工作方案
- [实用文档]2013年下期电子商务专业部宣传工作计划
- [实用文档]方庄一矿通风、钻探绩效工资考核管理办
- [实用文档]项目一 认识企业物流认识企业物流
- [实用文档]MBI_Display_产品蓝图规画
- [实用文档]北京市建筑业劳务作业人员普法维权培训
- [实用文档]锅炉燃烧调整与运行优化
- [实用文档]4支付结算业务的核算
- [实用文档]米什金_货币金融学_第9版各章学习指导
- [实用文档]水泥混凝土路面硬化工程施工组织设计
- [实用文档]钢筋工程安全技术交底书
- [实用文档]关于公布华中师范大学本科毕业论文
- [实用文档]太原市园林绿化施工合同范本 2
- [实用文档]周日辅导 初中英语分类复习单项选择题(
- [实用文档]第四章 文化经纪人的管理形式 第二节
- [实用文档]学宪法讲宪法竞赛题库
- [实用文档]《数值计算方法》期末考试模拟试题二
- [实用文档]爱词霸学英语:每日一句( 十月)
- [实用文档]2014年国家公务员面试:无领导小组讨论
- 新课程主要理念和教学案例分析汇编(24
- 英国人的快乐源于幸福的家庭生活
- 七年级上册第一次月考模拟数学试卷
- 真丝及仿真丝的种类有哪些?
- 【最新】华师大版八年级数学下册第十六
- 高中英语3500个必背单词
- 我可以接受失败,但我不能接受放弃!
- 最近更新沪科版八年级物理上册期末试卷
- 绿化工作先进乡镇事迹材料
- 鲁教版九年级上册思想品德教学计划
- 英语音标的分类
- 地下室底板无梁楼盖与普通梁板结构形式
- 美容师黄金销售话术
- 雅思写作满分作文备考方法
- 血清甲状腺激素测定与高频彩色多普勒超
- 1度浅析装修对室内空气品质的影响
- 2017-2022年中国汞矿行业深度分析与投
- 计算机二级VB公共基础知识
- (何勇)秸秆禁烧_重在寻找出路
- 内外墙抹灰工程分包施工合同1




