“善意的谎言、美丽的错误”,这些事情在我们的生活及工作经常都在发生。最近花了三天多的时间学习了EasyJF开源官网的Blog程序源码,振奋人心之处就不说了,看过的都知道。同时也存在很多的错误,这些错误有的是由我不知何时亲自导演,这里就捡一些“美丽”的错误及Bub来说说,为了自己以后不再犯这样错误。
技术构架: EasyJWeb+Spring2+JPA 视图模板使用:Velocity
1、很Cool的循环
来自:Blog的圈子显示 错误等级★★★★★
< tr >
#foreach($!info in $subList)
< td >
$!info.title
</ td >
#end
< tr >
#end
其中$myOnwerCircle是从后台传过来的一个List。这个程序是遍历一个列集合,把集合的元素循环显示到<tr>中,第行最多显示两列<td>。
但无论如何,都无法得到想要的结果,由于准备换成类似$BlogQuery.circleQuery.user($blog.owner).number(-1).list这样的标签来查询数据,所以一直认为是标签设计的问题。经过后来的一阵折腾证明是脚本写法的问题,你知道是哪些地方出的问题了吗?先说明:$!CommUtil.toRowChildList这个标签没任何问题。
2、easy的echo
来自:Blog的圈子显示 错误等级★★★★★☆
页面内容:
这里打算显示圈子的主题以及圈子下面的blog数量。但如果不亲身体会,鬼都不知道他会给你显示什么出来。你知道吗?
3、非菜鸟的equals
来自:文章及照片评论
数据结构永远就比算法重要,这个是不容质疑的,可以搞出很漂亮的算法,但没有一个好的模型,你就瞎忙吧。你觉得上面的代码哪儿错了?
4、一不小心就OO及ORM
来自:评论系统设计 ★★☆
@javax.persistence.Inheritance(strategy = javax.persistence.InheritanceType.JOINED)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@FormPO(inject = " sequence,content,owner " )
public abstract class Review implements java.io.Serializable ... {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id; // 主键
..}
@FormPO(inject = " blogOwner,inputUser " )
@Entity
@javax.persistence.MappedSuperclass
public class BlogReview extends Review implements IBlogComponment ... {
@POLoad(name = " userId " )
@ManyToOne
private User blogOwner;
private String inputUser;
}
@FormPO(inject = " newsDoc " )
@Entity
public class BlogNewsReview extends BlogReview ... {
@POLoad(name = " docId " )
@ManyToOne
@JoinColumn
private BlogNewsDoc newsDoc; // 评论的对象
}
public interface IBlogReviewDAO extends GenericDAO < BlogReview > ... {
}
private IBlogReviewDAO dao;
public BlogReview getBlogReview(Long id) ... {
return this .dao.get(id);
}
评论系统,管理员能管理所有评论,能对Blog文章、像册等进行评论。
这个示例要是搞好了可以当成是一个比较经典的OO及ORM示例,但是现在这样的写法你知道JPA会创建几张表吗,各个表之间关联字段是是什么? Service中的getBlogReview返回什么?答对了有奖。
4、有事无事的事务
来自blog信息发表
< aop:config >
< aop:pointcut id = " saveMethods "
expression = " execution(* com.easyjf.blog.service.BlogNewsDocService.*(..)) " />
< aop:advisor advice - ref = " txBlogServiceAdvice "
pointcut - ref = " saveMethods " />
</ aop:config >
< tx:advice id = " txBlogServiceAdvice "
transaction - manager = " transactionManager " >
< tx:attributes >
< tx:method name = " wirteBlog* " propagation = " REQUIRES_NEW " />
< tx:method name = " update* " propagation = " REQUIRES_NEW " />
< tx:method name = " get* " propagation = " SUPPORTS "
read - only = " true " />
< tx:method name = " query* " propagation = " SUPPORTS "
read - only = " true " />
< tx:method name = " * " propagation = " REQUIRED " />
</ tx:attributes >
</ tx:advice >
代码:
this .service.addBlogReview(review);
if (review instanceof BlogNewsReview) ... {
BlogNewsReview r = (BlogNewsReview) review;
// this.docService.updateBlogNewsDoc(r.getNewsDoc());
this .htmlGenerator.process(r.getNewsDoc());
r.getNewsDoc().getReviews().remove(r); // 很怪也滑稽的设计
return new Page( " html " , r.getNewsDoc().getStaticUrl(), " html " );
}
为什么Blog更新后出来的html页面还是上一次更新的内容?为什么在添加新闻的评论里面要加一句r.getNewsDoc().getReviews().remove(r),是无奈还是真的滑稽。
5、究竟是要IP、IQ还是IC卡
来自:blog首页 ☆
public Page doInit(WebForm form, Module module) ... {
form.addResult( " blogInfoService " , this .blogInfoService);
form.addResult( " bqu " , bqu);
form.addResult( " bdqu " , bdqu);
form.addResult( " bcqu " , bcqu);
form.addResult( " bb” bb);
if (UserContext.getUser() != null ) ... {
form.addResult( " user " , " true " );
}
return new Page( " index " , " /blog/index.html " );
}
前台页面
#foreach($info in $bcu.thisYear.doc.list)
$info.title
#end
这段代码是想把一些实用工具比如bb,bq,bcqu,bdqu等暴露给页面,由页面人员根据自己的喜爱想要展示什么数据就展示什么数据。严格来说,这没什么错,只是害苦了美工MM而已,难怪她们不喜欢呆办公室。
7、真空还是没空(is NULL or EMPTY)
来自Blog发布程序
QueryObject query = new QueryObject();
java.util.Calendar ca = java.util.Calendar.getInstance();
ca.setTimeInMillis(ca.getTimeInMillis() - blogIntervals * 1000 );
query.addQuery( " (obj.updateTime<? or obj.updateTime is EMPTY) " , new Object[] ... {ca.getTime()} );
query.setPageSize( - 1 );
List list = this .blogService.getBlogInfo(query).getResult();
知道执行这段代码生成的SQL吗?一定会让你大吃一惊,把EMPTY改成NULL难道是我们想要的?
8、F想要干什么
来自:blog新闻管理
function init() ... {
F = new FORM( " blogNewsDoc.ejf " , " ListForm " );
windowInit();
}
window.onload = init;
F.doList = F.doOneCommand( " listDoc " );
古老的new FORM曾经让我们非常欣喜,但为什么现在换来的却是大家抱怨呢?代码有时候也是有生命的,你如何都不用心好好对待他,他怎么会一直按部就班的运转呢?
9.想擦掉js给你留下的伤疤吗
来自blog管理后台
< form name = ”ListForm” id = ”ListForm” />
< input type = " button " name = " submit " value = " 彻底删除 " onClick = " F.doRemove(); " class = " pushbutton " style = " cursor:pointer " >
</ form >
F.doRemove()里面会执行类似$(“ListForm”).submit()这样的代码来提交表单。
你觉得这段代码能让你真正的彻底删除掉js曾经留给你的诸多痛苦回忆吗?你继续痛哭吧,呵呵。其实我们只要仔细看一看就知道问题了。w3c可不是war3,不能随便乱来的。
10.你拥有什么?
来自Blog域对象
@MappedSuperclass
public class AbstractBlog implements Serializable ... {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
protected Long id;
@OneToOne
protected User onwer;
@Column(length = 200 )
protected String title; // 标题
@Column(length = 200 )
protected String subtitle; // 副标题
}
页面标签:
#foreach($info $BlogQuery.photoQuery.blogOwner($blog.owner).number( 6 ).orderBy( " inputTime " ).desc().list)
#end
呵呵,今天就这么多了,先听听大家的高见!下次发几个能让人眼前一亮的。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1921072