目標:通過執行個體掌握常用的具有關係的實體操作,執行個體採用大家比較熟悉的訂單管理。主要內容:n 建立資料庫表,包括訂單表和訂單明細表。n 建立持久單元和實體類n 建立管理實體類的會話Bean,添加添加訂單、刪除訂單和察看所有訂單的功能。n 編寫用戶端程式進行測試。注意:在完成第三次大作業的時候可以參考這個內容,但是不要完全按照這個做。1、 建立資料庫表訂單管理組件括訂單表和訂單明細表(正常情況下,還應該包含物品表,為了講解方便),表定義語句如下:create table ordertable( orderid char(10) not null, orderdate date, orderstate char(1), userid char(10), primary key(orderid));create table orderdetail( orderid char(10), goodid char(10), quantity int, primary key(orderid,goodid), foreign key(orderid) references ordertable(orderid)); 2、 建立持久單元和實體類操作過程與前面幾講的操作過程相同。根據上面的表結構產生的實體類的代碼如下。2.1 實體類Ordertable:package order; import java.io.Serializable;import java.util.Collection;import java.util.Date;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.Id;import javax.persistence.NamedQueries;import javax.persistence.NamedQuery;import javax.persistence.OneToMany;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType; @Entity@Table(name = "ordertable")@NamedQueries( { @NamedQuery(name = "Ordertable.findByOrderid", query = "SELECT o FROM Ordertable o WHERE o.orderid = :orderid"), @NamedQuery(name = "Ordertable.findByOrderdate", query = "SELECT o FROM Ordertable o WHERE o.orderdate = :orderdate"), @NamedQuery(name = "Ordertable.findByOrderstate", query = "SELECT o FROM Ordertable o WHERE o.orderstate = :orderstate"), @NamedQuery(name = "Ordertable.findByUserid", query = "SELECT o FROM Ordertable o WHERE o.userid = :userid") })public class Ordertable implements Serializable { @Id @Column(name = "orderid", nullable = false) private String orderid; @Column(name = "orderdate") @Temporal(TemporalType.DATE) private Date orderdate; @Column(name = "orderstate") private Character orderstate; @Column(name = "userid") private String userid; @OneToMany(cascade = CascadeType.ALL, mappedBy = "ordertable",fetch=FetchType.EAGER) private Collection<Orderdetail> orderdetailCollection; /** Creates a new instance of Ordertable */ public Ordertable() { } public Ordertable(String orderid) { this.orderid = orderid; } public String getOrderid() { return this.orderid; } public void setOrderid(String orderid) { this.orderid = orderid; } public Date getOrderdate() { return this.orderdate; } public void setOrderdate(Date orderdate) { this.orderdate = orderdate; } public Character getOrderstate() { return this.orderstate; } public void setOrderstate(Character orderstate) { this.orderstate = orderstate; } public String getUserid() { return this.userid; } public void setUserid(String userid) { this.userid = userid; } public Collection<Orderdetail> getOrderdetailCollection() { return this.orderdetailCollection; } public void setOrderdetailCollection(Collection<Orderdetail> orderdetailCollection) { this.orderdetailCollection = orderdetailCollection; } @Override public int hashCode() { int hash = 0; hash += (this.orderid != null ? this.orderid.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Ordertable)) { return false; } Ordertable other = (Ordertable)object; if (this.orderid != other.orderid && (this.orderid == null || !this.orderid.equals(other.orderid))) return false; return true; } @Override public String toString() { return "order.Ordertable[orderid=" + orderid + "]"; } }2.2 實體類Orderdetail: package order; import java.io.Serializable;import javax.persistence.Column;import javax.persistence.EmbeddedId;import javax.persistence.Entity;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.NamedQueries;import javax.persistence.NamedQuery;import javax.persistence.Table; @Entity@Table(name = "orderdetail")@NamedQueries( { @NamedQuery(name = "Orderdetail.findByOrderid", query = "SELECT o FROM Orderdetail o WHERE o.orderdetailPK.orderid = :orderid"), @NamedQuery(name = "Orderdetail.findByGoodid", query = "SELECT o FROM Orderdetail o WHERE o.orderdetailPK.goodid = :goodid"), @NamedQuery(name = "Orderdetail.findByQuantity", query = "SELECT o FROM Orderdetail o WHERE o.quantity = :quantity") })public class Orderdetail implements Serializable { @EmbeddedId protected OrderdetailPK orderdetailPK; @Column(name = "quantity") private Integer quantity; @JoinColumn(name = "orderid", referencedColumnName = "orderid", insertable = false, updatable = false) @ManyToOne private Ordertable ordertable; public Orderdetail() { } public Orderdetail(OrderdetailPK orderdetailPK) { this.orderdetailPK = orderdetailPK; } public Orderdetail( String orderid,String goodsid) { this.orderdetailPK = new OrderdetailPK(goodsid, orderid); } public OrderdetailPK getOrderdetailPK() { return this.orderdetailPK; } public void setOrderdetailPK(OrderdetailPK orderdetailPK) { this.orderdetailPK = orderdetailPK; } public Integer getQuantity() { return this.quantity; } public void setQuantity(Integer quantity) { this.quantity = quantity; } public Ordertable getOrdertable() { return this.ordertable; } public void setOrdertable(Ordertable ordertable) { this.ordertable = ordertable; } @Override public int hashCode() { int hash = 0; hash += (this.orderdetailPK != null ? this.orderdetailPK.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Orderdetail)) { return false; } Orderdetail other = (Orderdetail)object; if (this.orderdetailPK != other.orderdetailPK && (this.orderdetailPK == null || !this.orderdetailPK.equals(other.orderdetailPK))) return false; return true; } @Override public String toString() { return "order.Orderdetail[orderdetailPK=" + orderdetailPK + "]"; } }2.3 訂單明細主鍵類:package order; import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Embeddable; @Embeddablepublic class OrderdetailPK implements Serializable { @Column(name = "orderid", nullable = false) private String orderid; @Column(name = "goodid", nullable = false) private String goodid; /** Creates a new instance of OrderdetailPK */ public OrderdetailPK() { } public OrderdetailPK(String goodid, String orderid) { this.goodid = goodid; this.orderid = orderid; } public String getOrderid() { return this.orderid; } public void setOrderid(String orderid) { this.orderid = orderid; } public String getGoodid() { return this.goodid; } public void setGoodid(String goodid) { this.goodid = goodid; } @Override public int hashCode() { int hash = 0; hash += (this.goodid != null ? this.goodid.hashCode() : 0); hash += (this.orderid != null ? this.orderid.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof OrderdetailPK)) { return false; } OrderdetailPK other = (OrderdetailPK)object; if (this.goodid != other.goodid && (this.goodid == null || !this.goodid.equals(other.goodid))) return false; if (this.orderid != other.orderid && (this.orderid == null || !this.orderid.equals(other.orderid))) return false; return true; } @Override public String toString() { return "order.OrderdetailPK[goodid=" + goodid + ", orderid=" + orderid + "]"; } }3、 建立管理實體的會話Bean在會話Bean中添加如下業務方法:n 添加訂單的方法n 刪除訂單的方法n 查詢所有訂單的方法n 為訂單添加訂單項3.1 添加業務方法:添加訂單 public void addOrder(Ordertable order){ Ordertable newOrder = em.merge(order); em.persist(newOrder);}因為通過參數傳遞過來的Order實體處理分離狀態,所有需要先通過merge操作把該執行個體轉換成被管理的,然後通過persist方法持久化。注意:在持久化訂單的同時,會把與訂單關聯的訂單明細也持久化,這是通過定義管理的時候指定的“cascade”屬性完成的,代碼如下紅色部分:@OneToMany(cascade = CascadeType.ALL, mappedBy = "ordertable",fetch=FetchType.EAGER) private Collection<Orderdetail> orderdetailCollection;cascade屬性的值是CascadeType.ALL,意味著對訂單類的操作,都會級聯到關聯的訂單明細,包括下面的訂單刪除。3.2 添加業務方法:刪除訂單 public void removeOrder(String orderid){ Ordertable order = em.find(Ordertable.class,orderid); em.remove(order); }要刪除訂單,需要尋找到該訂單,然後再刪除。3.3 添加業務方法:查詢所有訂單 public List<Ordertable> getAllOrders(){ return em.createQuery("select o from Ordertable o").getResultList();}因為訂單包括訂單明細,所以在查詢所有訂單的時候,應該把該訂單涉及的所有訂單明細查詢出來,該功能是通過定義關係的時候的fetch屬性完成的,代碼如下紅色部分:@OneToMany(cascade = CascadeType.ALL, mappedBy = "ordertable",fetch=FetchType.EAGER) private Collection<Orderdetail> orderdetailCollection;如果不需要在載入實體的時候,載入該實體所關聯的實體,可以使用FetchType.LAZY。ManyToOne關係中,fetch屬性的預設值是EAGER。OneToOne關係中,fetch屬性的預設值是EAGER。OneToMany關係中,fetch屬性的預設值是LAZY。ManyToMany關係中,fetch屬性的預設值是LAZY。3.4 添加業務方法:添加訂單項 public void addItem(String orderid,String goodsid,int quantity){ Ordertable order = em.find(Ordertable.class,orderid); Orderdetail item = new Orderdetail(orderid,goodsid); item.setQuantity(quantity); if(order.getOrderdetailCollection()==null) order.setOrderdetailCollection(new Vector<Orderdetail>()); order.getOrderdetailCollection().add(item); item.setOrdertable(order); }4、 編寫用戶端程式進行測試分別對下面的3個功能進行測試:n 添加訂單n 刪除訂單n 察看訂單4.1 添加訂單添加訂單有兩種方式:n 建立訂單對象、建立訂單項對象、把訂單項添加到訂單中,然後調用會話Bean完成添加。n 建立訂單對象,調用會話Bean完成添加,然後調用會話Bean的添加訂單項方法添加具體的訂單項。下面代碼中用到的remote是注入的EJB對象。4.1.1 第一種方式 Ordertable order = new Ordertable(); String orderid="order2222"; order.setOrderid(orderid); order.setUserid("lixucheng"); order.setOrderstate('0'); order.setOrderdate(new Date()); Vector v = new Vector(); Orderdetail od1 = new Orderdetail(orderid,"goods111"); Orderdetail od2 = new Orderdetail(orderid,"goods777"); Orderdetail od3 = new Orderdetail(orderid,"goods333"); Orderdetail od4 = new Orderdetail(orderid,"goods999"); Orderdetail od5 = new Orderdetail(orderid,"goods555"); od1.setOrdertable(order); od2.setOrdertable(order); od3.setOrdertable(order); od4.setOrdertable(order); od5.setOrdertable(order); v.add(od1); v.add(od2); v.add(od3); v.add(od4); v.add(od5); order.setOrderdetailCollection(v); remote.addOrder(order); 4.1.2 第二種方式Ordertable order = new Ordertable(); order.setOrderid("order1111"); order.setUserid("lixucheng"); order.setOrderstate('0'); order.setOrderdate(new Date()); remote.addOrder(order); remote.addItem("order1111","goods111",10); remote.addItem("order1111","goods222",20); remote.addItem("order1111","goods333",30); remote.addItem("order1111","goods444",40); remote.addItem("order1111","goods555",50);4.2 刪除訂單刪除訂單需要根據訂單編號刪除。remote.removeOrder("order0000");4.3 查詢所有訂單及明細List<Ordertable> list = remote.getAllOrders();該方法調用就可以得到所有的訂單以及訂單的明細。下面是在Servlet中顯示訂單資訊的代碼: Iterator<Ordertable> i = list.iterator(); while(i.hasNext()){ Ordertable tempOrder = i.next(); out.println("訂單號:"+tempOrder.getOrderid()+" 訂單日期:"+tempOrder.getOrderdate()+" 明細:"); Iterator<Orderdetail> detail=tempOrder.getOrderdetailCollection().iterator(); while(detail.hasNext()){ Orderdetail tempDetail = detail.next(); out.println("["+tempDetail.getOrderdetailPK().getGoodid()+","+tempDetail.getQuantity()+"]"); } out.println("<br>");
}
更多內容可以參考《Java EE 5實用教程——基於WebLogic和Eclipse》