`
lixucheng
  • 浏览: 79909 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

Java持久性API(JPA)第6讲——关系操作

    博客分类:
  • JPA
阅读更多

目标:通过实例掌握常用的具有关系的实体操作,实例采用大家比较熟悉的订单管理。
主要内容:
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;
@Embeddable
public 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》

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics