`
lovethisworld
  • 浏览: 52531 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JPA初识

    博客分类:
  • JPA
阅读更多

 

 JPA(Java Persistence API)为Java开发人员提供一种对象/关系映射工具以管理Java应用程序中的关系数据。JPA包含三个部分:

 

  • Java持久性API
  • 持久性查询语言JPQL
  • 对象/关系映射元数据

JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用的对象持久化的开发工作;其二,Sun希望整合对ORM技术,实现天下归一。JPA时一种持久化规范,其具体实现可以是Hibernate、TopLink,JDO等ORM框架,开发人员只需要根据JPA规范开发,而不是针对某个ORM框架,降低了耦合性。

JPA可以脱离容器运行,既可以在J2SE和J2EE环境运行,先动手试试:

 

  • 依赖jar包:

这里使用hibernate作为实现orm框架,需要jar包如下:

hibernate-distribution核心包下的
  hibernate3.jar, 
  lib\bytecode\cglib\hibernate-cglib-repack.jar,
  lib\required\*.jar

hibernate-annotations注解包:
  hibernate-annotations.jar,
  lib\ejb3-persistence.jar,
  hibernate-commons-annotation.jar

hibernate-entitymanager对JPA的实现包:
  hibernate-entitymanager.jar,
  lib\test\log4j.jar,slf4j-log4j12.jar 
  • 配置文件persistence.xml,需要放置在类路径下META-INF文件夹下
<?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="JPA" transaction-type="RESOURCE_LOCAL">
	<provider>org.hibernate.ejb.HibernatePersistence</provider>
   	<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.url" value = "jdbc:mysql://localhost:3306/jpa?useUnicode=true&amp;characterEncoding=UTF-8"/>
	    <property name = "hibernate.connection.username" value = "root"/><property name = "hibernate.connection.password" value = "root"/>
	    <property name="hibernate.max_fetch_depth" value="3"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>  
	  </properties>
	</persistence-unit>
</persistence>
  • 实体
@Entity	// 所有实体类必须标示为javax.persistence.Entity
public class Person {

	private Integer id;
	private String name;
	private Date birthday;//1988-02-01
	private Gender gender=Gender.MAN;
	private String info;
	private Byte[] file;
	private String imagePathString;
	
        //必须有无参构造方法
	public Person(){
	}
	
	public Person(String name){
		this.name=name;
	}

	@Id @GeneratedValue(strategy=GenerationType.AUTO)
	public Integer getId() {
		return id;
	}
	
	@Column(length=10,nullable=false)
	public String getName() {
		return 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) //设置长度,是否为null
	public Gender getGender() {
		return gender;
	}

	@Lob //大数据字段的说明,用在String上面是个大文本类型
	public String getInfo() {
		return info;
	}

	@Lob //大数据字段说明,用在这里是存放二进制数据的类型
	@Basic(fetch=FetchType.LAZY)   //延迟加载,当访问此属性的get方法时才会从数据库加载到内存,此时必须保证em处于打开状态,否则会有延迟加载错误。
	public Byte[] getFile() {
		return file;
	}


	@Transient //此属性不成为持久化字段
	public String getImagePathString() {
		return imagePathString;
	}
	
	// setter方法
	
}
    枚举类
public enum Gender {
  MAN,WOMAN
}
  • 测试

 

public class TestPersonCRUD {
	
	private static EntityManagerFactory fac;
	private EntityManager em;
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		// 根据persistence.xml的配置规则,如设为create,每次加载hibernate时都会重建数据库
		fac = Persistence.createEntityManagerFactory("test");
	}
	
	@Before
	public void beforeTest() {
		em = fac.createEntityManager();
	}
	
	@Test
	public void test() {
		test_save();
		test_find();
		test_update();
		test_delete();
	}
	
	public void test_save() {
		// 此时数据库表已经建立,若没有表,很可能是实体的注解出错了。
		em.getTransaction().begin();// 开启事务
		Person person = new Person("lzz");
		person.setBirthday(new Date());
		em.persist(person);
		em.getTransaction().commit();// 提交事务
	}

	public void test_find() {
		// 读取不用开启事务
		// 1为主键值,不错在则返回null
		Person p1 = em.find(Person.class, 1);
		assertEquals("lzz", p1.getName());
		
		// 延迟初始化,不会立刻从数据库得到记录,只是得到一个代理对象
		Person p2 = em.getReference(Person.class, 2);
		assertNotNull(p2);
		try {
			// 当我们访问这个代理对象的属性时,才从数据库得到记录,此时必须保证entityManager是开着的,否则出现延迟加载例外。
			// 此时若访问时,不存在该实体则抛出例外EntityNotFoundException
			assertNull(p2.getName());
		} catch(Exception e) {
			assertEquals(EntityNotFoundException.class, e.getClass());
		}
		
		Person p3 = em.getReference(Person.class, 1);
		assertEquals("lzz", p3.getName());
	}

	public void test_update() {
		em.getTransaction().begin();
		Person p = em.find(Person.class, 1);
		p.setName("new");
		em.getTransaction().commit();
		
		Person np = em.find(Person.class, 1);
		assertEquals("new", np.getName());
	}

	public void test_delete() {
		em.getTransaction().begin();
		Person p = em.find(Person.class, 1);
		em.remove(p);
		em.getTransaction().commit();
		
		Person dp = em.find(Person.class, 1);
		assertNull(dp);
	}

	@After
	public void afterTest() {
		em.close();
	}
	
	@AfterClass
	public static void tearDownAfterClass() {
		fac.close();
	}
}
 

 

分享到:
评论
1 楼 lovethisworld 2010-07-29  
junit 4 是怎样设置测试方法的测试顺序的?

相关推荐

Global site tag (gtag.js) - Google Analytics