- 注:这是笔者在学习过程的一些知识记录,有可能有些地方写得不对,仅供参考
JPA的简介
JPA是Java Persistence API的简称,中文名Java持久层API,在ORM框架中,我们一直需要自己编写很多配置文件,例如在Hibernate中,每一个持久化类都对应一个映射文件,这样导致程序员编写任务过于繁重,而JPA能够使用简洁的注解来代替映射文件,这减少了代码编写量,同时由于市面上有很多ORM框架,我们不可能每种框架都学习一遍,而JPA就是一种规范,大多数ORM框架都遵循了JPA的规范,这样我们只要学习JPA和ORM框架基本知识就可以使用大多数的ORM框架了。
JPA需要的Jar包
在原有的ORM框架需要的jar包的基础上再加入jar的包,以hibernate为例,在hibernate的解压缩包中的lib/jpa目录底下就有jpa需要的jar包。
JPA的配置文件
- 核心配置文件
在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的基本使用
在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();
}