SpringData-JPA

在講解JPA以前先將hibernate和JPA簡單的瞭解一下.java

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(); } } }
相關文章
相關標籤/搜索