天天看点

关于JPA的初步了解及使用方法前言一、认识JPA二、JPA的基本使用

关于JPA的初步了解及使用方法

文章目录

  • 前言
  • 一、认识JPA
    • 1.JPA是什么?
    • 2.那么JPA 与 Hibernate究竟是什么关系呢
    • 3.JPA我们主要学习点什么呢?
  • 二、JPA的基本使用
    • 1、JPA的常用的几个注解
    • 2、创建一个JPA项目
      • 2.1用到的jar包
      • 2.2项目
    • 3、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驱动的关系或者类比的理解为

关于JPA的初步了解及使用方法前言一、认识JPA二、JPA的基本使用

3.JPA我们主要学习点什么呢?

JPA 包括三个方面的技术:

  1. ORM 映射元数据,支持 XML 和 JDK 注解两种元数据的形式
  2. JPA 的 API
  3. 查询语言:JPQL

备注:JPA和HIbernate是同一个人写的

二、JPA的基本使用

1、JPA的常用的几个注解

  1. @Entity :修饰实体类,指明该类将映射到指定的数据表,例如:Customer 类默认的数据表名为 customer
  2. @Table :当实体类与映射的数据库表名不同名时需要使用 @Table 注解,该注解与 @Entity 注解并列使用,使用其 name 属性指明数据库的表名
  3. @Id :标识该属性为主键,一般标注在该属性的 getter 方法上
  4. @GeneratedValue :标注主键的生成策略,通过其 strategy 属性。通常与 @Id 注解一起使用。默认情况下 JPA 会自动选择一个最适合底层数据库的主键生成策略,MySQL 默认为 AUTO,常用策略有:

    4.1 IDENTITY:采用数据库 ID自增长的方式来自增主键字段,Oracle 不支持这种方式;

    4.2 AUTO: JPA自动选择合适的策略,是默认选项;

    4.3 SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySql 不支持这种方式

    4.4 TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植

  5. @Column :当实体的属性与其映射的数据表的列不同名时使用,一般用于 getter 方法上。其 name 属性用来指明此属性在数据表中对应的列名;unique 属性指明是否为唯一约束;nullable 属性用来指明是否可以为空,false 为不能为空;length 属性指明此列的长度。

2、创建一个JPA项目

项目源码地址:JPA_001文件下载地址

2.1用到的jar包

关于JPA的初步了解及使用方法前言一、认识JPA二、JPA的基本使用

2.2项目

关于JPA的初步了解及使用方法前言一、认识JPA二、JPA的基本使用

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&amp;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("[email protected]");
        ctr.setName("紫菱");
        ctr.setCreatedTime(new Date());
        entityManager.persist(ctr);
        transaction.commit();
        entityManager.close();
        entityManagerFactory.close();
	}
}