JPA是Java Persistence API的简称,中文名Java持久层API,在ORM框架中,我们一直需要自己编写很多配置文件,例如在Hibernate中,每一个持久化类都对应一个映射文件,这样导致程序员编写任务过于繁重,而JPA能够使用简洁的注解来代替映射文件,这减少了代码编写量,同时由于市面上有很多ORM框架,我们不可能每种框架都学习一遍,而JPA就是一种规范,大多数ORM框架都遵循了JPA的规范,这样我们只要学习JPA和ORM框架基本知识就可以使用大多数的ORM框架了。
在原有的ORM框架需要的jar包的基础上再加入jar的包,以hibernate为例,在hibernate的解压缩包中的lib/jpa目录底下就有jpa需要的jar包。
在JPA中,大部分配置文件都可以使用注解来代替,但是核心配置文件还是需要自己编写,这个配置文件类似于hibernate的hibernate.cfg.xml,只不过JPA的核心配置文件名必须为persistence.xml,同时必须放在工程的src/META-INF目录底下。
核心配置文件代码示例 <?xml version="1.0" encoding="UTF-8"?> <!-- 在JPA中,不再使用hibernate。cfg。xml这个配置文件,而是用一个名为persistence。xml的配置文件,注意这个文件要放在src/META-INF目录底下 --> <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为必选,值可以随意 在persistence.xml中可以配置多个persistence-unit来匹配不同的数据库 --> <persistence-unit name="mysql"> <!-- properties参数集合 --> <properties> <!-- 开始定义参数,在这里的参数与hibernate.cfg.xml中的参数一样,只不过参数的值要放在value这个属性之中 --> <!-- 定义数据库的连接驱动 --> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <!-- 定义数据库的连接地址 --> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/hibernate"/> <!-- 定义数据库连接的用户名 --> <property name="hibernate.connection.username" value="root"/> <!-- 定义数据库的连接密码 --> <property name="hibernate.connection.password" value="123456"/> <!-- 定义使用的数据库方言 --> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <!-- 定义使用的数据库连接池 --> <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/> <!-- 定义是否显示SQL语句 --> <property name="hibernate.show_sql" value="true"/> <!-- 定义是否格式化SQL语句 --> <property name="hibernate.format_sql" value="true"/> <!-- 定义数据库表的定义方式 --> <property name="hibernate.hbm2ddl.auto" value="update"/> <!-- 定义使用线程来存储session,currentSession,事务相关 --> <property name="hibernate.current_session_context_class" value="thread"/> </properties> </persistence-unit> </persistence>在JPA中,因为没有了像Hibernate一样的对象映射文件,为了能够将持久化类于数据库的表相映射,这里就是通过在实体类中添加注解,让其变成一个持久化类。
实体类的代码示例 package com.wzm.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; /* * 在JPA中,使用注解代替了映射配置文件 * Entity表明这是一个持久化类 * Table表明这个类所对应的表,name为数据库的表名 */ @Entity @Table(name="user") public class User { /* * Id表明这是持久化类的OID * Column表明该属性所对应的表字段,name为表字段名, * 属性:length定义字段的长度,nullable定义字段是否可以为空,unique定义字段值是否唯一,这几个是在自动创表的时候使用 * @GeneratedValue:定义OID的自增长方式 * IDENTITY对应hibernate中的identity,适应数值的自增长 * SEQUENCE对应hibernate中的sequence,适应序列的自增长,要求数据库支持序列 * AUTO:要求程序自己来定义增长方式 */ @Id @Column(name="uid",length=20) @GeneratedValue(strategy=GenerationType.IDENTITY) private Long uid; @Column(name="uname",length=25) private String uname; @Column(name="age",length=10) private Integer age; //省略getter和setter } JPA的基本操作 @Test public void test1() { //创建一个实体管理工厂,EntityManagerFactory类似于SessionFactory, //传入的参数要与persistence.xml中的persistence-unit的name属性一致 //类似于加载配置文件 EntityManagerFactory emf = Persistence.createEntityManagerFactory("mysql"); //获取实体管理对象,类似hibernate的session对象 EntityManager em = emf.createEntityManager(); //获取事务对象,在JPA中同样也要启用事务 EntityTransaction transaction = em.getTransaction(); //开启事务 transaction.begin(); //创建一个User对象 User user = new User(); user.setUname("xiaoming"); user.setAge(18); //保存对象,persist类似于hibernate的save em.persist(user); //获取对象,find类似于hibernate的get,同样都是立即查询 User user2 = em.find(User.class, 1L); System.out.println(user2); //更新对象,在JPA中同样有缓存机制,因此这里就算不用merge,事务一提交也会保存 user2.setAge(20); //类似hibernate的update em.merge(user2); //getReference类似hibernate的load,同样是延迟加载,只有使用到才去查询 User user3 = em.getReference(User.class, 1L); System.out.println(user3); //删除对象,类似hibernate的delete em.remove(user3); //提交事务 transaction.commit(); //关闭资源 em.close(); emf.close(); } JPA的查询操作 @Test public void test2() { //创建一个实体管理工厂,EntityManagerFactory类似于SessionFactory, //传入的参数要与persistence.xml中的persistence-unit的name属性一致 //类似于加载配置文件 EntityManagerFactory emf = Persistence.createEntityManagerFactory("mysql"); //获取实体管理对象,类似hibernate的session对象 EntityManager em = emf.createEntityManager(); //获取事务对象,在JPA中同样也要启用事务 EntityTransaction transaction = em.getTransaction(); //开启事务 transaction.begin(); /* * 在JPA中也有一套查询的API,查询操作与语句与hibernate的查询很类似,只有几点区别 */ //全查操作,使用createQuery创建query对象,注意与hibernate的query区别开 Query query = em.createQuery("from User"); //第一点区别,在hibernate中的到list集合是用list(),在JPA中是用getResultList() List<User> list = query.getResultList(); //遍历得到每一条记录 for (User user : list) { System.out.println(user); } //条件查询,第二点区别,在JPA中同样支持占位符,但是注意占位符是从1开始算,在hibernate中是从0开始算 Query query2 = em.createQuery("from User where age=?"); //添加条件参数值,注意从1开始 query2.setParameter(1, 20); List<User> list2 = query2.getResultList(); //遍历得到每一条记录 for (User user : list2) { System.out.println(user); } //聚合查询,第三点区别,在hibernate中是用uniqueResult()来接返回值,在JPA中使用getSingleResult()接返回值 Query query3 = em.createQuery("select count(*) from User"); //注意使用getSingleResult() Object result = query3.getSingleResult(); //输出查询结果 System.out.println(result); //提交事务 transaction.commit(); //关闭资源 em.close(); emf.close(); }