SpringData-JPA

在讲解JPA之前先将hibernate和JPA简单的了解一下.

Hibernate概述:

  Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的ORM框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象变成思维来操作数据库.

JPA概述:

  JPA全称为Java Persistence API,即Java持久化Api,是sun公司推出的一套基于ORM的规范,内部是由一系列的接口和抽象类构成.

  JPA通过JDK5.0注解描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.

JPA的优势:

1.标注化

  JPA是JCP组织发布的JavaEE 标准之一,因此任何声称符合JPA标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行.

2.容器级特性的支持.

  JPA框架中支持大数据集.事务.并发等容器级事务,这使得JPA超越了见到持久化框架的局限,在企业应用发挥更大的作用.

3.简单方便

  JPA的主要目标之一就是提供更加简单的变成模型:在JPA框架下创建实体和创建Java类一样简单.没有任何的约束和限制,只需要使用javax,persistence.Entity进行注释,JPA的框架和接口也都非常简单.没有太多特别的规则和设计模式的要求,开发者可以很容易的掌握.JPA 基于非侵入式原则设计.因此可以分容易和其他框架或者容器集成.

4.查询能力

  JPA的查询语言是面向对象而非面向数据库的.它以面向对象的自然语法构造查询语句,可以看成是Hibernate HQL的等价物,JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJBQL的一种拓展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改,JOIN GROUP BY ,HAVING等通常只有SQL才能够提供的高级查询特性,甚至还能够支持子查询.

5.高级特性

  JPA中能够支持面向对象的高级特性,如类之间的继承.多态和类之间的复杂关系,这样能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化.

JPA与hibernate的关系?

JPA规范本质上就是一种ORM规范,注意不是ORM框架---因为JPA并未提供ORM实现,它只是制定了一些规范,提供了一些编程的API接口,但具体实现则由服务厂商来提供实现.

JPA和Hibernate的关系就像JDBC和JDBC驱动的关系,JPA是规范,Hibernate除了作为ORM框架之外,它也是一种JPA实现,JPA怎么取代Hibernate呢?JDBC规范可以驱动底层数据库么?答案是否定的,也就是所,如果使用JPA规范进行数据库操作,底层需要hibernate作为其实现类完成数据持久化工作.

简单的入门案例:

  因为JPA是sun公司制定的API规范,所以我并没有使用额外的JPA相关的Jar包,只需要导入JPA的提供商的jar包,我们选择Hibernate作为JPA的提供商,所以需要导入Hibernate的相关jar包.

可以在

    http://sourceforge.net/projects/hibernate/files/hibernate-orm/5.0.7.Final/

这里进行下载.

JPA中的主键生成策略

  通过annotation(注解)来映射hibernate实体的,基于annotation的hibernate主键标识为@Id,其生成规则由@GeneratedValue设定的,这里的@Id和@GeneratedValue都是JPA的标准用法.

  JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO

  具体说名如下:

  IDENTITY:主键由数据库自动生成(主要是自动增长型)

  用法:

  

@Id
@GeneratedValue(startegy=GenerationType.IDENTITY)
private Long custId;

SQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列.

用法:一般情况为Oracle数据库

@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="payablemoney_seq")
@SequenceGenerator(name="payablemoney_seq",sequenceName="seq_payment")
private Long custId;
//@SequenceGenerator源码中的定义
@Target({TYPE,METHOD,FIELD})
@Retention(RUNTIME)
public @interface SequenceGenerator{
//表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的"generator"值中
String name();
//属性表示生成策略用到的数据库序列名称
String sequenceName() default "";
//表示主键初始值,默认为0
int initialValue() default 0;
//表示每次主键值增加的大小,例如设置1,则表示每次插入新纪录后自动加1,默认为50
int allocationSize() default 50;
}

 

AUTO:主键由程序控制

用法:

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long custId;

TABLE:使用一个特定的数据库表格来保存主键

用法:

    @Id  
    @GeneratedValue(strategy = GenerationType.TABLE, generator="payablemoney_gen")  
    @TableGenerator(name = "pk_gen",  
        table="tb_generator",  
        pkColumnName="gen_name",  
        valueColumnName="gen_value",  
        pkColumnValue="PAYABLEMOENY_PK",  
        allocationSize=1  
    ) 
private Long custId;


//@TableGenerator的定义:
    @Target({TYPE, METHOD, FIELD})   
    @Retention(RUNTIME)  
    public @interface TableGenerator {  
      //表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中
      String name();  
      //表示表生成策略所持久化的表名,例如,这里表使用的是数据库中的“tb_generator”。
      String table() default "";  
      //catalog和schema具体指定表所在的目录名或是数据库名
      String catalog() default "";  
      String schema() default "";  
      //属性的值表示在持久化表中,该主键生成策略所对应键值的名称。例如在“tb_generator”中将“gen_name”作为主键的键值
      String pkColumnName() default "";  
      //属性的值表示在持久化表中,该主键当前所生成的值,它的值将会随着每次创建累加。例如,在“tb_generator”中将“gen_value”作为主键的值 
      String valueColumnName() default "";  
      //属性的值表示在持久化表中,该生成策略所对应的主键。例如在“tb_generator”表中,将“gen_name”的值为“CUSTOMER_PK”。 
      String pkColumnValue() default "";  
      //表示主键初识值,默认为0。 
      int initialValue() default 0;  
      //表示每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50。
      int allocationSize() default 50;  
      UniqueConstraint[] uniqueConstraints() default {};  
    } 

    //这里应用表tb_generator,定义为 :
    CREATE TABLE  tb_generator (  
      id NUMBER NOT NULL,  
      gen_name VARCHAR2(255) NOT NULL,  
      gen_value NUMBER NOT NULL,  
      PRIMARY KEY(id)  
    )

JPA的API介绍

Persistence对象

Persistence对象主要作用是用于获取EntityManagerFactory对象的.通过调用该类的createEntityManagerFactory静态方法,根据配置文件中持久化单元名称创建EntityManagerFactory.

//1. 创建 EntitymanagerFactory
@Test
String unitName = "myJpa";
EntityManagerFactory factory= Persistence.createEntityManagerFactory(unitName);

EntityManagerFactory

EntityManagerFacotry接口主要用来创建EntityManager实例:

//创建实体管理类
EntityManager em = factory.createEntityManager();

由于EntityManagerFactory是一个线程安全的对象(即多个线程访问同一个EntityManagerFactory对象不会有线程问题),并且EntityManagerFactory的创建极其浪费资源,所以在使用JPA编程时,我们可以对EntityManagerFactory的创建进行优化,只需要做到一个工程只存在一个EntityMmanagerFactory即可/

EntityManger

在JPA规范中,EntityMmanager是完成持久化操作的核心对象,实体类作为普通java对象,只有在调用EntityManager将其持久化后才会变成持久化对象.EntityMmanager对象在一组实体类与底层数据源之间进行O/R映射的管理.它可以用来管理和更新EntityBean,根据主键查找EntityBean,还可以通过JPQL语句查询实体.

我们可以通过调用EntityManager的方法完成获取事务,以及持久化数据库的操作.

  方法说明:

    getTransaction : 获取事务对象
    persist : 保存操作
    merge : 更新操作
    remove : 删除操作
    find/getReference : 根据id查询

EntityTransaction

在JPA规范中,EntityTraction是完成事务操作的核心对象,对于EntityTraction在我们的java代码中承接的功能比较简单

begin:开启事务
commit:提交事务
rollback:回滚事务

抽取JPAUtils工具类

package cn.itcast.dao;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public final class JPAUtil {
    // JPA的实体管理器工厂:相当于Hibernate的SessionFactory
    private static EntityManagerFactory em;
    // 使用静态代码块赋值
    static {
        // 注意:该方法参数必须和persistence.xml中persistence-unit标签name属性取值一致
        em = Persistence.createEntityManagerFactory("myPersistUnit");
    }

    /**
     * 使用管理器工厂生产一个管理器对象
     * 
     * @return
     */
    public static EntityManager getEntityManager() {
        return em.createEntityManager();
    }
}

简单的增删改查和复杂查询:

package com.qingmu;

import org.hibernate.dialect.CUBRIDDialect;
import org.junit.Test;
import org.junit.experimental.theories.suppliers.TestedOn;

import javax.persistence.*;
import java.util.List;

/**
 * @Auther:qingmu
 * @Description:脚踏实地,只为出人头地
 * @Date:Created in 16:12 2019/5/14
 */
public class SpringDataJPATest02 {
    private EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa");

    /**
     * 增加
     */
    @Test
    public void saveCustomer() {
        Customer customer = new Customer();
        /**
         * 如果设置了主键自增长,然后再设置id,就会出现异常:
         * PersistentObjectException: detached entity passed to persist: com.qingmu.Customer
         */
//        customer.setCustId(3L);
        customer.setCustName("青木堂");
        customer.setCustAddress("北京市昌平区");
        customer.setCustIndustry("教育");
        customer.setCustLevel("VIP");
        customer.setCustPhone("12345678912");
        customer.setCustSource("网络");
        EntityManager entityManager = null;
        //创建事务
        EntityTransaction transaction = null;
        try {
            //获取实体类管理对象
            entityManager = entityManagerFactory.createEntityManager();
            transaction = entityManager.getTransaction();
            //开始事务
            transaction.begin();
            //创建一个pojo对象

            //保存
            entityManager.persist(customer);
            //提交
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();

        } finally {
            //关闭资源
            entityManager.close();
            entityManagerFactory.close();
        }
    }

    /**
     * 更新
     */
    @Test
    public void update() {

        EntityManager entityManager = null;
        EntityTransaction transaction = null;
        try {
            entityManager = entityManagerFactory.createEntityManager();
            transaction = entityManager.getTransaction();
            transaction.begin();
            Customer customer = entityManager.find(Customer.class, 2L);
            customer.setCustName("qingmutang");
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        } finally {
            entityManager.close();
            entityManagerFactory.close();
        }
    }

    /**
     * 删除
     */
    @Test
    public void testRemove() {
        EntityManager entityManager = null;
        EntityTransaction transaction = null;
        try {
            entityManager = entityManagerFactory.createEntityManager();
            transaction = entityManager.getTransaction();
            transaction.begin();
            Customer customer = entityManager.find(Customer.class, 3L);
            entityManager.remove(customer);
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        } finally {
            entityManager.close();
        }
    }

    /**
     * 根据id查询,立即加载
     */
    @Test
    public void findById() {
        EntityManager entityManager = null;
        EntityTransaction transaction = null;
        try {
            entityManager = entityManagerFactory.createEntityManager();
            transaction = entityManager.getTransaction();
            transaction.begin();
            Customer customer = entityManager.find(Customer.class, 2L);
            System.out.println(customer);
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        } finally {
            entityManager.close();
        }
    }

    /**
     * 根据id查询,延迟加载
     */
    @Test
    public void findById2() {
        EntityManager entityManager = null;
        EntityTransaction transaction = null;
        try {
            entityManager = entityManagerFactory.createEntityManager();
            transaction = entityManager.getTransaction();
            transaction.begin();
            Customer reference = entityManager.getReference(Customer.class, 2L);
            System.out.println(reference);
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        } finally {
            entityManager.close();
        }
    }

    /**
     * 查询全部
     */
    @Test
    public void findAll() {
        EntityManager entityManager = null;
        EntityTransaction transaction = null;
        try {
            entityManager = entityManagerFactory.createEntityManager();
            transaction = entityManager.getTransaction();
            transaction.begin();
            String jpql = "from Customer";
            Query query = entityManager.createQuery(jpql);
            List resultList = query.getResultList();
            for (Object o : resultList) {
                System.out.println(o);
            }
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        } finally {
            entityManager.close();
        }
    }

    /**
     * 分页查询
     */
    @Test
    public void limit() {
        EntityManager entityManager = null;
        EntityTransaction transaction = null;
        try {
            entityManager = entityManagerFactory.createEntityManager();
            transaction = entityManager.getTransaction();
            transaction.begin();
            String jpql = "from Customer";
            Query query = entityManager.createQuery(jpql);
            query.setFirstResult(0);
            query.setMaxResults(2);
            List resultList = query.getResultList();
            for (Object o : resultList) {
                System.out.println(o);
            }
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        } finally {
            entityManager.close();
        }
    }
/**
*通过条件查询
*/ @Test
public void ByQuery() { EntityManager entityManager = null; EntityTransaction transaction = null; try { entityManager = entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); String jpql = "from Customer where custName like ?"; Query query = entityManager.createQuery(jpql); query.setParameter(1, "%青木%"); List resultList = query.getResultList(); for (Object o : resultList) { System.out.println(o); } transaction.commit(); } catch (Exception e) { e.printStackTrace(); transaction.rollback(); } finally { entityManager.close(); } } /**
*分类查询
*/ @Test
public void sortBy(){ EntityManager entityManager = null; EntityTransaction transaction = null; try { entityManager = entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); String jpql = "from Customer order by custId desc"; Query query = entityManager.createQuery(jpql); List resultList = query.getResultList(); for (Object o : resultList) { System.out.println(o); } transaction.commit(); } catch (Exception e) { e.printStackTrace(); transaction.rollback(); }finally { entityManager.close(); } } /** * 统计查询 */ @Test public void count(){ EntityManager entityManager = null; EntityTransaction transaction = null; try { entityManager = entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); String jpql = "select count(custId) from Customer"; Query query = entityManager.createQuery(jpql); List resultList = query.getResultList(); for (Object o : resultList) { System.out.println(o); } transaction.commit(); } catch (Exception e) { e.printStackTrace(); transaction.rollback(); }finally { entityManager.close(); } } }

 

posted @ 2019-05-14 21:24  King-DA  阅读(185)  评论(0编辑  收藏  举报