1 JPA概述
JPA是
Java
Persistence
API的简称,是Sun推出的J2EE规范之一,是ORM规范,Hibernate,TOPLink,OpenJPA等框架提供了JPA实现。JPA是Hibernate的作者主导制定的,所以它跟Hibernate算是有一定的血缘关系,熟悉Hibernate的话,学习JPA成本一点都不高。Hibernate3.2开始支持JPA1.0规范,Hibernate3.5开始支持JPA2.0规范,另外Hibernate也保留了原来的API。
2 JPA优势
1)ORM。因为它也属于ORM,所以ORM有的优势它都具备,对于ORM不适合的批量更新场景,可以使用JPQL直接写个SQL执行。
2)脱离容器运行。相比于EJB,它可以脱离容器独立运行。这使应用更容易测试。
3)标准化。如果你使用了JPA,就可以在各个实现中切换,而必须修改你的应用代码。
3 Helloworld
3.1 依赖的jar包
hibernate 直接到sourceforge上下就可以了,注释因为使用的是JPA2.0所以请下载hibernate3.5以后的版本。JPA的jar包不大,而且因为我之前找了半天,好多还要资源分,所以笔者直接放到附件中,就不用费心去找了。
3.2 helloworld代码
persistence.xml配置文件。
这个文件必须放到src/META-INF/目录下,否则找不到。
<?xml version="1.0"?>
<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_2_0.xsd"
version="2.0">
<persistence-unit name="myJPA" transaction-type="RESOURCE_LOCAL">
<mapping-file>course.hbm.xml</mapping-file>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="frank1234" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpatest " />
<property name="hibernate.show_sql" value="true"/>
<!--property name="hibernate.max_fetch_depth" value="3" /-->
<!--property name="hibernate.hbm2ddl.auto" value="update" /-->
</properties>
</persistence-unit>
</persistence>
<mapping-file>标签必须放到<properties>标签之前。
<property name="hibernate.show_sql" value="true"/>用于输出SQL语句,方便查看执行的SQL语句。
course.hbm.xml:
这就是一个hibernate映射文件,没有任何特殊之处。
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//HIbernate/HibernateMapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.frank1234.jpa.helloworld.Course" table="course">
<id name="id" column="id">
<generator class="identity"/>
</id>
<property name="name" />
</class>
</hibernate-mapping>
Course:
public class Course implements Serializable {
public Course(){}
private int id;
private String name;
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;
}
public String toString(){
return "id="+id+",name="+name;
}
}
JpaUtil,提供了EntiyManager的获取和关闭。
public class JpaUtil {
public static EntityManagerFactory entityFactory = null;
static{
try{
entityFactory = Persistence.createEntityManagerFactory("myJPA");
}catch(Exception e){
e.printStackTrace();
}
}
public static final ThreadLocal entityManager = new ThreadLocal();
public static EntityManager currentManager() throws HibernateException{
EntityManager manager = (EntityManager) entityManager.get();
if(manager == null){
manager = entityFactory.createEntityManager();
entityManager.set(manager);
}
return manager;
}
public static void closeManager() throws HibernateException{
EntityManager manager = (EntityManager)entityManager.get();
if(manager != null)
manager.close();
entityManager.set(null);
}
}
JpaHelloWorldMain:
增删改查。另外推荐使用JUnit写Helloworld测试代码,之前我都是用静态方法写,在main方法中调用,还得一个一个的注释放开,使用JUnit确实感受到了方便。
public class JpaHelloWorldMain {
private static EntityManager em ;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
em = JpaUtil.currentManager();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
JpaUtil.closeManager();
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void save() {
em.getTransaction().begin();
Course course = new Course();
course.setName("english");
try {
em.persist(course); //对应hibernate session.save(course);
em.getTransaction().commit();
}catch (Exception e){
e.printStackTrace();
em.getTransaction().rollback();
}
}
@Test
public void delete(){
Course course = em.find(Course.class, 33);
em.getTransaction().begin();
try{
em.remove(course);//对应hibernate session.delete(course);
em.getTransaction().commit();
}catch (Exception e){
e.printStackTrace();
em.getTransaction().rollback();
}
}
@Test
public void update(){
Course course = em.find(Course.class, 30);
em.getTransaction().begin();
try{
course.setName("1oxx");
em.persist(course);//可执行,可不执行
em.getTransaction().commit();
}catch (Exception e){
e.printStackTrace();
em.getTransaction().rollback();
}
}
@Test
public void list1(){
Course course = em.find(Course.class, 55);//相当于hibernate的get,没有数据就返回null
System.out.println(course.getName());
}
@Test
public void list2(){
Course course = em.getReference(Course.class, 55);//相当于hibernate的load,没有数据就抛异常
System.out.println(course.getName());
}
}
3.3 Helloworld注解方式
注解方式将Course修改如下即可,其他的都不用变。
@Entity
public class Course implements Serializable {
public Course(){}
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;
}
public String toString(){
return "id="+id+",name="+name;
}
}
4 同Hibernate常用接口的对照关系
Hiberate - JPA
SessionFactory - EntityManagerFactory
Session - EntityManager
save - persist
delete - remove
get - find
load - getReference