一:什么是JPA
JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合ORM技术。结束现在hibernate、topLink、JDO、等ORM框架各自为营的局面。
JPA是在充分吸收了现有hibernate、TopLink,JDO等ORM框架的基础上发展而来的。
JPA是一套规范,不是产品。
二:JPA包括以下三个方面技术
1. ORM映射元数据
JPA支持XML和JDK5.0注释。
2.Java持久化API
用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者可以从繁琐的JDBC和SQL代码中解脱出来。
3. 查询语言
这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
三:JPA依赖的jar包
Hibernate-distribution-3.3.1.GA:
hibernate3.jar、hibernate-cglib-repack-2.1_3.jar、antlr-2.7.6.jar、commons-collections-3.1.jar、dom4j-1.6.1.jar、javassist-3.4.GA.jar、jta-1.1.jar、slf4j-api-1.5.2.jar
Hibernate-annotations-3.4.0.GA:
hibernate-annotations.jar、ejb3-persistence.jar、hibernate-commons-annotations.jar
Hibernate-entitymanager-3.4.0.GA:
Hibernate-entitymanager.jar、log4j.jar、slf4j-log4j12.jar
四:JPA的配置文件
JPA规范要求在类路径的META-INF目录下放置persistence.xml,文件名称是固定的。
注意:这个META-INF不是WebRoot目录下的,而是在src下面创建这个META-INF。
persistence.xml
<?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_1_0.xsd" version="1.0"> <persistence-unit name="itcast" 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.username" value="root" /> <property name=" hibernate.connection.password" value="wdpc" /> <property name=" hibernate.connection.url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8" /> <property name="hibernate.max_fetch_depth" value="3" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.jdbc.fetch_size" value="18" /> <property name="hibernate.jdbc.batch_size" value="10" /> <property name="hibernate.show_sql" value="false" /> <property name="hibernate.format_sql" value="false" /> </properties> </persistence-unit> </persistence>
先建表,后再根据表来编写配置文件和实体bean,使用这种方案的开发人员受到了传统数据库建模的影响。
先编写配置文件和实体bean,然后再生成表,使用这种方案的开发人员采用的是领域建模思想,这种思想相对前一种思想更加oop(面向对象).
五:数据库表是与实体同名的,也是类名
数据库的字段是根据类属性同名的。
Person.java
package cn.wdpc.bean; import java.util.Date; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.Persistence; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient; @Entity //标注了这个类是实体bean,默认的实体名称就是Person //@Table 将数据库表名为xxx @Table(name="xxx") public class Person { private Integer id; private String name; private Date birthday; //生日 private Gender gender = Gender.MAN; //默认为男 private String info; //信息 private Byte[] file; //字节数组文件 private String imagepath; //因为这个对象是由hibernate内部反射技术创建的,需要默认构造 public Person() { super(); } public Person(String name) { this.name = name; } //@Id 实体标示 ,可以标在字段上,也可以标在属性get方法上 @Id @GeneratedValue //(strategy=GenerationType.AUTO) public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } //length数据库表字段长度为10 //nullabel 表示数据库字段不能为空 //name 表示将数据库name字段改为username @Column(length=10,nullable=false,name="username") public String getName() { return name; } public void setName(String name) { this.name = name; } //@Temporal 存放时间格式 @Temporal(TemporalType.DATE) public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } //@Enumerated枚举类型 @Enumerated(EnumType.STRING) @Column(length=5,nullable=false) public Gender getGender() { return gender; } public void setGender(Gender gender) { this.gender = gender; } //@Lob 用来声明属性为大文本类型 @Lob public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } @Lob //用来存储二进制文件 @Basic(fetch=FetchType.LAZY) //是否延迟初始化,一般用在大数据上 1BM以上 public Byte[] getFile() { return file; } public void setFile(Byte[] file) { this.file = file; } //@Transient数据库表字段中不会有这属性 @Transient public String getImagepath() { return imagepath; } public void setImagepath(String imagepath) { this.imagepath = imagepath; } public static void main(String[] args) { EntityManagerFactory factory = Persistence.createEntityManagerFactory("wdpc"); EntityManager em = factory.createEntityManager(); em.getTransaction().begin(); em.persist(new Person("张三")); em.getTransaction().commit(); em.close(); factory.close(); } }
创建枚举Gender.java
package cn.wdpc.bean; public enum Gender { MAN,WOMEN }
测试类PersonTest.java
package com.wdpc.junit.test; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.junit.BeforeClass; import org.junit.Test; import cn.wdpc.bean.Person; public class PersonTest { @BeforeClass public static void setUpBeforeClass() throws Exception { } //创建数据库,并插入数据 @Test public void save(){ //相当于sessionFactory //createEntityManagerFactory 创建持久化单元的名称,要和xml文件里persistence-unit name="wdpc"对应 EntityManagerFactory factory = Persistence.createEntityManagerFactory("wdpc"); //相当于session EntityManager em = factory.createEntityManager(); //事务的开始begin(); em.getTransaction().begin(); //持久化方法==事务session.save() em.persist(new Person("张三")); em.getTransaction().commit(); em.close(); factory.close(); } //从数据库里获取数据 @Test public void getPerson(){ EntityManagerFactory factory = Persistence.createEntityManagerFactory("wdpc"); EntityManager em = factory.createEntityManager(); //读取数据库的数据不需要开启事务 Person person = em.find(Person.class, 1);//如果将1改为2,打印出null System.out.println(person.getName()); em.close(); factory.close(); } //从数据库里获取数据 @Test public void getPerson2(){ EntityManagerFactory factory = Persistence.createEntityManagerFactory("wdpc"); EntityManager em = factory.createEntityManager(); //读取数据库的数据不需要开启事务 Person person = em.getReference(Person.class, 1);//如果将1改为2,抛异常 System.out.println(person.getName()); em.close(); factory.close(); } //数据跟新,数据插入和数据跟新需要用到事务 //new //managed 托管 //游离(脱管) //删除 @Test public void updatePerson(){ EntityManagerFactory factory = Persistence.createEntityManagerFactory("wdpc"); EntityManager em = factory.createEntityManager(); em.getTransaction().begin(); Person person = em.find(Person.class, 1); person.setName("李四"); em.getTransaction().commit(); em.close(); factory.close(); } @Test public void updatePerson2(){ EntityManagerFactory factory = Persistence.createEntityManagerFactory("wdpc"); EntityManager em = factory.createEntityManager(); em.getTransaction().begin(); Person person = em.find(Person.class, 1); em.clear();//把实体管理器中的所有实体变成游离状态 person.setName("王五"); em.merge(person); //用于把游离状态实体同步到数据库 em.getTransaction().commit(); em.close(); factory.close(); } @Test public void deletePerson(){ EntityManagerFactory factory = Persistence.createEntityManagerFactory("wdpc"); EntityManager em = factory.createEntityManager(); em.getTransaction().begin(); Person person = em.find(Person.class, 1); em.remove(person); em.getTransaction().commit(); em.close(); factory.close(); } } //查询语句 @Test public void query(){ EntityManagerFactory factory = Persistence.createEntityManagerFactory("wdpc"); EntityManager em = factory.createEntityManager(); Query query= em.createQuery("select o from Person o where o.id=?"); query.setParameter(1, 2); Person person =(Person)query.getSingleResult(); System.out.println(person.getName()); em.close(); factory.close(); } //跟新查询 @Test public void queryupdate(){ EntityManagerFactory factory = Persistence.createEntityManagerFactory("wdpc"); EntityManager em = factory.createEntityManager(); em.getTransaction().begin(); Query query= em.createQuery("update Person o set o.name=:name where o.id=:id"); query.setParameter("name", "xxx"); query.setParameter("id", 4); query.executeUpdate(); em.getTransaction().commit(); em.close(); factory.close(); }
创建配置文件persistence.xml
在src下创建META-INF,将persistence.xml配置文件放入里面
<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"> <!-- 持久化单元,实体bean --> <!-- transaction-type:有 JTA全局事务;RESOURCE_LOCAL本地事务--> <persistence-unit name="wdpc" transaction-type="RESOURCE_LOCAL"> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> <property name="hibernate.connection.username" value="root" /> <property name="hibernate.connection.password" value="admin" /> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8" /> <property name="hibernate.jdbc.fetch_size" value="18" /> <property name="hibernate.jdbc.batch_size" value="10" /> <property name="hibernate.show_sql" value="false" /> <property name="hibernate.format_sql" value="false" /> </properties> </persistence-unit> </persistence>
Jar包:hibernate-cglib-repack-2.1_3.jar,commons-collections-3.1.jar,dom4j-1.6.1.jar,javassist-3.4.GA.jar,jta-1.1.jar,slf4j-api-1.5.2.jar,antlr-2.7.6.jar,hibernate-annotations.jar,hibernate-commons-annotations.jar,ejb3-persistence.jar,hibernate-entitymanager.jar,slf4j-log4j12.jar,log4j.jar,ehcache-1.2.3.jar,hibernate3.jar,commons-logging.jar,cglib-2.1.3.jar,cglib-nodep-2.1_3.jar,asm.jar,asm-attrs.jar,asm-commons-2.2.3.jar,asm-util-2.2.3.jar,spring.jar,commons-dbcp.jar