2014-12-13 61 views
0

如何使用從數據庫中讀取的類型以及如何在代碼中提供類型安全性?Java數據庫字符串類型和類型安全性

前提

考慮與各種類型列的數據庫表。列 「A」 中包含的字符串值 「A」,「B 「C」。 「B」 列包含字符串值 「X」, 「Y」, 「Z」。

示例用法

在爲了保證類型安全,我寧願環繞枚舉這些值,並使用類型,而不是直接使用值作爲字符串

事情是這樣的:

public class TypeSafetyExample { 

    /** 
    * TypeA: map string type to enum type. 
    */ 
    public enum TypeA { 
     A("A"), 
     B("B"), 
     C("C"); 

     String id; 

     TypeA(String id) { 
      this.id = id; 
     } 

     public static TypeA get(String id) { 

      for(TypeA item: EnumSet.allOf(TypeA.class)) { 
       if(item.id.equals(id)) { 
        return item; 
       } 

      } 

      throw new IllegalArgumentException("Unsupported enum id: " + id); 
     } 
    } 

    /** 
    * TypeB: map string type to enum type and give it some other attribute. 
    */ 
    public enum TypeB { 
     X("X", true), 
     Y("Y", true), 
     Z("Z", false); 

     String id; 
     boolean someAttribute; 

     TypeB(String id, boolean someAttribute) { 
      this.id = id; 
      this.someAttribute = someAttribute; 
     } 

     public boolean isSomeAttribute() { 
      return this.someAttribute; 
     } 

     public static TypeB get(String id) { 

      for(TypeB item: EnumSet.allOf(TypeB.class)) { 
       if(item.id.equals(id)) { 
        return item; 
       } 

      } 

      throw new IllegalArgumentException("Unsupported enum id: " + id); 
     } 
    } 

    /** 
    * Object using enums as types. 
    */ 
    public static class MyObjectTyped { 
     TypeA typeA; 
     TypeB typeB; 

     public String toString() { 
      return "Type A: " + typeA + ", Type B: " + typeB; 
     } 
    } 

    /** 
    * Object using strings as types. 
    */ 
    public static class MyObjectUntyped { 
     String typeA; 
     String typeB; 

     public String toString() { 
      return "Type A: " + typeA + ", Type B: " + typeB; 
     } 
    } 

    /** 
    * Example usage. 
    * @param args 
    */ 
    public static void main(String[] args) { 

     MyObjectTyped objTyped; 
     MyObjectUntyped objUntyped; 

     // ... here we would read data from the database and create our typed objects ... 

     objTyped = new MyObjectTyped(); 
     objTyped.typeA = TypeA.get("A"); 
     objTyped.typeB = TypeB.get("X"); 

     System.out.println(objTyped); // Type A: A, Type B: X 

     objTyped = new MyObjectTyped(); 
     objTyped.typeA = TypeA.get("A"); 
     objTyped.typeB = TypeB.get("?"); // Runtime Error during database read: java.lang.IllegalArgumentException: Unsupported enum id: ? 

     objUntyped = new MyObjectUntyped(); 
     objUntyped.typeA = "???"; // no error at all, probably we'll get a runtime error or some inconsistency later, but never during database loading 
     objUntyped.typeB = "???"; // no error at all, probably we'll get a runtime error or some inconsistency later, but never during database loading 

     System.exit(0); 
    } 
} 

基本上是創建一個枚舉所有類型並且數據庫字符串類型被映射到那個枚舉。在java代碼中,只使用枚舉,而不使用字符串。枚舉

優勢:從數據庫加載枚舉

缺點期間

  • 一致性檢查:每當添加新類型

    • 代碼改變必要

    s的優勢trings:當一個新的類型被添加字符串

缺點

  • 無需更改代碼需要:

    • 沒有類型安全。數據庫可以包含任何內容。運行期間可能出現錯誤。

    您對這些概念有什麼看法?你更傾向哪個?或者有更好的方法嗎?我寧願堅持類型安全,因爲代碼的穩定性是值得的。另一方面,每當添加新類型時,代碼更改也不是好習慣。

    謝謝您的意見!

回答

1

這一切都取決於你如何使用這些字符串。代碼的邏輯取決於實際值,還是僅僅是您從數據庫中讀取的內容,或許以某種方式轉換並呈現​​給用戶或發送給其他使用者?

如果是前者,enum可能是有保證的。

另請注意,如果要確保字符串屬於已知有效集,則可以在數據庫級別強制執行約束。所以,「數據庫可以包含任何東西」並不是真的。

一般來說,如果您使用的是數據庫,它應該是您放在那裏的數據一致性和有效性的「真相來源」。這就是數據庫的用途,這就是他們擅長的。在你的數據存儲中扔垃圾,依靠應用程序代碼在出路上消毒它並不是一個好主意。

+0

謝謝。是的,邏輯取決於代碼以及向用戶顯示的內容。該機制正在被用於各種類型。不幸的是,數據庫設計不在我的手中,來自幾個國家的幾位開發人員混淆了它。所以我寧願我可以立即證明不一致。我不知道你可以對數據庫列的值進行約束。我會研究它。 – Roland 2014-12-13 00:39:10