首页 > 代码库 > jpa入门之环境搭建和CRUD基本操作

jpa入门之环境搭建和CRUD基本操作

hibernate虽然好用但编写映射文件还是比较麻烦,虽然可以借助插件但是后期的维护还是比较麻烦,jpa的全称是Java Persistence API,实现该规范的产品很多像hibernate就是其中比较出名的一个,原则上应该尽量不要使用hibernate,可惜jpa只是一个接口规范,自己按照规范写一套也不现实,只能通过hibernate间接的使用jpa.

1 使用hibernate的jpa实现需要的jar包如下

我用的是hibernate3.6的版本,如果是低版本的hibernate则还需要hibernate-commons-annotations.jar、hibernate-annotations.jar


2  persistence.xml的相关配置

jpa和hibernate类似需要一个类似hibernate.cfg.xml的配置文件,该文件指定要操作的相关数据库,内容如下

<?xml version="1.0" encoding="UTF-8"?>
<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="myPersistUnit" transaction-type="RESOURCE_LOCAL">
	   <provider>org.hibernate.ejb.HibernatePersistence</provider>
	   <properties>  
               <property name="hibernate.hbm2ddl.auto" value=http://www.mamicode.com/"update" />>
相信学过hibernate应该能看懂这个配置文件,需要注意的是persistence-unit节点的name属性,这个名称后面将会用到,另外这个文件的名称只能是persistence.xml不能是别的名称且必须放在src下面的META-INF文件夹下面,如果不存在可以手动创建。

3  编写实体类

实体是jpa中比较重要的一部分,它承担着POJO和类似hibernate映射文件的功能,算得上是jpa的核心文件,下面这个是其中一个例子

package org.lxh.info;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "m_users")
public class User {
	
	private int id;
	private String name;
	private Date birthday;
	private Sex sex;
	@Id
	@GeneratedValue
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	@Column(length=20,nullable=false)
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
    @Temporal(TemporalType.DATE)
	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
    @Enumerated(EnumType.STRING)
    @Column(length=5,nullable=false)
	public Sex getSex() {
		return sex;
	}

	public void setSex(Sex sex) {
		this.sex = sex;
	}
}

下面是注解的功能描述

@Entity   这个注解表明这个java类是一个实体对象

@Table  该注解用来指定实体对应的表,默认情况下表名和实体类的名称相同

@Id         该注解用来指定主键

@GeneratedValue   该注解配置的是主键的生成策略

@Column    该注解用于指定数据库表对于的列名、唯一约束、非空约束等

@Temporal   主要用于日期属性上面,可以指定日期的类型

@Lob      指定映射到数据库的字段为大文本数据或者字节数组

@Enumerated  指定对于的属性为枚举

4  编写简单的JPA工具类

package org.lxh.util;

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

public final class JpaUtil {
  private static EntityManagerFactory em;
  static{
	  em=Persistence.createEntityManagerFactory("myPersistUnit");
  }
  public static EntityManager getEntityManager(){
	  return em.createEntityManager();
  }
}

5  JPA的crud基本操作

package org.lxh.test;

import static org.junit.Assert.*;

import java.util.*;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import org.lxh.info.Sex;
import org.lxh.info.User;
import org.lxh.util.JpaUtil;

public class Test {

	@org.junit.Test
	public void testInsert() {
		EntityManager em=null;
		EntityTransaction tx=null;
		try{
			em=JpaUtil.getEntityManager();
			tx=em.getTransaction();
			tx.begin();
			User u=new User();
			u.setBirthday(new Date());
			u.setName("潘玮柏");
			u.setSex(Sex.MAN);
			em.persist(u);
			tx.commit();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(em!=null){
				em.close();
			}
		}
		
	}
	@org.junit.Test
	public void testUpdate() {
		EntityManager em=null;
		EntityTransaction tx=null;
		try{
			em=JpaUtil.getEntityManager();
			tx=em.getTransaction();
			tx.begin();
			User u=new User();
		    u.setId(2);
			u.setName("周杰伦");
			u.setSex(Sex.MAN);
			u.setBirthday(new Date());
			em.merge(u);
			tx.commit();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(em!=null){
				em.close();
			}
		}
		
	}
	@org.junit.Test
	public void testDelete() {
		EntityManager em=null;
		EntityTransaction tx=null;
		try{
			em=JpaUtil.getEntityManager();
			tx=em.getTransaction();
			tx.begin();
		    User u=em.find(User.class, 2);
			em.remove(u);
			tx.commit();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(em!=null){
				em.close();
			}
		}
		
	}
	/**
	 * 最简单的查询
	 */
	@org.junit.Test
	public void testJPLQuery() {
		EntityManager em=null;
		EntityTransaction tx=null;
		try{
			em=JpaUtil.getEntityManager();
			String jpl="select u from User u";
		    Query q=em.createQuery(jpl);
		    List<User> all=q.getResultList();
		    Iterator<User> it=all.iterator();
		    while(it.hasNext()){
		    	User user=it.next();
		    	System.out.println(user.getName()+","+user.getBirthday());
		    }
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(em!=null){
				em.close();
			}
		}
		
	}
	/**
	 * 使用命名参数的方式更新数据
	 */
	@org.junit.Test
	public void testJPLUpdate() {
		EntityManager em=null;
		EntityTransaction tx=null;
		try{
			em=JpaUtil.getEntityManager();
			String jpl="update User u set u.name=:name where u.id=:id";
			Query q=em.createQuery(jpl);
			q.setParameter("name", "加菲猫");
			q.setParameter("id", 3);
			q.executeUpdate();
		   
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(em!=null){
				em.close();
			}
		}
		
	}
}

最后来分析一下jpa的缺点:

1> 提供的主键生成策略较少

2>没有缓存机制

3> 实体类中注解和java代码混合在一起,可读性降低了

明天接着给大家分享jpa的一对多关联关系


jpa入门之环境搭建和CRUD基本操作