对 Entity 的初步构思
2019獨角獸企業重金招聘Python工程師標準>>>
本文是《輕量級 Java Web 框架架構設計》的系列博文。
Hibernate 框架確實挺好,最早我們使用它的?ORM 配置文件,當時確實覺得有些累。于是后來就有了 Doclet 這樣的技術,這樣 ORM 配置文件就不用寫了,但 Java Doc 卻要寫一大堆。直到最后,救星終于來了!它就是 JPA。隨后, Hibernate 就成為 JPA 規范中的一個實現了,這表明了什么呢?注解才是去掉繁重的?XML 配置文件的真正解決之道(至少目前是這樣,將來就不好說了)。我也深受了 JPA 的影響,想搞一個更加輕量級的 JPA,目的就是實用性強,此外還需要通過編碼規范來確保每個程序員都能正確的完成自己的工作任務。
領域建模是 Hibernate 所推崇的開發方式,首先要根據業務需求確定 Domain,用?Hibernate?的話來講就是 Entity(實體)。下面以 Product ?Entity為例,描述一下我對 Entity 的構想:
@Table("product") public class Product extends Entity {@Column("product_type_id")private long productTypeId;@Column("product_name")private String productName;@Column("product_code")private String productCode;@Column("price")private int price;@Column("description")private String description;public long getProductTypeId() {return productTypeId;}public void setProductTypeId(long productTypeId) {this.productTypeId = productTypeId;}public String getProductName() {return productName;}public void setProductName(String productName) {this.productName = productName;}... 省略其他 getter/setter 方法 }第1行:使用 @Table 注解來定義 Product 實體對應于 product 表,這注解與 JPA 的 @Entity +?@Table 作用相同,可認為這里簡化了配置。
第2行:該 Product Entity 繼承于 Entity,這樣做是為了在父類?Entity 中封裝每個業務實體所共有的屬性,例如:id,MySQL 建議我們每張表最好有一個 id 主鍵,我想還是它的道理的。
第3行:使用 @Column 注解標明 productName 屬性與 product_name 列相對應。當然,這里是不是也要 JPA 那樣,指定 Column 的數據類型以及長度與精度呢?我個人認為這是不必要的,因為在實際開發工作當中,一般是由架構師或者 DBA 來創建數據庫表結構(即 Database Schema),我們拿到這份表結構文檔之后,在此基礎之上再編寫相應的 Entity。所以,我們在編寫這個 Entity 的時候,可以假設數據庫已經存在了,而無需再像 Hibernate 那樣根據 Entity 中的注解自動生成數據庫的?DDL。這樣自動化的生成,其實對項目的風險也挺大的。此外,這里推薦對每個屬性都配置 @Column 注解,不管它們的拼寫是否完全一致。當然不寫 @Column 注解也是可以的,但是這個不妨作為編碼規范,把 Code Review 的任務交給架構師去吧。
下面再來看看這個 Entity 類吧:
public abstract class Entity extends Bean {@Column("id")private long id;public long getId() {return id;}public void setId(long id) {this.id = id;} }它是一個抽象類。其實就包含一個 id 屬性,當然可以從業務需求中可以盡可能的抽象出公共的屬性,統一在這里定義。注意,該類又繼承了一個 Bean 類,那么這個 Bean 類又是怎樣的呢??
最后再來看看這個 Bean?類吧:
public abstract class Bean implements Serializable {@Overridepublic int hashCode() {return HashCodeBuilder.reflectionHashCode(this);}@Overridepublic boolean equals(Object obj) {return EqualsBuilder.reflectionEquals(this, obj);}@Overridepublic String toString() {return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);}public String toJson() {return JSONUtil.toJSON(this);}public String toXML() {return XMLUtil.toXML(this);} } 它也是一個抽象類。首先,它實現了?Serializable 接口,也就是可以序列化了,這樣更有助于網絡傳輸。為什么要將序列化接口實現在最基礎的 Bean 類中呢?這樣做是因為,繼承該類的其他子類無需再次實現這個序列化接口了,配置也更加簡單了。 其次,這里還定義了一些公共方法,Java 自帶的 hashCode()、equals()、toString() 方法,這些方法均使用了 Apache Commons 的? lang 包來實現。 ?最后,還有兩個非常實用的方法,toJSON() 與 toXML() 方法,其作用我想已經不言而喻了。
如果有了以上這樣的繼承體系,那么每個 Entity 是不是更加強大了呢?此外,Bean 類還可用于非 Entity 類上,這樣它的功能又進一步得到了復用。
請大家對以上構思,提點建議或意見吧!
補充(2013-09-03)
根據大家提供的建議,我將 Entity 定義為以下結構:
public class Product extends BaseEntity {private long productTypeId;private String productName;private String productCode;private int price;private String description;public long getProductTypeId() {return productTypeId;}public void setProductTypeId(long productTypeId) {this.productTypeId = productTypeId;}... }這里沒有任何的注解,只是繼承了 BaseEntity 這個類(也就是上文提到的 Entity 抽象類,為了便于理解,這里將其重命名為 BaseEntity)。Java 類中的 Field 會自動映射為數據庫中的 Column,映射規則只是將“駝峰風格”的 Field 與“下劃線”風格的 Column 進行映射,例如:productTypeId 對應于 product_type_id。這些映射規則完全由框架來實現,對程序員完全透明,程序員要做的事情就是 extends BaseEntity 了。?
是不是比 JPA 要簡單呢?那么框架又是如何實現的呢?敬請期待...
轉載于:https://my.oschina.net/huangyong/blog/158481
總結
以上是生活随笔為你收集整理的对 Entity 的初步构思的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery的弹出窗口插件colorbo
- 下一篇: VS2010开发ribbon风格的程序