日期:2014-05-20  浏览次数:20912 次

EJB5: JPA扩展-J2SE环境下使用EntityManager

????? 好久没有写博客了,最近比较忙,今天抽时间写点,最近的工作都是围绕EJB及JBoss的,所以这篇博客还是EJB相关。

我们知道EJB环境下Session Bean(两种状态)中可以直接使用EntityManager,使用时只需对EntityManager加一个Annotation(EJB 3)即可,如下:

@PersistenceContext(unitName="com.xxx.xxx.po") 
	EntityManager em=null;

??EJB Container看到PersistenceContext标记是会自动初始化EntityManager,在Session Bean中需要对com.xxx.xxx.po包下面的Entity类进行处理时直接可以用em既可。而实际工作中往往想在自己的代码中控制使用EntityManager,本文就是基于在J2Se环境下使用EntityManager处理POJO类完成对数据库的update。

直接写一个简单Demo:

项目Eclipse下截图:


从下向上,说明:

1 所需Jar包如图中,Jar包添加花了我好多时间,主要是Hibernate相关jar

2 oracle.properties定义数据库连接信息,如下;

hibernate.dialect=org.hibernate.dialect.Oracle10gDialect

#connection
hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver
hibernate.connection.username=IPC113
hibernate.connection.password=bpm
hibernate.connection.url=jdbc:oracle:thin:@//192.168.68.120:1521/orcl

#pool 
hibernate.c3p0.min_size=1
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50

?如上显示连接Oracle数据库,用户名IPC113,密码bpm连接URL及数据库池等

3 hibernate.cfg.xml 本来可以不要,但是我不知道用EntityManager直接产生初始化表,我知道是可以产生,但暂时用Hibernate产生初始化表

配置:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@192.168.68.120:1521:orcl</property>
        <property name="connection.username">ipc113</property>
        <property name="connection.password">bpm</property>
      	<property name="dialect">org.hibernate.dialect.OracleDialect</property>

        <property name="connection.pool_size">1</property>

        <property name="current_session_context_class">thread</property>

        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
     
		<mapping class="com.kylin.study.po.Person"/>
		<mapping class="com.kylin.study.po.Husband"/>
		<mapping class="com.kylin.study.po.Wife"/>
    </session-factory>
</hibernate-configuration>

?

4 persistence.xml,Persistence 提供者配置信息

如下:

<persistence 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"
	version="1.0">
	<persistence-unit name="com.kylin.study.po" >
		<provider>org.hibernate.ejb.HibernatePersistence</provider>

		<properties>
			<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
			<property name="hibernate.ejb.classcache.com.kylin.study.po.Person" value="read-write"/>
			<property name="hibernate.ejb.classcache.com.kylin.study.po.Husband" value="read-write"/>
			<property name="hibernate.ejb.classcache.com.kylin.study.po.Wife" value="read-write"/>
		</properties>	
	</persistence-unit>
</persistence>

5 POJO类,此处用到一对一单向映射的例子,前面http://kylinsoong.iteye.com/blog/739502中第二部分第一个Husband和Wife例子。

代码:

package com.kylin.study.po;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity  
@Table(name="t_husband")
public class Husband {   
	
    private int id;   
    
    private String name;  
    
    private Wife wife;   
    
    @Id  
    @GeneratedValue  
    public int getId() {   
        return id;   
    }   
    
    public void setId(int id) {   
        this.id = id;   
    }   
    
    public String getName() {   
        return name;   
    }   
    
    public void setName(String name) {   
        this.name = name;   
    }   
    
    @OneToOne(cascade=CascadeType.ALL)   
    @JoinColumn(name="wifeId")   
    public Wife getWife() {   
        return wife;   
    }   
    
    public void setWife(Wife wife) {   
        this.wife = wife;   
    }      
}  

?

package com.kylin.study.po;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity  
@Table(name="t_wife")
public class Wife {   
	
    private int id;  
    
    private String name;  
    
    @Id  
    @GeneratedValue  
    public int getId() {   
        return id;   
    }   
    
    public void setId(int id) {   
        this.id = id;   
    }   
    
    public String getName() {   
        return name;   
    }   
    
    public void setName(String name) {   
        this.name = name;   
    }   
}  

?

package com.kylin.study.po;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity  
@Table(name="t_person")
public class Person {

	private int id;
	
	private String name;

	@Id  
    @GeneratedValue
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

?

6。测试代码:

package com.kylin.study.jpa;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.BeforeClass;
import org.junit.Test;

import com.kylin.study.po.Husband;
import com.kylin.study.po.Person;
import com.kylin.study.po.Wife;

public class JPAJ2SETest {
	
	private static EntityManager em ;
	
	@BeforeClass
	public static void beforeClass() {
		String persistence_unit = "com.kylin.study.po";
		
		Properties prop = new Properties();
		InputStream is = JPAJ2SETest.class.getClassLoader().getResourceAsStream("oracle.properties");
		try {
			prop.load(is);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(is != null)
					is.close();
			} catch (IOException ignored) {
			}
		}
		
		EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistence_unit, prop);
		em = emf.createEntityManager();
	}
	
	@Test
	public void createTestTables() {
		new SchemaExport(new AnnotationConfiguration().configure()).create(true, true);
	}
	
	@Test
	public void save() {
		EntityTransaction t = em.getTransaction();
		t.begin();
		Person kobe = new Person();
		kobe.setName("Kobe Bryant");
		Person vanessa = new Person();
		vanessa.setName("Vanessa Bryant");
		em.persist(kobe);
		em.persist(vanessa);
		t.commit();
	} 
	
	@Test
	public void query() {
		EntityTransaction t = em.getTransaction();
		t.begin();
		String str = "Kobe Bryant";
		Query query = em.createQuery("from Person where name='" + str + "'");
		List<Person>lists = query.getResultList();
		for(Person p : lists) {
			System.out.println(p.getId() + " " + p.getName());
		}
		t.commit();
	}
	
	@Test
	public void find() {
		EntityTransaction t = em.getTransaction();
		t.begin();
		Object obj = em.find(Person.class, 1);
		t.commit();
		System.out.println(obj);
	}
	
	@Test
	public void delete() {
		EntityTransaction t = em.getTransaction();
		t.begin();
		Object obj = em.find(Person.class, 1);
		em.remove(obj);
		t.commit();
	}
	
	@Test
	public void one2Onesave() {
		EntityTransaction t = em.getTransaction();
		t.begin();
		Husband kobe = new Husband();
		kobe.setName("Kobe Bryant");
		Wife vanessa = new Wife();
		vanessa.setName("Vanessa Bryant");
		kobe.setWife(vanessa);
		em.persist(kobe);
		t.commit();
	} 
	
	@Test
	public void one2Onequery() {
		EntityTransaction t = em.getTransaction();
		t.begin();
		Query query1 = em.createQuery("from Husband");
		List<Husband> husbands = query1.getResultList();
		for(Husband h : husbands) {
			System.out.println(h.getId() + " " + h.getName() + " " + h.getWife().getId() + " " + h.getWife().getName());
		}
		Query query2 = em.createQuery("from Wife");
		List<Wife> wifes = query2.getResultList();
		for(Wife w : wifes) {
			System.out.println(w.getId() + " " + w.getName());
		}
		t.commit();
	}
	
	@Test
	public void one2Onefind() {
		EntityTransaction t = em.getTransaction();
		t.begin();
		Husband kobe = em.find(Husband.class, 21);
		System.out.println(kobe.getId());
		System.out.println(kobe.getName());
		System.out.println(kobe.getWife().getId());
		System.out.println(kobe.getWife().getName());
		t.commit();
	}
	
	@Test
	public void one2Onedelete() {
		EntityTransaction t = em.getTransaction();
		t.begin();
		Husband kobe = em.find(Husband.class, 21);
		em.remove(kobe);
		Query query2 = em.createQuery("from Wife");
		List<Wife> wifes = query2.getResultList();
		for(Wife w : wifes) {
			System.out.println(w.getId() + " " + w.getName());
		}
		t.commit();
	}
	
	public static void main(String[] args ) {
//		JPAJ2SETest test = new JPAJ2SETest();
//		JPAJ2SETest.beforeClass();
//		test.save();
	}

}

?依次向下执行测试类方法:

(1)createTestTables()执行完后,数据库中产生了三张表,如下:



?(2)save()向数据库中存入两个Person,Kobe和他老婆

(3)query()可以查看数据库中所有名字是Kobe Bryant的人,执行结果:

1 Kobe Bryant
3 Kobe Bryant

?

(4)find()查找一个Person对象,id为1,执行结果

com.kylin.study.po.Person@16ea269

?

(5) delete()删除一个id为1Person对象;

(6)one2Onesave()同样存储一个一对一的对象,同样是Kobe和他老婆

(7)one2Onequery()查询刚插入的数据,主要验证,一对多单向可以用一方获取另一方,执行结果:

21 Kobe Bryant 22 Vanessa Bryant
22 Vanessa Bryant

?

(8)one2Onefind()查找id为21的丈夫,执行结果:

21
Kobe Bryant
22
Vanessa Bryant

?(9)one2Onedelete()删除id为21的Husband,主要验证删除Husband后相关的Wife也删除

?

到此例子结束,有好多问题,比如,如何直接用JPA API生成表等,值得去研究,由于时间不说写……