国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
ibatis支持枚舉類型
很多應(yīng)用中,數(shù)據(jù)庫表結(jié)構(gòu)都會(huì)存在一些狀態(tài)字段。在關(guān)系性數(shù)據(jù)庫中,一般會(huì)用VARCHAR類型。使用ibatis的應(yīng)用,傳統(tǒng)做法,往往會(huì)使用String的屬性,與之對(duì)應(yīng)。
例如一張member表,結(jié)構(gòu)設(shè)計(jì)如下:

其中status為狀態(tài)字段。

ibatis中,使用class MemberPO 與之mapping,設(shè)計(jì)往往如下:
public class MemberPO implements Serializable {
    
private Integer id;
    
private String loginId;
    
private String password;
    
private String name;
    
private String profile;
    
private Date gmtCreated;
    
private Date gmtModified;
    
private String status;

   
//getter/setters


缺點(diǎn):
1)不直觀,沒人會(huì)知道status具體有哪些值。在缺乏文檔,并且歷史悠久的系統(tǒng)中,只能使用“select distinct(status) from member”,才能得到想要的數(shù)據(jù)。如果是在千萬級(jí)數(shù)據(jù)中,代價(jià)太大了;
2)類型不安全,如果有人不小心拼寫錯(cuò)誤,將會(huì)導(dǎo)致錯(cuò)誤狀態(tài)。假設(shè)上面列子中,status只允許ENABLED/DISABLED,如果一不小心,memberPO.setStatus("ENABLEDD"),那么將會(huì)造成臟數(shù)據(jù)。

既然jdk5之后,引入了enum,是否可以讓ibatis支持enum類型呢?事實(shí)上,最新的ibatis版本,已經(jīng)支持enum類型(本文使用的是2.3.4.726版本--mvn repsitory上最新的版本)。
以上代碼可以修改成:
1)Status類:
public enum Status {

    
/** enabled */
    ENABLED,

    
/** disabled */
    DISABLED;

2)MemberPO類:
public class MemberPO implements Serializable {
    
private Integer id;
    
private String loginId;
    
private String password;
    
private String name;
    
private String profile;
    
private Date gmtCreated;
    
private Date gmtModified;
    
private Status status;

    
//getter/setters


除此之外,其他均無需改動(dòng)。
為什么呢?ibatis如何知道VARCHAR/Enum的mapping呢?
看過ibatis源碼的同學(xué),知道,ibatis是通過jdbcType/javaType得到對(duì)應(yīng)的TypeHandler做mapping處理的。ibatis有基本類型的TypeHandler,比如StringTypeHandler,IntegerTypeHandler等等。在最新版本中,為了支持enum,增加了一個(gè)EnumTypeHandler。

并且在TypeHandlerFactory中,加了對(duì)enum類型的判斷,請(qǐng)看:
public TypeHandler getTypeHandler(Class type, String jdbcType) {
    Map jdbcHandlerMap 
= (Map) typeHandlerMap.get(type);
    TypeHandler handler 
= null;
    
if (jdbcHandlerMap != null) {
      handler 
= (TypeHandler) jdbcHandlerMap.get(jdbcType);
      
if (handler == null) {
        handler 
= (TypeHandler) jdbcHandlerMap.get(null);
      }
    }
    
if (handler == null && type != null && Enum.class.isAssignableFrom(type)) {
      handler 
= new EnumTypeHandler(type);
    }
    
return handler;
  }
ibatis使用了取巧的方法,當(dāng)取不到基本類型的handler時(shí)候,判斷javaType是否是Enum類型--Enum.class.isAssignableFrom(type),如果是,則使用 EnumTypeHandler進(jìn)行mapping處理。

為什么說它取巧,原因是早期ibatis設(shè)計(jì)過程中,自定義的接口無法得到具體的java class type。故早期的ibatis中,要實(shí)現(xiàn)對(duì)enmu的支持,非??嚯y。而新版本中,為了達(dá)到這個(gè)功能,作者直接修改了TypeHandlerFactory的實(shí)現(xiàn),打了一個(gè)補(bǔ)丁,如下:
if (handler == null && type != null && Enum.class.isAssignableFrom(type)) {
      handler 
= new EnumTypeHandler(type);
}
這個(gè)設(shè)計(jì)有悖于和早前的設(shè)計(jì)思想。早期,TypeHandler都是通過public void register(Class type, String jdbcType, TypeHandler handler)方式事先注冊(cè)到factory中的,而這次,是在運(yùn)行期,通過new方法動(dòng)態(tài)得到EnumTypeHandler。
當(dāng)然,新版本ibatis能支持enum,已經(jīng)是一件開心的事情了。

Status枚舉類除了描述狀態(tài),就足夠了嗎?回想起很多應(yīng)用,我是做web開發(fā)的,在view層(velocity,jsp,等),見多了類似這樣的代碼:
#if($member.getStatus()==Status.ENABLED)開通#elseif($member.getStatus()==Status.DISABLED)關(guān)閉#end

<select>
  
<option value="ENABLED" #if($member.getStatus()==Status.ENABLED) selected="selected"#end >開通</option>
  
<option value="DISABLED" #if($member.getStatus()==Status.DISABLED) selected="selected"#end >關(guān)閉</option>
</select>

web層需要多少個(gè)頁面,就需要維護(hù)多少份這樣的代碼;以后每添加/刪除一種狀態(tài),多個(gè)地方都需要修改,還要擔(dān)心邏輯不一致。

而事實(shí)上,關(guān)于狀態(tài)的信息描述,按照職責(zé)分,就應(yīng)該由枚舉類來維護(hù):
1)制定一個(gè)接口,EnumDescription.java
public interface EnumDescription {

    
public String getDescription();

}
2)寫一個(gè)ResourceBundleUtil.java,通過Properties文件得到描述信息:
public class ResourceBundleUtil {

    
private ResourceBundle resourceBundle;

    
public ResourceBundleUtil(String resource) {
    
this.resourceBundle = ResourceBundle.getBundle(resource);
    }

    
public ResourceBundleUtil(String resource, Locale locale) {
    
this.resourceBundle = ResourceBundle.getBundle(resource, locale);
    }

    
public String getProperty(String key) {
    
return resourceBundle.getString(key);
    }

}
3)Status等枚舉類實(shí)現(xiàn)EnumDescription:
public enum Status implements EnumDescription {

    
/** enabled */
    ENABLED,

    
/** disabled */
    DISABLED;

    
private static ResourceBundleUtil util = new ResourceBundleUtil(Status.class.getName());

    
public String getDescription() {
       
return util.getProperty(this.toString());
    }

}

這樣,有什么好處:
1)通過Properties文件,支持國際化。
2)描述信息統(tǒng)一由自己來維護(hù),方便維護(hù),并且顯示層邏輯簡(jiǎn)化,如:
$member.getStatus().getDescription()

<select>
  #foreach($status in $Status.values())
    
<option value="$status" #if($member.getStatus()==$status)selected="selected"#end >$status.getDescription()</option>
  #end
</select>

##############################################################################
那么使用老版本ibatis的客戶怎么辦呢?就像我們公司使用ibatis 2.3.0,難道只能眼饞著?解決方案:
1)升級(jí)到最新版本。 :)
2)ibatis提供了TypeHandler/TypeHandlerCallback接口,針對(duì)每種枚舉類型,寫相應(yīng)的TypeHandler/TypeHandlerCallback的接口實(shí)現(xiàn)即可--工作量大,重復(fù)的勞動(dòng)力。
主要是早期ibatis TypeHandler無法得到j(luò)avaType類型,無法從jdbc value轉(zhuǎn)成對(duì)應(yīng)的枚舉。在我看來,TypeHandler是作mapping用的,它至少有權(quán)知道javaType。
3)實(shí)現(xiàn)偽枚舉類型(允許繼承)來實(shí)現(xiàn)狀態(tài)類型安全,而拋棄jdk5的方式--不方便日后升級(jí)。


不知道大家是否還有更好的方案?

本文涉及演示代碼如下:
演示代碼
workspace file encoding:utf-8
build tool: maven
repository:spring/2.5.5;ibatis/2.3.4.726

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
ibatis如何支持clob 和blob
萬惡的Mybatis的EnumTypeHandler
Mybatis中幾個(gè)重要類
Java中不可或缺的50個(gè)小技巧,好用!
設(shè)計(jì)模式-單例模式
Android中定時(shí)器Timer和TimerTask的啟動(dòng),停止,暫停,繼續(xù)等操作實(shí)例
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服