2012-02-19 44 views
4

使用枚舉而不是文字來引用表和列的名稱是一種很好的做法嗎?或者它只是矯枉過正?使用枚舉來存儲**行和列的數據庫名稱是矯枉過正的?

E.g.
而不是做這個的:

executeQuery("SELECT name, age FROM people WHERE id = '23';"); 

做這樣的事情:

executeQuery("SELECT "+COLUMN.NAME.getName()+", "+COLUMN.AGE.getName()+ 
    "FROM "+ TABLE.PEOPLE.getName()+" WHERE "+COLUMN.ID.getName()+" = '23';"); 

有了這個枚舉

public Enum COLUMN{ 
    NAME("name"), 
    AGE("age"), 
    ID("id"); 
    //... 
} 

又是怎麼回事時,DB的結構還不是非常好定義,但你有義務開始使用尚未定義的數據庫開發代碼?

回答

3

我個人稱之爲矯枉過正。這就是所謂的「軟編碼」,當你花費太多時,它與硬編碼一樣糟糕。可能更糟糕的是,因爲它的壞處更加微妙 - 對於那些一遍又一遍地聽到硬編碼的「惡魔」的人來說,這是非常誘人的。

考慮當年齡欄名稱更改時會發生什麼情況。你或者有一個枚舉值不再對應於列的名字(閱讀:代碼對你說謊),或者你必須通過並更改每個引用COLUMN.AGE以使用COLUMN.NEW_NAME_FOR_AGE而不是(你沒有保存自己從之後的編輯代碼,這可能是你考慮這個的最大原因)。如果結構發生變化,那甚至不會發生什麼情況。如果列移動到另一個表或其他東西,你的枚舉根本無法應付。

如果你確實沒有對數據庫的任何控制權,或者使用存儲過程並讓數據庫處理列名稱的細節,那麼您應該或者將列的名稱作爲該類的私有靜態成員。

哦,並與任何人要求您針對尚未設計的數據庫進行編碼。你至少可以得到一些事情。如果不是這樣,那麼一定要去存儲的proc路徑,讓他們擔心在事情發生變化時獲取列名稱。

0

改爲使用存儲過程。讓數據庫擔心所有的SQL,讓你的代碼擔心它將如何處理數據。

我通常的做法是有一個類(通常是靜態的)專用於與數據庫交互。每個存儲過程在類中都有自己的靜態方法。

+0

存儲的特效都非常/大都/一般DB-具體,這是好的,但它是一個非常強的假設,我想。 – 2012-02-19 00:37:04

0

在這裏使用枚舉是巨大的矯枉過正,它使你的代碼更難讀寫。

如果您擔心有太多的代碼直接與數據庫進行交互(如果您不是,您可能應該這麼做),更好的方法是使用ORM。

0

如果使用這種方法,當您更改模式並在編寫查詢時有更多工作時,您的工作量會減少。它是如此簡單。

從我寫這種應用程序的經驗(網絡應用程序)我不會這樣做。這是一個判斷力的決定因素。

作爲一個側面說明,你不必使用枚舉。你可以使用任何你想要的常數。

+0

當架構更改僅限於重命名列和表時,工作量會減少,就這些了。如果模式發生重大變化(提取細節表,通過查找表將一對多轉換爲多對多等),那麼他現在必須付出更多的努力來改變他的查詢。他們如何寫。 – 2012-02-19 00:30:59

0

YES枚舉可以是組織表並快速枚舉列名的好方法。例如在卡桑德拉我做的:

public class EventSchema 
{ 
    public static enum EVENTS { 
     TYPE_ID("type_id"), 
     SLICE_START_TIME("slice_start_time"), 
     EVENT_TIME("event_time"), 
     EVENT_ID("event_id"), 
     EVENT_PAYLOAD("event_payload"); 

     public final static String TABLE_NAME = "events"; 
     public final String COLUMN_NAME; 
     EVENTS (String name) {COLUMN_NAME = name;} 
     public String toString() {return COLUMN_NAME;} 
     public static String[] names() { 
      return Arrays.toString(values()).replaceAll("\\[|]", "").split(", "); 
     } 
    } 

    public void addEvent (String keyspace, String typeId, long timeSliceStart, long timeSliceDuration, Event event) { 
     Object[] values = {typeId, timeSliceStart, event.getTime(), event.getId(), event.getDetails()}; 
     Statement stmt = QueryBuilder.insertInto(EVENTS.TABLE_NAME).values(EVENTS.names(), values); 
     getSession(keyspace).execute(stmt); 

    } 
} 

相關問題