物件資料庫持久層 - Java Persistence API

開發工具:

運行環境:

資料庫:

資料表格:

持久層框架:

JPA 設定:

persitence.xml

主程式:

持久層程式:

持久層調用程式:

JPA

mySQL

Contact

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();

}

}

}