物件資料庫持久層 - Java Persistence API
Hibernate
Java 物件導向模型與關聯資料庫模型間有相當程度不匹配,而物件與資料庫資料同步、更新,常是 Java 永續儲存(Persistence)問題。
Object/Relational Mapping(ORM)簡單的說就是將 Java 中物件與物件關係,映射至關聯式資料庫中表格與表格間關係,
過去有以下自動對應轉換的方案:
而 Java Persistence API(JPA)正因應此需求,並吸取前人方案優點,所製訂出之 Java 永續儲存標準,將內含資料物件儲存至關聯式資料庫。
透過 JPA 標準定義介面可用於註解 Java 物件、使用查詢擷取物件,以及透過交易與資料庫互動。
使用 JPA 介面應用程式可與不同資料庫一起運作,不需使用特定廠商的資料庫程式碼。
Google 雲端運算平台-應用服務引擎,也使用 JPA 機制存取資料庫。
<?xml version="1.0" encoding="UTF-8"?>
<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">
<persistence-unit name="ContactPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>Contact.Contact</class>
<properties>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://資料庫-IP:資料庫服務-TCP-埠號/資料庫名稱"/>
<property name="hibernate.connection.username" value="資料庫帳號"/>
<property name="hibernate.connection.password" value="資料庫密碼"/>
</properties>
</persistence-unit>
</persistence>
package Contact; public class Main { private ContactJpaController myContactJpaController = null; public Main() { String dbHost = "資料庫-IP:資料庫服務-TCP-埠號"; String dbName = "資料庫名稱"; String dbUser = "資料庫帳號"; String dbPassword = "資料庫密碼"; this.myContactJpaController = new ContactJpaController( dbHost, dbName, dbUser, dbPassword);
} private void PrintContactInfo(Contact myContact) { System.out.println("MSN=" + myContact.getMsn()); System.out.println("\tTEL=" + myContact.getTel()); System.out.println("\tName=" + myContact.getRealName());
} private void PrintContactList(java.util.List<Contact> myContactList) { for (int i = 0; i < myContactList.size(); i++) { Contact myContact = myContactList.get(i); this.PrintContactInfo(myContact);
}
} public void ShowContactInfoByMSN(String MSN) { Contact myContact = null; try { myContact = myContactJpaController.findContact(MSN); this.PrintContactInfo(myContact);
} catch (Exception ex) { ex.printStackTrace();
}
} public void ShowAllContactInfo() { java.util.List<Contact> myContactList = null; try { myContactList = this.myContactJpaController.findContactEntities(); this.PrintContactList(myContactList);
} catch (Exception ex) { ex.printStackTrace();
}
} public void AddContact(java.util.Hashtable<String, String> ContactInfo) { Contact myContact = new Contact(); myContact.setMsn(ContactInfo.get("MSN")); myContact.setRealName(ContactInfo.get("RealName")); myContact.setTel(ContactInfo.get("TEL")); try { this.myContactJpaController.create(myContact);
} catch (Exception ex) { ex.printStackTrace();
}
} public void RemoveContactInfoByMSN(String MSN) { Contact myContact = null; try { myContact = myContactJpaController.findContact(MSN); this.myContactJpaController.destroy(MSN); this.PrintContactInfo(myContact);
} catch (Exception ex) { ex.printStackTrace();
}
} /** * @param args 命令列引數 */ public static void main(String[] args) { Main main = new Main(); // 顯示所有資料 main.ShowAllContactInfo(); // 依已知主鍵欄位 MSN 查詢單筆資料 String MSN = "RichChihLee@hotmail.com"; main.ShowContactInfoByMSN(MSN); // 新增一筆資料 java.util.Hashtable<String, String> ContactInfo = new java.util.Hashtable<String, String>(); ContactInfo.put("MSN", "RichChihLee@aim.com"); ContactInfo.put("RealName", "Rich Lee (李智)"); ContactInfo.put("TEL", "0123456789"); main.AddContact(ContactInfo); main.ShowAllContactInfo(); // 刪除一筆資料 MSN = "RichChihLee@aim.com"; main.RemoveContactInfoByMSN(MSN);
}
}
package Contact; import java.io.Serializable; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; @Entity @Table(name = "contact") @NamedQueries({ @NamedQuery(name = "Contact.findAll", query = "SELECT c FROM Contact c"), @NamedQuery(name = "Contact.findByMsn", query = "SELECT c FROM Contact c WHERE c.msn = :msn"), @NamedQuery(name = "Contact.findByRealName", query = "SELECT c FROM Contact c WHERE c.realName = :realName"), @NamedQuery(name = "Contact.findByTel", query = "SELECT c FROM Contact c WHERE c.tel = :tel")}) public class Contact implements Serializable { private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @Column(name = "MSN") private String msn; @Column(name = "RealName") private String realName; @Column(name = "TEL") private String tel; public Contact() {
} public Contact(String msn) { this.msn = msn;
} public String getMsn() { return msn;
} public void setMsn(String msn) { this.msn = msn;
} public String getRealName() { return realName;
} public void setRealName(String realName) { this.realName = realName;
} public String getTel() { return tel;
} public void setTel(String tel) { this.tel = tel;
} @Override public int hashCode() { int hash = 0; hash += (msn != null ? msn.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 Contact)) { return false;
} Contact other = (Contact) object; if ((this.msn == null && other.msn != null) || (this.msn != null && !this.msn.equals(other.msn))) { return false;
} return true;
} @Override public String toString() { return "Contact.Contact[msn=" + msn + "]";
}
}
package Contact; import Contact.exceptions.NonexistentEntityException; import Contact.exceptions.PreexistingEntityException; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.Query; import javax.persistence.EntityNotFoundException; public class ContactJpaController { public ContactJpaController() { emf = Persistence.createEntityManagerFactory("ContactPU");
} public ContactJpaController(String dbHost, String dbName, String dbUser, String dbPassword) { java.util.Properties config = new java.util.Properties(); config.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver"); config.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider"); config.setProperty("hibernate.connection.url", "jdbc:mysql://" + dbHost + "/" + dbName); config.setProperty("hibernate.connection.username", dbUser); config.setProperty("hibernate.connection.password", dbPassword); emf = Persistence.createEntityManagerFactory("ContactPU", config);
} private EntityManagerFactory emf = null; public EntityManager getEntityManager() { return emf.createEntityManager();
} public void create(Contact contact) throws PreexistingEntityException, Exception { EntityManager em = null; try { em = getEntityManager(); em.getTransaction().begin(); em.persist(contact); em.getTransaction().commit();
} catch (Exception ex) { if (findContact(contact.getMsn()) != null) { throw new PreexistingEntityException("Contact " + contact + " already exists.", ex);
} throw ex;
} finally { if (em != null) { em.close();
}
}
} public void edit(Contact contact) throws NonexistentEntityException, Exception { EntityManager em = null; try { em = getEntityManager(); em.getTransaction().begin(); contact = em.merge(contact); em.getTransaction().commit();
} catch (Exception ex) { String msg = ex.getLocalizedMessage(); if (msg == null || msg.length() == 0) { String id = contact.getMsn(); if (findContact(id) == null) { throw new NonexistentEntityException("The contact with id " + id + " no longer exists.");
}
} throw ex;
} finally { if (em != null) { em.close();
}
}
} public void destroy(String id) throws NonexistentEntityException { EntityManager em = null; try { em = getEntityManager(); em.getTransaction().begin(); Contact contact; try { contact = em.getReference(Contact.class, id); contact.getMsn();
} catch (EntityNotFoundException enfe) { throw new NonexistentEntityException("The contact with id " + id + " no longer exists.", enfe);
} em.remove(contact); em.getTransaction().commit();
} finally { if (em != null) { em.close();
}
}
} public List<Contact> findContactEntities() { return findContactEntities(true, -1, -1);
} public List<Contact> findContactEntities(int maxResults, int firstResult) { return findContactEntities(false, maxResults, firstResult);
} private List<Contact> findContactEntities(boolean all, int maxResults, int firstResult) { EntityManager em = getEntityManager(); try { Query q = em.createQuery("select object(o) from Contact as o"); if (!all) { q.setMaxResults(maxResults); q.setFirstResult(firstResult);
} return q.getResultList();
} finally { em.close();
}
} public Contact findContact(String id) { EntityManager em = getEntityManager(); try { return em.find(Contact.class, id);
} finally { em.close();
}
} public int getContactCount() { EntityManager em = getEntityManager(); try { Query q = em.createQuery("select count(o) from Contact as o"); return ((Long) q.getSingleResult()).intValue();
} finally { em.close();
}
}
}