如下描述正确与否,哪里有纰漏的,@詹兄请指出。
关于activerecord的model属性的创建:
jfinal activerecord的model使用map存储属性值,这与传统的model(javabean)的设计是不一样的,在ActiveRecordPlugin实例化并.start()后TableInfoBuilder.buildTableInfo(tableMappings)即将数据库中数据表及字段的信息创建好已备使用,此时比如demo的数据表blog,其对应的model为Blog,blog的属性(存储在map中)有id,title,content三个,这三个属性是由TableInfoBuilder.buildTableInfo(tableMappings)完成填入Blog中的。
关于model属性的读取:
Java读取:
List<Blog> blogList = Blog.dao.find("select * from blog order by id asc");
for(Blog blog : blogList){
//Get attribute of mysql type: int, integer, tinyint, smallint, mediumint
blog.getInt("id"); // 取Integer,而非int
// Get attribute of mysql type: varchar, char, enum, set, text, tinytext, mediumtext, longtext
blog.getStr("title");
}
这里提一个建议,@詹兄,考虑将getInt方法改名为getInteger,getStr改名为getString。
FreeMaker读取:
<#list blogList as x>
<tr>
<td style="text-align:left;">${x.id}</td>
<td style="text-align:left;">${(x.addColumn)!}</td>
<td style="text-align:left;">${x.title}</td>
</tr>
</#list>
这里有一个问题FreeMake默认对null值不做处理,如果某个值为null,则会发生异常,处理方法是${value!}即在值后加一个英文感叹号,此时会将null当空字符处理。
如何给model添加额外的属性:
再以blog为例,开发中对model的需求,可能需要增加额外的属性,经詹兄的指导及实践,jfinal有如下两种或四种model添加额外属性的方法。
方法一(此种方法添加的额外属性,是即时的(下一次find的List没有put属性addColumn,Blog即没有属性addColumn)?):
public void list() {
List<Blog> blogList = Blog.dao.find("select * from blog order by id asc");
for(Blog blog : blogList){
// 覆盖属性原来的值,这里注意对于表字段映射的属性,使用put或set的效果是一样的
blog.put("title", "11");
// 而对于非表字段映射的属性,则不可以set,否则会出现异常,找不到属性
blog.put("addColumn", blog.getInt("id")+10);
}
setAttr("blogList", blogList);
render("blog.html");
}
方法二(即传统javabean的做法):
private Integer addColumn;
public Integer getAddColumn() {
return this.addColumn;
}
public void setAddColumn(Integer addColumn) {
this.addColumn = addColumn;
}
这两种添加额外属性方法,对于FreeMaker而言,取数据的方法都是一样的model.property。
顺便提一句,经测试,如果这两种方法一起使用,FreeMaker取数据model.property取的是 getAddColumn() 而非方法一put的值,这里值得注意。
方法三(亦或方法三及四,或者方法一二的混合使用,参看如下代码):
Mode的代码:
private Integer addColumn;
public Integer getAddColumn() {
this.addColumn = get("addColumn"); //注意此行
return this.addColumn;
}
public void setAddColumn(Integer addColumn) {
put("addColumn", addColumn);
}
赋值部分代码:
bog.put("addColumn", blog.getInt("id")+15); //方法三
bog.setAddColumn(blog.getInt("id")+15); //方法四,如果可以这么说
总结:关于model添加额外属性,个人建议使用方法二,因为方法一、三、四,容易与数据表原有属性的操作混淆。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
首先,谢谢你的这些建议,这位同学的确是发现了一些细节,如下我逐一说一下:
1:考虑将方法名 getInt 改为 getInterger,getStr改为getString
当初的确是这么设计的,后来为了省代码,所以没这么干了,因为getInt与getStr是比较长用的方法。JFinal的设计目标是开发效率高,代码量省,所以很多地方都体现这个设计原则。
2:Model 尽量去使用 set 方法
Model的set方法能保证属性确实是存在的,是正确的,以免开发的过程中出现手误,出现手误时能在开发过程中及早发现错误。出现手误可以造成手误过的属性不能入库,而开发者认为应该入库,实质是手误导致问题发生。而有时候需要在model 中存放并不存在的属性值,此时可以使用put方法,很是方便。
3:如何给Model添加额外的属性
为了节省代码,就算要给Model添加额外属性时,也不必定义新的成员变量,只需要创建getter与setter方法即可,在getter与setter方法中去存取父类中的map即可,当然或许要对null值以及默认值时进行一些额外处理。
4:FreeMarker表达式 ${model.property}取值问题
如果model中存在property,并且存在 getProperty()方法时,FreeMarker会以 getProperty()优先,其实这也不能完全确定,例如在FreeMarker中迭代时,如果最开始碰到的是无getXxxx方法的property,那么,以后面的迭代中可能就一直使用map中的property。这个以前测试过,现在有些忘记了。这个问题实质与JFinal无关,完一是FreeMarker的个人行为 :)