JPA (Java Persistence API)

JPA

JPA是JAVA EE的重要组成部分, 它不再是EJB里面的一种BEAN, 可以在一般的Servlet容器中使用, 并不一定要应用服务器的支持, 可以看
成实体BEAN的替代品. 相比实体BEAN(CMP), JPA开发开发起来更加简化, 也更加轻量级, 使用了Annotation代替了原来繁琐的XML文件的配
置, 在API方面倒是跟Hibernate非常相似.

一. persistence.xml(此文件位于MATE-INF下, 是JPA的主配置文件)
  格式如下:

三. 实体管理
  1. 容器管理(使用@PersistenceContext对EntityManager实行注射, 完成初始化)
    @javax.persistence.PersistenceContext(unitName="persistence_sample")
    private EntityManager em ;
    .......................................................................

  2. 应用管理的实体管理(Application-Managed Entity Managers)
   此时, 由于取不到上下文的信息, 我们只能采用这种方式实现得到EntityManager
   @PersistenceUnit
   EntityManagerFactory emf;
   然后, 从EntityManagerFactory获取一个EntityManager实例:
   EntityManager em = emf.createEntityManager();

四. 实体的生命周期(四种状态)
  1. new 创建
  2. managed 管理
  3. detached 托管
  4. removed 删除
  
五. 实体操作
  1. 实体的查找

  2. 持久化实体实例(Persisting Entity Instances)
  调用persist方法, 使新的实体类成为被管理的持久对象
  3. 实体类中的实体关系(@OneToMany, @ManyToMany, @OneToOne, @ManytoOne)

 

4. 删除实体
  public void removeOrder(Integer orderId) {
  try {
  Order order = em.find(Order.class, orderId);
  em.remove(order);
  }...   

  5. 实体的查询
   1.) createQuery
   public List findWithName(String name) {
    return em.createQuery(
    "SELECT c FROM Customer c WHERE c.name LIKE :custName")
    .setParameter("custName", name)
    .setMaxResults(10)
    .getResultList();
   }  
   
   2.) createNamedQuery
   使用Annotation定义NamedQuery
   @NamedQuery(
   name="findAllCustomersWithName",
   query="SELECT c FROM Customer c WHERE c.name LIKE :custName"
   )
   
   @PersistenceContext
   public EntityManager em;
   ...
   customers = em.createNamedQuery("findAllCustomersWithName")
   .setParameter("custName", "Smith")
   .getResultList();
   
   指定参数名字
   public List findWithName(String name) {
    return em.createQuery(
    "SELECT c FROM Customer c WHERE c.name LIKE :custName")
    .setParameter("custName", name)
    .getResultList();
   }  
   指定参数位置
   public List findWithName(String name) {
    return em.createQuery(
    "SELECT c FROM Customer c WHERE c.name LIKE ?1")
    .setParameter(1, name)
    .getResultList();
   }
   
  6. 用实体更新数据库记录
   我们首先找到这个实体对象, 然后对它进行操作
   public void buyBooks(ShoppingCart cart) throws OrderException{
    Collection items = cart.getItems();
    Iterator i = items.iterator();
    try {
     while (i.hasNext()) {
     ShoppingCartItem sci = (ShoppingCartItem)i.next();
     Book bd = (Book)sci.getItem();
     String id = bd.getBookId();
     int quantity = sci.getQuantity();
     buyBook(id, quantity);
     }
    } catch (Exception ex) {
     throw new OrderException("Commit failed: "
     + ex.getMessage());
    }
   }
   
   public void buyBook(String bookId, int quantity)
   throws OrderException {
    try {
     Book requestedBook = em.find(Book.class, bookId);
     if (requestedBook != null) {
     int inventory = requestedBook.getInventory();
     if ((inventory - quantity) >= 0) {
     int newInventory = inventory - quantity;
     requestedBook.setInventory(newInventory);
     } else{
     throw new OrderException("Not enough of "
     + bookId + " in stock to complete order.");
     }
     }
    } catch (Exception ex) {
     throw new OrderException("Couldn't purchase book: "
     + bookId + ex.getMessage());
    }
   }
   
  7. JTA事务支持
   @Resource
   UserTransaction utx;
   ...
   try {
    utx.begin();
    bookDBAO.buyBooks(cart);
    utx.commit();
   } catch (Exception ex) {
   try {
    utx.rollback();
   } catch (Exception exe) {
    System.out.println("Rollback failed: "+exe.getMessage());
   }
   
  8. 主键产生策略
   1.) @Id (含有主键的表, 自己管理主键)
   
   2.) 主键用一个专门的表产生
      @TableGenerator(name="ADDRESS_ID_GEN",
              table="ID_GEN",
              pkColumnName="GEN_KEY",
              valueColumnName="GEN_VALUE",
              pkColumnValue="ADDRESS_ID",
              allocationSize=1)
              @GeneratedValue(strategy=GenerationType.TABLE,generator="ADDRESS_ID_GEN")
              @Id
              public String getAddressID() {
          return addressID;
      }
   
    3.) 使用主键类
    package order.entity;
    public final class LineItemKey implements
    java.io.Serializable {
     private Integer orderId;
     private int itemId;
     public int hashCode() {
      return ((this.getOrderId()==null
      ?0:this.getOrderId().hashCode())
      ^ ((int) this.getItemId()));
     }
     public boolean equals(Object otherOb) {
      if (this == otherOb) {
       return true;
      }
      if (!(otherOb instanceof LineItemKey)) {
       return false;
      }
      LineItemKey other = (LineItemKey) otherOb;
      return ((this.getOrderId()==null
      ?other.orderId==null:this.getOrderId().equals
      (other.orderId)) && (this.getItemId ==
      other.itemId));
     }
     public String toString() {
      return "" + orderId + "-" + itemId;
     }
    }
    
    @IdClass(order.entity.LineItemKey.class)
    @Entity
    ...
    public class LineItem {
    ...
    }              
  
 

 

java 代码
  1. @PersistenceContext  
  2. EntityManager em;   
  3. ...   
  4. public LineItem createLineItem(Order order, Product product,   
  5. int quantity) {   
  6.     LineItem li = new LineItem(order, product, quantity);   
  7.     order.getLineItems().add(li);   
  8.     em.persist(li);   
  9.     return li;   
  10. }  

 

xml 代码

 

  1. <persistence>  
  2.     <persistence-unit name="OrderManagement">  
  3.         <description>This unit manages orders and customers.   
  4.         It does not rely on any vendor-specific features and can   
  5.         therefore be deployed to any persistence provider.   
  6.         description>  
  7.         <jta-data-source>jdbc/MyOrderDBjta-data-source>  
  8.         <jar-file>MyOrderApp.jarjar-file>  
  9.         <class>com.widgets.Orderclass>  
  10.         <class>com.widgets.Customerclass>  
  11.     persistence-unit>  
  12. persistence>  
  13.   
  14. xml version="1.0" encoding="UTF-8"?>  
  15. <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">  
  16.   <persistence-unit name="persistence_sample" transaction-type="JTA">  
  17.     <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProviderprovider>  
  18.     <jta-data-source>jdbc/SamplesDBjta-data-source>  
  19.     <properties>  
  20.       <property name="toplink.ddl-generation" value="drop-and-create-tables"/>  
  21.     properties>  
  22.   persistence-unit>  
  23. persistence>  

 

 

二. 实体类
  使用annotation @Entity标识它是实体类
  使用@Id 标识它是主键
  使用@Table 标识这个实体类对应的数据库表, 如果类名跟表名相同, 则可以省略

java 代码

 

  1. import java.io.Serializable;   
  2. import javax.persistence.Entity;   
  3. import javax.persistence.Id;   
  4. import javax.persistence.Table;   
  5. @Entity  
  6. @Table(name="WEB_BOOKSTORE_BOOKS")   
  7. public class Book implements Serializable {   
  8. private String bookId;   
  9. private String title;   
  10. public Book() { }   
  11.   
  12. public Book(String bookId, String title, ...) {   
  13.     this.bookId = bookId;   
  14.     this.title = title;   
  15.     ...   
  16. }   
  17. @Id  
  18. public String getBookId() {   
  19.     return this.bookId;   
  20. }   
  21. public String getTitle() {   
  22.     return this.title;   
  23. }   
  24. ...   
  25. public void setBookId(String id) {   
  26.     this.bookId=id;   
  27. }   
  28. public void setTitle(String title) {   
  29.     this.title=title;   
  30. }   
  31. ...   
  32. }  

 

java 代码
  1. package enterprise.customer_cmp_ejb.ejb.session;   
  2.   
  3. import javax.ejb.Stateless;   
  4. import javax.ejb.Stateful;   
  5. import javax.ejb.SessionContext;   
  6. import javax.persistence.*;   
  7. import javax.ejb.*;   
  8. import java.util.List;   
  9.   
  10. import enterprise.customer_cmp_ejb.persistence.*;   
  11. import enterprise.customer_cmp_ejb.common.*;   
  12. /**  
  13.  *  
  14.  * @author Rahul Biswas  
  15.  *  
  16.  * Why a facade?    
  17.  * 1. session beans are thread safe, and EMs are not necessarily; so injecting a EM into a SessionBean makes it safe.   
  18.  * 2. Tx management is taken care of by container  
  19.  * 3. of course, because it's a facade [we can combine operations].  
  20.  *   
  21.  */  
  22. @Stateless  
  23. @TransactionManagement(value=TransactionManagementType.CONTAINER)   
  24.   
  25. public class CustomerSession implements CustomerSessionLocal, CustomerSessionRemote{   
  26.        
  27.     @javax.persistence.PersistenceContext(unitName="persistence_sample")   
  28.     private EntityManager em ;   
  29.        
  30.        
  31.     public CustomerSession(){   
  32.            
  33.     }   
  34.   
  35.     public Customer searchForCustomer(String id){   
  36.            
  37.         Customer cust = (Customer)em.find(Customer.class, id);   
  38.         return cust;   
  39.     }   
  40.        
  41.        
  42.     public Subscription searchForSubscription(String id){   
  43.            
  44.         Subscription subscription = (Subscription)em.find(Subscription.class, id);   
  45.         return subscription;   
  46.     }   
  47.        
  48.     public Address searchForAddress(String id){   
  49.            
  50.         Address address = (Address)em.find(Address.class, id);   
  51.         return address;   
  52.            
  53.     }   
  54.        
  55.     //This is the default; here as an example of @TransactionAttribute   
  56.     @TransactionAttribute(TransactionAttributeType.REQUIRED)   
  57.     public void remove(Object obj){   
  58.         Object mergedObj = em.merge(obj);   
  59.         em.remove(mergedObj);   
  60.     }   
  61.        
  62.     public void persist(Object obj){   
  63.         em.persist(obj);   
  64.     }   
  65.        
  66.     public List findAllSubscriptions(){   
  67.        
  68.         List subscriptions = em.createNamedQuery("findAllSubscriptions").getResultList();   
  69.         return subscriptions;   
  70.            
  71.     }   
  72.        
  73.     public List findCustomerByFirstName(String firstName){   
  74.         List customers = em.createNamedQuery("findCustomerByFirstName").setParameter("firstName", firstName).getResultList();   
  75.         return customers;   
  76.     }   
  77.        
  78.     public List findCustomerByLastName(String lastName){   
  79.         List customers = em.createNamedQuery("findCustomerByLastName").setParameter("lastName", lastName).getResultList();   
  80.         return customers;   
  81.     }   
  82.        
  83.        
  84.     public Customer addCustomerAddress(Customer cust, Address address){   
  85.            
  86.         Customer mergedCust = em.merge(cust);   
  87.         mergedCust.getAddresses().add(address);   
  88.         return mergedCust;   
  89.            
  90.     }   
  91.        
  92.     public Customer removeCustomerSubscription(String cust, String subs) throws SubscriptionNotFoundException{   
  93.            
  94.         //System.out.println("called remove Customer Subscription.....");   
  95.            
  96.         Customer customer = (Customer)em.find(Customer.class, cust);   
  97.         Subscription subscription = (Subscription)em.find(Subscription.class, subs);   
  98.            
  99.         if(!customer.getSubscriptions().contains(subscription)){   
  100.             System.out.println("remove: did not find a subscription obj for :"+subscription.getTitle());   
  101.             throw new SubscriptionNotFoundException();   
  102.         }   
  103.            
  104.         customer.getSubscriptions().remove(subscription);   
  105.         subscription.getCustomers().remove(customer);   
  106.            
  107.         return customer;   
  108.     }   
  109.        
  110.     public Customer addCustomerSubscription(String cust, String subs) throws DuplicateSubscriptionException{   
  111.            
  112.         //System.out.println("called add Customer Subscription.....");   
  113.         Customer customer = (Customer)em.find(Customer.class, cust);   
  114.         Subscription subscription = (Subscription)em.find(Subscription.class, subs);   
  115.            
  116.         if(customer.getSubscriptions().contains(subscription)){   
  117.             System.out.println("add: found an existing subscription obj for :"+subscription.getTitle());   
  118.             throw new DuplicateSubscriptionException();   
  119.         }   
  120.            
  121.         customer.getSubscriptions().add(subscription);   
  122.         subscription.getCustomers().add(customer);   
  123.            
  124.         return customer;   
  125.            
  126.     }   
  127.        
  128. }  

 

java 代码
  1. @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)   
  2.   
  3. @OneToMany(cascade=ALL, mappedBy="order")   
  4. public Collection <lineitem></lineitem>  getLineItems() {   
  5. return lineItems;   
  6. }   
  7.   
  8. @ManyToMany(fetch=FetchType.EAGER )   
  9.   @JoinTable(   
  10.           name="CUSTOMERBEANSUBSCRIPTIONBEAN",   
  11.           joinColumns=@JoinColumn(name="CUSTOMERBEAN_CUSTOMERID96", referencedColumnName="customerid"),    
  12.           inverseJoinColumns=@JoinColumn(name="SUBSCRIPTIONBEAN_TITLE", referencedColumnName="TITLE")    
  13.   )   
  14.   public Collection<subscription></subscription> getSubscriptions(){   
  15.       return subscriptions;   
  16.   }        
  17.   
  18. @OneToOne(optional=false)   
  19.   @JoinColumn(   
  20.       name="CUSTREC_ID", unique=true, nullable=false, updatable=false)   
  21.   public CustomerRecord getCustomerRecord() { return customerRecord; }   
  22.   
  23. @ManyToOne(optional=false)    
  24.   @JoinColumn(name="CUST_ID", nullable=false, updatable=false)   
  25.   public Customer getCustomer() { return customer; }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值