买了本《EJB3 in Action》,好长时间了都没看……@_@
……
周日,忽然感觉很郁闷,就随手抽了本书看看,没想到是尘封N久的《EJB3 in Action》……
看看简介,看看目录,觉JPA很有意思,就翻到那章看了起来……
很认真的看完了,觉得很有收获,应该是理解差不多了。……夜晚已降临了,先吃点吧,晚上决定玩一把!
1、创建实体(标注很强大,有兴趣的可以查看相关EJB3的规范)
可以自己编写,也可由IDE直接生产,如下:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.ex;
import java.io.Serializable;
import java.util.Date;
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;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
*
* @author C
*/
@Entity
@Table(name = "t_test")
@NamedQueries({@NamedQuery(name = "TTest.findAll", query = "SELECT t FROM TTest t"), @NamedQuery(name = "TTest.findById", query = "SELECT t FROM TTest t WHERE t.id = :id"), @NamedQuery(name = "TTest.findByName", query = "SELECT t FROM TTest t WHERE t.name = :name"), @NamedQuery(name = "TTest.findByBirthday", query = "SELECT t FROM TTest t WHERE t.birthday = :birthday"), @NamedQuery(name = "TTest.findByFavorite", query = "SELECT t FROM TTest t WHERE t.favorite = :favorite")})
public class TTest implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@Column(name = "name")
private String name;
@Column(name = "birthday")
@Temporal(TemporalType.DATE)
private Date birthday;
@Column(name = "favorite")
private String favorite;
public TTest() {
}
public TTest(Integer id) {
this.id = id;
}
public TTest(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getFavorite() {
return favorite;
}
public void setFavorite(String favorite) {
this.favorite = favorite;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 TTest)) {
return false;
}
TTest other = (TTest) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "com.ex.TTest[id=" + id + "]";
}
}
2、创建非容器性JPA应用测试
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.ex;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceUnit;
/**
*
* @author C
*/
public class JpaTest {
@PersistenceUnit(unitName = "NoJTAPU")
private EntityManagerFactory emf = null;
public JpaTest() {
emf = Persistence.createEntityManagerFactory("NoJTAPU");
}
public EntityManager getEntityManager() {
System.out.println("===========begin create EntityManager...");
System.out.println("===========EntityManagerFactory:========="+emf);
// return (EntityManager) PersistenceProvider.getEntityManagerSetupImpl("NoJTAPU");
return emf.createEntityManager();
}
public static void main(String[] args) {
TTest te = new TTest();
te.setId(101);
te.setName("SOLO Cui");
te.setFavorite("D== Films killer");
te.setBirthday(new Date());
JpaTest jpa = new JpaTest();
EntityManager em = null;
try {
em = jpa.getEntityManager();
em.getTransaction().begin();
em.persist(te);
em.getTransaction().commit();
}catch(Exception ex){
System.out.println("=======Exception:"+ex.getMessage());
}finally{
if(em!=null){
em.close();
}
}
}
}
这里需要注意的是 em.getTransaction().begin()和em.getTransaction().commit()。Toplink的非容器性JPA应用,要自己管理事务,并需要最后关闭em和emf,以释放相关资源
3、编写Persistence.xml——持久化单元配置(我决的这里是关键点)
<?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="NoJTAPU" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name = "toplink.jdbc.driver" value = "com.mysql.jdbc.Driver"/>
<property name = "toplink.jdbc.url" value = "jdbc:mysql://localhost:3306/mytest"/>
<property name = "toplink.jdbc.user" value = "test"/>
<property name = "toplink.jdbc.password" value = "test"/>
</properties>
</persistence-unit>
</persistence>
重点说明:
3.1、本持久单元的配置文件在工程中,存放在源代码目录的META-INF下,机构形如下
-source
|-META-INF
|-persistence.xml
相关配置元素可参考http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd定义
3.2、配置元素<persistence-unit>可以有多个,必须有个名字,且需唯一,并指定ransaction-type的内容(JTA或RESOURCE_LOCAL),因为本测试并没放在容器中,所有只能配置为RESOURCE_LOCAL;
3.3、<provider>必须要有,JPA的实现;
3.4、<properties> 内容请参考Oracle的相关描述,具体参考http://www.oracle.com/technology/products/ias/toplink/JPA/essentials/toplink-jpa-extensions.html#TopLinkJDBC;
3.5、运行,成功!
4、总结
4.1、JPA很酷!!真的;
4.2、JPA的实现目前有4类(我知道的):Eclipselink、Openjpa、Toplink以及Hibernate;< provider >的实现可以使用任意一种,这里用的是Toplink;
4.3、这里只是测试,没有在中间容器中运行,也就是说,如果在容器外应用JPA,和在容器内应用JPA一样简单高效;
4.4、持久化单元配置可以N多,并可针对不同数据库,就可对Oracle,也可对Mysql,只要简单配置、标准以下就可以了;
4.5、附送我的两个持久化单元的配置信息(容器性应用JPA和非容器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="NoJTAPU" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name = "toplink.jdbc.driver" value = "com.mysql.jdbc.Driver"/>
<property name = "toplink.jdbc.url" value = "jdbc:mysql://localhost:3306/mytest"/>
<property name = "toplink.jdbc.user" value = "test"/>
<property name = "toplink.jdbc.password" value = "test"/>
</properties>
</persistence-unit>
<persistence-unit name="excenterPU" transaction-type="JTA">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<jta-data-source>jdbc/excenter</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="toplink.ddl-generation" value="create-tables"/>
</properties>
</persistence-unit>
</persistence>