关于JPA的初步了解及使用方法
文章目录
前言
随着时间的推移市面上涌现了越来越多的ORM框架,那么作为java的官方势必要开始一些动作,于是oracle引入新的JPA ORM规范出于两个原因:
- 其一,简化现有Java EE和Java SE应用开发工作;
- 其二,oracle希望整合ORM技术,实现天下归一
一、认识JPA
1.JPA是什么?
全称Java Persistence API,通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中
简而言之:用于对象持久化的 API,使得应用程序以统一的方式访问持久层
2.那么JPA 与 Hibernate究竟是什么关系呢
JPA 是一种 ORM 规范,而HIbernate是JPA的一种实现,mybtais也是JPA的一种实现
友情提示:我们可以类比的理解为JDBC技术和JDBC驱动的关系或者类比的理解为
3.JPA我们主要学习点什么呢?
JPA 包括三个方面的技术:
- ORM 映射元数据,支持 XML 和 JDK 注解两种元数据的形式
- JPA 的 API
- 查询语言:JPQL
备注:JPA和HIbernate是同一个人写的
二、JPA的基本使用
1、JPA的常用的几个注解
-
@Entity :修饰实体类,指明该类将映射到指定的数据表,例如:Customer 类默认的数据表名为 customer
-
@Table :当实体类与映射的数据库表名不同名时需要使用 @Table 注解,该注解与 @Entity 注解并列使用,使用其 name 属性指明数据库的表名
-
@Id :标识该属性为主键,一般标注在该属性的 getter 方法上
-
@GeneratedValue :标注主键的生成策略,通过其 strategy 属性。通常与 @Id 注解一起使用。默认情况下 JPA 会自动选择一个最适合底层数据库的主键生成策略,MySQL 默认为 AUTO,常用策略有:
4.1 IDENTITY:采用数据库 ID自增长的方式来自增主键字段,Oracle 不支持这种方式;
4.2 AUTO: JPA自动选择合适的策略,是默认选项;
4.3 SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySql 不支持这种方式
4.4 TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植 -
@Column :当实体的属性与其映射的数据表的列不同名时使用,一般用于 getter 方法上。其 name 属性用来指明此属性在数据表中对应的列名;unique 属性指明是否为唯一约束;nullable 属性用来指明是否可以为空,false 为不能为空;length 属性指明此列的长度。
2、创建一个JPA项目
项目源码地址:JPA_001文件下载地址
2.1用到的jar包
2.2项目
2.1配置persistence.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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">
<!--
persistence-unit:负责将固定数量的一组类映射到数据库中
name:该属性是必须填写的,其定义了持久化单元的名字
transaction-type:该属性指定了事务管理的类型:其值有两种情况
1)RESOURCE_LOCAL:本地事务管理,其实就是数据库级别的事务,
只能针对一种数据库,不支持分布式的事务,
且经常应用用中小型项目中
2)JTA:分布式事务,是容器级别的事务(一般不怎么用)
-->
<persistence-unit name="JPA_001" transaction-type="RESOURCE_LOCAL">
<!-- 1.使用什么 ORM 产品作为 JPA 的实现 -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- 2.添加持久化类 -->
<class>pro.yf.bj.entity.User</class>
<properties>
<!-- 3.设置连库四要素 -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/testjpa?useUnicode=true&characterEncoding=utf-8"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<!-- 5.配置JPA实现产品的基本属性:配置Hibernate的基本属性 -->
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
2.2 实体类user文件
@Table(name="user")//当实体类与映射的数据库表名不同名时需要使用 @Table 注解,该注解与 @Entity 注解并列使用,使用其 name 属性指明数据库的表名
@Entity//修饰实体类,指明该类将映射到指定的数据表
public class User {
private Integer id;
private String name;
/**
* @GeneratedValue :标注主键的生成策略,通过其 strategy 属性。通常与 @Id 注解一起使用。默认情况下 JPA 会自动选择一个最适合底层数据库的主键生成策略,MySQL 默认为 AUTO,常用策略有:
–IDENTITY:采用数据库 ID自增长的方式来自增主键字段,Oracle 不支持这种方式;
–AUTO: JPA自动选择合适的策略,是默认选项;
–SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySql 不支持这种方式
–TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植
*/
@GeneratedValue(strategy=GenerationType.AUTO)//标注主键的生成策略,通过其 strategy 属性
@Id//标识该属性为主键,一般标注在该属性的 getter 方法上
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="name" ,length=64, nullable=false)//当实体的属性与其映射的数据表的列不同名时使用
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.3 JPA:测试持久化操作:test01.java
public class Test01 {
public static void main(String[] args) {
//1.创建实体管理器工厂
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("JPA_001");
//2.创建实体管理器
EntityManager entityManager = entityManagerFactory.createEntityManager();
//3.获取事务
EntityTransaction transaction = entityManager.getTransaction();
//4.开启事务
transaction.begin();
//5.创建一个带有数据的实体类对象
User user = new User();
//user.setId(64);
user.setName("程咬金");
//6.保存实体:类似于HIbernate中的save()方法,但是也有不同的地方,就是在数据库主键自增情况下:若提前设置id属性值,JPA EntityManager 的 persist方法将抛出异常,而Hibernate Session的 save 方法可以执行,将忽略提前设置的id值
entityManager.persist(user);
//7.提交事务
transaction.commit();
//8.关闭JPA的相关对象
entityManager.close();
entityManagerFactory.close();
}
}
3、JPA的注解
关于JPA注解的示例,jar包和persistence.xml文件同上
项目源码地址:JPA_002文件下载地址
实体类
/**
* @Entity 用于注明该类是一个实体类
* @Table(name="t_customer") 表明该实体类映射到数据库的 t_customer 表
*/
@Table(name = "t_customer")
@Entity
public class Customer {
private Integer id;
private String name;
private String email;
private Integer age;
private Date birthday;
private Date createdTime;
private String info;
/**
* @GeneratedValue(strategy=GenerationType.AUTO) 指明主键生成策略为AUTO
* @Id 表明实体类的主键
*/
@GeneratedValue(strategy=GenerationType.AUTO)
@Id
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
/**
* @Column 指明lastName属性映射到表的 LAST_NAME 列中
* 同时还可以指定其长度、能否为null等数据限定条件
*/
@Column(name="LAST_NAME" ,length=50, nullable=false)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
/*
* 通过 @Column 的 columnDefinition 属性将email列
* 映射为“TEXT”类型
*/
@Column(columnDefinition="text")
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
/**
* 利用 @Temporal 来限定birthday为DATE型
*/
@Column(name="birthday")
@Temporal(TemporalType.DATE)
public Date getBirthday() { return birthday; }
public void setBirthday(Date birthday) { this.birthday = birthday; }
/*
* 通过 @Column 的 columnDefinition 属性将CREATED_TIME列
* 映射为“DATE”类型
*/
@Column(name="CREATED_TIME" ,columnDefinition="DATE")
public Date getCreatedTime() { return createdTime; }
public void setCreatedTime(Date createdTime) { this.createdTime = createdTime; }
//工具方法,不需要映射为数据表的一列
@Transient
public String getInfo(){
System.out.println("Transient:工具方法,不需要映射为数据表的一列");
return "123";
}
public void setInfo(String info) { this.info = info; }
}
测试类
public class Test {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("JPA_002");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Customer ctr=new Customer();
ctr.setBirthday(new Date());
ctr.setAge(19);
ctr.setEmail("3657920@qq.com");
ctr.setName("紫菱");
ctr.setCreatedTime(new Date());
entityManager.persist(ctr);
transaction.commit();
entityManager.close();
entityManagerFactory.close();
}
}