关于activerecord的model增加属性的问题

bs2004 发布于 2012/03/25 21:00
阅读 1K+
收藏 2

如下描述正确与否,哪里有纰漏的,@詹兄请指出。

关于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添加额外属性,个人建议使用方法二,因为方法一、三、四,容易与数据表原有属性的操作混淆。

 

这部分描述如上,请詹兄指导。

加载中
0
JFinal
JFinal

首先,谢谢你的这些建议,这位同学的确是发现了一些细节,如下我逐一说一下:

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的个人行为 :)

JFinal
JFinal
@bs2004 ok
bs2004
bs2004
嗯,了解了,我慢慢用着慢慢习惯,呵呵。 明天再探索一下多主键时候的处理,先去忙别的了。
JFinal
JFinal
1:的确是有点歧义,不过该方法的返回值类型是Integer。想必你是一个追求完美的人,其实做框架是一个不断权衡的过程,Model中的最常用的两种数据类型就是Integer与String,所以就是为了省代码,才决定这么做的。2:现在的用法是经过近一年的试用摸索出来,一开始put方法是没有提供的,也是为了更严谨。一开始我用了一个CPI方法来做这个事,但后来发现put方法经常要用,所以还是加上了 :)
bs2004
bs2004
1:getInt因为取出的可能是Integer,极可能是null,int有非null值,个人觉得稍有点歧义,而getStr,我是觉得其他get都全字母了,这个干脆也就getString了,呵呵。 2:Model 使用 set 方法: 个人觉得put方法可以配置用或不用,或者设计一个没有put的model,然后多余的属性用javabean传统get set,个人观点了。
返回顶部
顶部