JPA入门

原文发布于:http://www.gufeng.tech/  谷风的我的主页java

    JPA全称Java Persistence API即Java持久化API,是一种经过注解或者XML配置描述映射关系来实现将实体持久化到数据库的一种java持久化实现方案。JPA和JDBC同样,都是jdk提供的API,各厂商提供实现,目前的实现有Apache的OpenJPA以及应用普遍的Hibernate,固然还有其它的实现,这里就不一一列出了。JAP做为一种标准,已经得到了JavaEES容器的支持,同时也仍然能够在JavaSE环境中使用,这就奠基了它可被普遍应用的前提。mysql


    JPA在随着SpringBoot的默认支持,再次被普遍说起、应用。做为一种ORM的技术,除了拥有ORM的特色以外,还有一些它本身的特色:程序员

1 标准化web

JPA是java标准化组织JCP提出的一项持久化标准,因此其任何实现都提供了相同的API,即使更换了实现方案,兼容性也是很是好的。sql

2 更面向对象数据库

JPA支持面向对象中的继承、多态及多个类间的关联关系,所以使得程序员在使用JPA开发时能够方便的使用面向对象的思惟,过渡性比较好。并发

3 功能全面框架

JPA支持事务、并发等特性,而不只仅是一个简单的持久化框架,于是能够在实际使用中发挥更大的做用。ide

4 卓越的查询能力工具

    JPA是面向对象的,定义了JPQL(Java Persistence Query Language),JPQL是一种针对实体的查询语句,操做对象是实体,能够以面向对象的方式构造查询语句,在这点上相似Hibernate的HQL。JPQL可以支持批量操做(如更新和修改)、join、group by、having等子句,同时还支持子查询,所以其查询能力可见一斑。

5 集成方便

    这一点从SpringBoot选择了JPA就可以看出来。在JPA框架下建立实体只须要使用javax.persistence.Entity注解便可,其接口使用也很是简单容易上手,尤为重要的一点是JPA被设计成非***式的,自然注定了它可以被很是容易的集成。


JPA涉及的技术

1 元数据

关于映射关系,JPA同时支持注解和XML。

2 API

操做简单,将程序员从繁琐的SQL中解放出来。

3 查询语言

经过面向对象的方式进行数据查询,避免程序与SQL语句的的耦合。


    上面说起了JPA的各类好处,那么做为一种技术方案(或者叫规范),JPA有没有缺点呢?答案是确定的,JPA将数据库关系以实体及实体间关系表示,必然存在一种将数据库的复杂概念(如一对1、一对多、多对多等关系)转移到程序中。这会带来如下一些问题:

1 程序可读性差,若是遇到特别复杂的业务逻辑,那么对于实体的定义也会很是困难,这须要设计者具备很是高的抽象、规范、设计能力。

2 数据关系发生变化时,实体必然也会发生变化。

3 将关系型数据库映射到面向对象程序上,自己就有着深度的复杂性,二者关注点不一样,当关联到一块儿的时候必然会来带冲突。数据库关心的是数据以及数据的完整性;面向对象关心的是对象的成员及行为。


接下来介绍下JPA的一些核心类:

1 EntityManagerFactory

    EntityManagerFactory 是 EntityManager 的工厂类,负责建立 EntityManager 对象。

2 EntityManager

    EntityManager 是 JPA 应用中使用的基本对象,经过它提供的相应方法能够管理持久化对象,也能够新建或者删除持久化对象。EntityManager 还负责建立 Query 实例。在容器外使用时,EntityManagerFactory 和 EntityManager 之间是一对一的关系。

EntityTransaction

    EntityTransaction 提供 Entity 操做时须要的事务管理,和 EntityManager 是一对一的关系。在查询操做时不须要使用 EntityTransaction,而在对象持久化、状态更新、对象删除等状况下则必须使用显式的使用 EntityTransaction 的相关方法管理事务。

4 Query

    Query 是查询实体的接口,Query 对象能够从 EntityManager 中得到。根据 EJB 3.0 规范中的描述,Query 接口须要同时支持 JPQL 和原生态 SQL 两种语法。

5 Persistence

    Persistence 是一个工具类,负责根据配置文件提供的参数建立 EntityManagerFactory 对象。


最后看一段JPA的示例代码:

import javax.persistence.Column;  
import javax.persistence.Entity;  
import javax.persistence.Id;  
import javax.persistence.Table;  
  
@Entity  
@Table(name = "user")  
public class User {  
    @Id  
    @Column(name = "id")  
    private String id;  
  
    @Column(name = "name")  
    private String name;  
  
    public String getId() {  
        return id;  
    }  
  
    public void setId(String id) {  
        this.id = id;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
   
}
import javax.persistence.EntityManager;  
import javax.persistence.EntityManagerFactory;  
import javax.persistence.Persistence;  
import java.util.List;  
  
public class Main {  
    static EntityManagerFactory emf = Persistence.createEntityManagerFactory("gufengJPA");  
    static EntityManager em = emf.createEntityManager();  
  
    public static void main(String[] args) {  
        User person = new User();   
        person.setId(123456l);  
        person.setName("张无忌");  
        em.persist(person);  
  
        add(person);  
  
        System.out.println("user id:" + person.getId());  
        User user = find(person.getId());  
        System.out.println(user);  
  
        List<User> all = findAll();  
        for (User u : all) {  
            System.out.println(u);  
        }  
  
        em.close();  
        emf.close();  
    }  
   
    public static void add(User user) {  
        em.getTransaction().begin();  
        em.persist(user);  
        em.getTransaction().commit();  
    }  
   
    public static User find(Object id) {  
        User user = em.find(User.class, id);  
        return user;  
    }  
  
    public static List<User> findAll() {  
        List<User> users = em.createQuery("select u from User u")  
                .getResultList();  
        return users;  
    }  
}
<?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="gufengJPA" transaction-type="RESOURCE_LOCAL">  
        <!--能够指定,若是不指定则从META-INF/services加载-->  
        <!--<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>-->  
        <!-- <class>com.micmiu.hibernate.jpa.UserInfo</class> -->  
        <!--<provider>com.tongweb.openjpa.persistence.PersistenceProviderImpl</provider>-->  
        <!--<jta-data-source>MyDataSource</jta-data-source>-->  
        <!-- class 定义指定持久化的实体类 注意配置属性hibernate.archive.autodetection=false -->  
        <!--<class>jpa.User</class>-->  
        <properties>  
            <property name="hibernate.archive.autodetection" value="class,hbm"/>  
  
            <!--Hibernate 方言 -->  
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>  
  
            <!--数据库url -->  
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test"/>  
            <!--数据库驱动 -->  
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>  
            <!--配置数据库用户名 -->  
            <property name="hibernate.connection.username" value="root"/>  
            <!--配置数据库密码 -->  
            <property name="hibernate.connection.password" value="123456"/>  
  
            <!--设置外链接抓取树的最大深度 -->  
            <!--<property name="hibernate.max_fetch_depth" value="3"/>-->  
            <!--自动输出schema建立DDL语句 -->  
            <!--<property name="hibernate.hbm2ddl.auto" value="update"/>-->  
  
            <property name="hibernate.show_sql" value="true"/>  
  
        </properties>  
    </persistence-unit>  
</persistence>

    这里须要注意的是JPA配置文件persistence.xml 必需放到类路径的根路径的META-INF文件夹下。

   

Persistence.createEntityManagerFactory("gufengJPA");

    上面这行代码是经过Java的SPI机制得到具体实现的。在hibernate的jar包里有个META-INF/services/javax.persistence.spi.PersistenceProvider 文件,这里指定的实现为 org.hibernate.jpa.HibernatePersistenceProvider。再有多个的时候,Persistence只会使用第一个。

相关文章
相关标签/搜索