elicer 发表于 2013-1-13 18:48:40

Mapping boolean field to Database In open Jpa

今天研究Open Jpa的文档时发现 它的 @PrePersist @PostPersist@PostLoan这些Callback 方法 非常有用,让我们可以在entity persist 或者 load 前后做一些我们的处理,比如它解决常见的boolean field 不能跟DB 里field Mapping 的问题(Oracle and DB2 没有相应的boolean field Type)。

注意因为displayFlag是一个页面显示字段,我们是用deleteFlag来跟db里的DELETE_FLAG来mapping ,所以我们要给displayFlag加上@Transient声明,不让它成为一个可persist的field,要不然运行时会抛exception.


Example Code 如下
@Entity@NamedQueries({@NamedQuery(name="magsOverPrice",query="SELECT x FROM Magazine x WHERE x.price > ?1"),@NamedQuery(name="magsByTitle",query="SELECT x FROM Magazine x WHERE x.title = :titleParam")})@EntityListeners({MagazineListener.class})@IdClass(Magazine.MagazineId.class)@Table(name="MAGAZINE")public class Magazine {@Id private String isbn;@Id private String title;@Column(name="PRICE")   private BigDecimal price;   @Column(name="SOLDCOPY")   private int copySold;   @Column(name="VERS")   private int version;   @Column(name="DELETE_FLG")   private String deleteFlag;      @Transient   private boolean displayFlag;         public static class MagazineId {   private String isbn;   private String title;      @Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((isbn == null) ? 0 : isbn.hashCode());result = prime * result + ((title == null) ? 0 : title.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;final MagazineId other = (MagazineId) obj;if (isbn == null) {if (other.isbn != null)return false;} else if (!isbn.equals(other.isbn))return false;if (title == null) {if (other.title != null)return false;} else if (!title.equals(other.title))return false;return true;}public MagazineId() {}public String getIsbn() {return isbn;}public void setIsbn(String isbn) {this.isbn = isbn;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}   }   @PrePersistprivate void covertDisplayToDB() {if (this.displayFlag) {this.deleteFlag = "Y";}else {this.deleteFlag = "N";}}@PostLoadprivate void covertDBValueToDisplay() {if (this.deleteFlag != null && !this.deleteFlag.equals("") && this.deleteFlag.equals("Y")) {this.displayFlag = true;}else {this.displayFlag = false;}} public String getIsbn() {return isbn;}public void setIsbn(String isbn) {this.isbn = isbn;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public BigDecimal getPrice() {return price;}public void setPrice(BigDecimal price) {this.price = price;}public int getCopySold() {return copySold;}public void setCopySold(int copySold) {this.copySold = copySold;}public int getVersion() {return version;}public void setVersion(int version) {this.version = version;}public Magazine() {super();}public String getDeleteFlag() {return deleteFlag;}public void setDeleteFlag(String deleteFlag) {this.deleteFlag = deleteFlag;}public boolean isDisplayFlag() {return displayFlag;}public void setDisplayFlag(boolean displayFlag) {this.displayFlag = displayFlag;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((isbn == null) ? 0 : isbn.hashCode());result = prime * result + ((title == null) ? 0 : title.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;final Magazine other = (Magazine) obj;if (isbn == null) {if (other.isbn != null)return false;} else if (!isbn.equals(other.isbn))return false;if (title == null) {if (other.title != null)return false;} else if (!title.equals(other.title))return false;return true;}      }

这个class 里的covertDisplayToDB 方法 用来在Magazine persist 前把页面displayFlag(boolean) 转换成DB存储的field类型 varchar.

covertDBValueToDisplay 方法用来把从DB抓出来的varchar类型的deleteFlag 转换成页面显示的dsiplayFlag.


当然我们也可以给这个entity class加上一个listener,然后把所有的Annotation的方法放在listener里。

Example Code 如下 首先给entity加上EntityListener Annotation @EntityListeners({MagazineListener.class}) 然后把我们的prePersist 跟PostLoad 的Annotation 方法移到listener中

public class MagazineListener {private static final Logger log = Logger.getLogger(MagazineListener.class);@PrePersistprivate void covertDisplayToDB(Object persistObject) {Magazine magazine = (Magazine) persistObject;if (magazine.isDisplayFlag()) {magazine.setDeleteFlag("Y");}else {magazine.setDeleteFlag("N");}}@PostLoadprivate void covertDBValueToDisplay(Object persistObject) {Magazine magazine = (Magazine) persistObject;if (magazine != null && magazine.getDeleteFlag() != null && !magazine.getDeleteFlag().equals("") && magazine.getDeleteFlag().equals("Y")) {magazine.setDisplayFlag(true);}else {magazine.setDisplayFlag(false);}} }
页: [1]
查看完整版本: Mapping boolean field to Database In open Jpa