spring data jpa

Part1

    概覽

orm思想和hibernate以及jpa的概述和jpa的基本操做

第一 orm思想
    主要目的:操做實體類就至關於操做數據庫表
    創建兩個映射關係:
        實體類和表的映射關係
        實體類中屬性和表中字段的映射關係
    再也不重點關注:sql語句
    
    實現了ORM思想的框架:mybatis,hibernate

第二 hibernate框架介紹
    Hibernate是一個開放源代碼的對象關係映射框架,
        它對JDBC進行了很是輕量級的對象封裝,
        它將POJO與數據庫表創建映射關係,是一個全自動的orm框架

第三 JPA規範
    jpa規範,實現jpa規範,內部是由接口和抽象類組成

第四 jpa的基本操做
    案例:是客戶的相關操做(增刪改查)
        客戶:就是一家公司
    客戶表:
    
    jpa操做的操做步驟
        1.加載配置文件建立實體管理器工廠
            Persisitence:靜態方法(根據持久化單元名稱建立實體管理器工廠)
                createEntityMnagerFactory(持久化單元名稱)
            做用:建立實體管理器工廠
            
        2.根據實體管理器工廠,建立實體管理器
            EntityManagerFactory :獲取EntityManager對象
            方法:createEntityManager
            * 內部維護的不少的內容
                內部維護了數據庫信息,
                維護了緩存信息
                維護了全部的實體管理器對象
                再建立EntityManagerFactory的過程當中會根據配置建立數據庫表
            * EntityManagerFactory的建立過程比較浪費資源
            特色:線程安全的對象
                多個線程訪問同一個EntityManagerFactory不會有線程安全問題
            * 如何解決EntityManagerFactory的建立過程浪費資源(耗時)的問題?
            思路:建立一個公共的EntityManagerFactory的對象
            * 靜態代碼塊的形式建立EntityManagerFactory
            
        3.建立事務對象,開啓事務
            EntityManager對象:實體類管理器
                getTransaction : 建立事務對象
                presist : 保存
                merge  : 更新
                remove : 刪除
                find/getRefrence : 根據id查詢
                
            Transaction 對象 : 事務
                begin:開啓事務
                commit:提交事務
                rollback:回滾
        4.增刪改查操做
        5.提交事務
        6.釋放資源
    
    i.搭建環境的過程
        1.建立maven工程導入座標
        2.須要配置jpa的核心配置文件
            *位置:配置到類路徑下的一個叫作 META-INF 的文件夾下
            *命名:persistence.xml
        3.編寫客戶的實體類
        4.配置實體類和表,類中屬性和表中字段的映射關係
        5.保存客戶到數據庫中
    ii.完成基本CRUD案例
        persist : 保存
        merge : 更新
        remove : 刪除
        find/getRefrence : 根據id查詢
        
    iii.jpql查詢
        sql:查詢的是表和表中的字段
        jpql:查詢的是實體類和類中的屬性
        * jpql和sql語句的語法類似
        
        1.查詢所有
        2.分頁查詢
        3.統計查詢
        4.條件查詢
        5.排序

 

1.ORM概述[瞭解]java

ORM(Object-Relational Mapping) 表示對象關係映射。在面向對象的軟件開發中,經過ORM,就能夠把對象映射到關係型數據庫中。只要有一套程序可以作到創建對象與數據庫的關聯,操做對象就能夠直接操做數據庫數據,就能夠說這套程序實現了ORM對象關係映射mysql

簡單的說:ORM就是創建實體類和數據庫表之間的關係,從而達到操做實體類就至關於操做數據庫表的目的。程序員

  1. 爲何使用ORM

當實現一個應用程序時(不使用O/R Mapping),咱們可能會寫特別多數據訪問層的代碼,從數據庫保存數據、修改數據、刪除數據,而這些代碼都是重複的。而使用ORM則會大大減小重複性代碼。對象關係映射(Object Relational Mapping,簡稱ORM),主要實現程序對象到關係數據庫數據的映射。spring

  1. 常見ORM框架

常見的orm框架:Mybatis(ibatis)、Hibernate、Jpasql

hibernate與JPA的概述[瞭解]數據庫

  1. hibernate概述

Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了很是輕量級的對象封裝,它將POJO與數據庫表創建映射關係,是一個全自動的orm框架,hibernate能夠自動生成SQL語句,自動執行,使得Java程序員能夠爲所欲爲的使用對象編程思惟來操縱數據庫。編程

  1. JPA概述

JPA的全稱是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基於ORM的規範,內部是由一系列的接口和抽象類構成。設計模式

JPA經過JDK 5.0註解描述對象-關係表的映射關係,並將運行期的實體對象持久化到數據庫中。api

  1. JPA的優點

1. 標準化緩存

   JPA 是 JCP 組織發佈的 Java EE 標準之一,所以任何聲稱符合 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是EJB QL的一種擴展,它是針對實體的一種查詢語言,操做對象是實體,而不是關係數據庫的表,並且可以支持批量更新和修改、JOIN、GROUP BY、HAVING 等一般只有 SQL 纔可以提供的高級查詢特性,甚至還可以支持子查詢。

5. 高級特性

   JPA 中可以支持面向對象的高級特性,如類之間的繼承、多態和類之間的複雜關係,這樣的支持可以讓開發者最大限度的使用面向對象的模型設計企業應用,而不須要自行處理這些特性在關係數據庫的持久化。

  1. JPA與hibernate的關係

JPA規範本質上就是一種ORM規範,注意不是ORM框架——由於JPA並未提供ORM實現,它只是制訂了一些規範,提供了一些編程的API接口,但具體實現則由服務廠商來提供實現。           

JPAHibernate的關係就像JDBCJDBC驅動的關係,JPA是規範,Hibernate除了做爲ORM框架以外,它也是一種JPA實現。JPA怎麼取代Hibernate呢?JDBC規範能夠驅動底層數據庫嗎?答案是否認的,也就是說,若是使用JPA規範進行數據庫操做,底層須要hibernate做爲其實現類完成數據持久化工做。

JPA的入門案例

 

  1. 需求介紹

實現的功能是保存一個客戶到數據庫的客戶表中。

  1. 開發包介紹

因爲JPA是sun公司制定的API規範,因此咱們不須要導入額外的JPA相關的jar包,只須要導入JPA的提供商的jar包。咱們選擇Hibernate做爲JPA的提供商,因此須要導入Hibernate的相關jar包。

下載網址:

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

 頁面顯示以下圖:

  1. 搭建開發環境[重點]

        導入jar包

對於JPA操做,只須要從hibernate提供的資料中找到咱們須要的jar導入到工程中便可。

  1. maven工程導入座標
  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.hibernate.version>5.0.7.Final</project.hibernate.version>
    </properties>
    <dependencies>
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- hibernate對jpa的支持包 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${project.hibernate.version}</version>
        </dependency>
        <!-- c3p0 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
           <version>${project.hibernate.version}</version>
        </dependency>
        <!-- log日誌 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- Mysql and MariaDB -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
    </dependencies>
      1. 建客戶的數據庫表和客戶的實體類
  1. 建立客戶的數據庫表
  2.    /*建立客戶表*/
        CREATE TABLE cst_customer (
          cust_id bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客戶編號(主鍵)',
          cust_name varchar(32) NOT NULL COMMENT '客戶名稱(公司名稱)',
          cust_source varchar(32) DEFAULT NULL COMMENT '客戶信息來源',
         cust_industry varchar(32) DEFAULT NULL COMMENT '客戶所屬行業',
          cust_level varchar(32) DEFAULT NULL COMMENT '客戶級別',
          cust_address varchar(128) DEFAULT NULL COMMENT '客戶聯繫地址',
          cust_phone varchar(64) DEFAULT NULL COMMENT '客戶聯繫電話',
          PRIMARY KEY (`cust_id`)
        ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

     

  3. 建立客戶的實體類
public class Customer implements Serializable {  

    private Long custId;

    private String custName;

    private String custSource;

    private String custIndustry;

    private String custLevel;

    private String custAddress;

    private String custPhone;

   

    public Long getCustId() {

        return custId;

    }

    public void setCustId(Long custId) {

        this.custId = custId;

    }

    public String getCustName() {

        return custName;

    }

    public void setCustName(String custName) {

        this.custName = custName;

    }

    public String getCustSource() {

        return custSource;

    }

    public void setCustSource(String custSource) {

        this.custSource = custSource;

    }

    public String getCustIndustry() {

        return custIndustry;

    }

    public void setCustIndustry(String custIndustry) {

        this.custIndustry = custIndustry;

    }

    public String getCustLevel() {

        return custLevel;

    }

    public void setCustLevel(String custLevel) {

        this.custLevel = custLevel;

    }

    public String getCustAddress() {

        return custAddress;

    }

    public void setCustAddress(String custAddress) {

        this.custAddress = custAddress;

    }

    public String getCustPhone() {

        return custPhone;

    }

    public void setCustPhone(String custPhone) {

        this.custPhone = custPhone;

    }

}  
      1. 編寫實體類和數據庫表的映射配置[重點]
  1. 在實體類上使用JPA註解的形式配置映射關係
/**

*       * 全部的註解都是使用JPA的規範提供的註解,

 *      * 因此在導入註解包的時候,必定要導入javax.persistence下的

 */

@Entity //聲明實體類

@Table(name="cst_customer") //創建實體類和表的映射關係

public class Customer {

   

    @Id//聲明當前私有屬性爲主鍵

    @GeneratedValue(strategy=GenerationType.IDENTITY) //配置主鍵的生成策略

    @Column(name="cust_id") //指定和表中cust_id字段的映射關係

    private Long custId;

   

    @Column(name="cust_name") //指定和表中cust_name字段的映射關係

    private String custName;

   

    @Column(name="cust_source")//指定和表中cust_source字段的映射關係

    private String custSource;

   

    @Column(name="cust_industry")//指定和表中cust_industry字段的映射關係

    private String custIndustry;

   

    @Column(name="cust_level")//指定和表中cust_level字段的映射關係

    private String custLevel;

   

    @Column(name="cust_address")//指定和表中cust_address字段的映射關係

    private String custAddress;

   

    @Column(name="cust_phone")//指定和表中cust_phone字段的映射關係

    private String custPhone;

   

    public Long getCustId() {

        return custId;

    }

    public void setCustId(Long custId) {

        this.custId = custId;

    }

    public String getCustName() {

        return custName;

    }

    public void setCustName(String custName) {

        this.custName = custName;

    }

    public String getCustSource() {

        return custSource;

    }

    public void setCustSource(String custSource) {

        this.custSource = custSource;

    }

    public String getCustIndustry() {

        return custIndustry;

    }

    public void setCustIndustry(String custIndustry) {

        this.custIndustry = custIndustry;

    }

    public String getCustLevel() {

        return custLevel;

    }

    public void setCustLevel(String custLevel) {

        this.custLevel = custLevel;

    }

    public String getCustAddress() {

        return custAddress;

    }

    public void setCustAddress(String custAddress) {

        this.custAddress = custAddress;

    }

    public String getCustPhone() {

        return custPhone;

    }

    public void setCustPhone(String custPhone) {

        this.custPhone = custPhone;

    }

}
  1. 經常使用註解的說明
        @Entity           做用:指定當前類是實體類。        
        @Table           做用:指定實體類和表之間的對應關係。           
          屬性:              
           name:指定數據庫表的名稱        
        @Id           做用:指定當前字段是主鍵。        
        @GeneratedValue           做用:指定主鍵的生成方式。。           
          屬性:              
            strategy :指定主鍵生成策略。        
        @Column           做用:指定實體類屬性和數據庫表之間的對應關係            
          屬性:              
            name:指定數據庫表的列名稱。              
            unique:是否惟一                
            nullable:是否能夠爲空                
            inserttable:是否能夠插入                
            updateable:是否能夠更新                
            columnDefinition: 定義建表時建立此列的DDL                
            secondaryTable: 從表名。若是此列不建在主表上(默認建在主表),該屬性定義該列所在從表的名字搭建開發環境[重點]
      1. 配置JPA的核心配置文件

在java工程的src路徑下建立一個名爲META-INF的文件夾,在此文件夾下建立一個名爲persistence.xml的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
    version="2.0">
    <!--配置持久化單元
        name:持久化單元名稱
        transaction-type:事務類型
            RESOURCE_LOCAL:本地事務管理
            JTA:分佈式事務管理 -->
    <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
        <!--配置JPA規範的服務提供商 -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <!-- 數據庫驅動 -->
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
           <!-- 數據庫地址 -->
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/ssh" />
            <!-- 數據庫用戶名 -->
            <property name="javax.persistence.jdbc.user" value="root" />
            <!-- 數據庫密碼 -->
            <property name="javax.persistence.jdbc.password" value="111111" />
            <!--jpa提供者的可選配置:咱們的JPA規範的提供者爲hibernate,因此jpa的核心配置中兼容hibernate的配 -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create" />
        </properties>
    </persistence-unit>
</persistence>

    1.實現保存操做

  @Test
    public void test() {
        /**
         * 建立實體管理類工廠,藉助Persistence的靜態方法獲取
         *      其中傳遞的參數爲持久化單元名稱,須要jpa配置文件中指定
         */
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
        //建立實體管理類
        EntityManager em = factory.createEntityManager();
        //獲取事務對象
        EntityTransaction tx = em.getTransaction();
        //開啓事務
        tx.begin();
        Customer c = new Customer();
        c.setCustName("傳智播客");
        //保存操做
        em.persist(c);
        //提交事務
        tx.commit();
        //釋放資源
        em.close();
        factory.close();
    }

JPA中的主鍵生成策略

經過annotation(註解)來映射hibernate實體的,基於annotation的hibernate主鍵標識爲@Id, 其生成規則由@GeneratedValue設定的.這裏的@id和@GeneratedValue都是JPA的標準用法。

JPA提供的四種標準用法爲TABLE,SEQUENCE,IDENTITY,AUTO

具體說明以下:

IDENTITY:主鍵由數據庫自動生成(主要是自動增加型)

用法:

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

SEQUENCE:根據底層數據庫的序列來生成主鍵,條件是數據庫支持序列。

用法:

    @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介紹

 

  1. Persistence對象

Persistence對象主要做用是用於獲取EntityManagerFactory對象的 。經過調用該類的createEntityManagerFactory靜態方法,根據配置文件中持久化單元名稱建立EntityManagerFactory。

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

EntityManagerFactory 接口主要用來建立 EntityManager 實例

//建立實體管理類
EntityManager em = factory.createEntityManager();

因爲EntityManagerFactory 是一個線程安全的對象(即多個線程訪問同一個EntityManagerFactory 對象不會有線程安全問題),而且EntityManagerFactory 的建立極其浪費資源,因此在使用JPA編程時,咱們能夠對EntityManagerFactory 的建立進行優化,只須要作到一個工程只存在一個EntityManagerFactory 便可

  1. EntityManager

在 JPA 規範中, EntityManager是完成持久化操做的核心對象。實體類做爲普通 java對象,只有在調用 EntityManager將其持久化後纔會變成持久化對象。EntityManager對象在一組實體類與底層數據源之間進行 O/R 映射的管理。它能夠用來管理和更新 Entity Bean, 根椐主鍵查找 Entity Bean, 還能夠經過JPQL語句查詢實體。

咱們能夠經過調用EntityManager的方法完成獲取事務,以及持久化數據庫的操做

方法說明:

getTransaction : 獲取事務對象
   persist : 保存操做
   merge : 更新操做
   remove : 刪除操做
   find/getReference : 根據id查詢
  1. EntityTransaction

在 JPA 規範中, EntityTransaction是完成事務操做的核心對象,對於EntityTransaction在咱們的java代碼中承接的功能比較簡單

begin:開啓事務
commit:提交事務
rollback:回滾事務

抽取JPAUtil工具類

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();
    }
}

使用JPA完成增刪改查操做

  1. 保存
    /**

     * 保存一個實體

     */

    @Test

    public void testAdd() {

        // 定義對象

        Customer c = new Customer();

        c.setCustName("傳智學院");

        c.setCustLevel("VIP客戶");

        c.setCustSource("網絡");

        c.setCustIndustry("IT教育");

        c.setCustAddress("昌平區北七家鎮");

        c.setCustPhone("010-84389340");

        EntityManager em = null;

        EntityTransaction tx = null;

        try {

            // 獲取實體管理對象

            em = JPAUtil.getEntityManager();

            // 獲取事務對象

            tx = em.getTransaction();

            // 開啓事務

            tx.begin();

            // 執行操做

            em.persist(c);

            // 提交事務

            tx.commit();

        } catch (Exception e) {

            // 回滾事務

            tx.rollback();

            e.printStackTrace();

        } finally {

            // 釋放資源

            em.close();

        }

    }
  1. 修改
  @Test

    public void testMerge(){ 

        //定義對象

        EntityManager em=null; 

        EntityTransaction tx=null; 

        try{ 

              //獲取實體管理對象

              em=JPAUtil.getEntityManager();

              //獲取事務對象

              tx=em.getTransaction();

              //開啓事務

              tx.begin();

              //執行操做

              Customer c1 = em.find(Customer.class, 6L);

              c1.setCustName("江蘇傳智學院");

         em.clear();//把c1對象從緩存中清除出去

              em.merge(c1);

              //提交事務

              tx.commit();

        }catch(Exception e){

              //回滾事務

              tx.rollback();

              e.printStackTrace(); 

        }finally{ 

          //釋放資源

          em.close(); 

        }   

    }
  1. 刪除
/**

     * 刪除

     */

    @Test

    public void testRemove() {

       // 定義對象

       EntityManager em = null;

       EntityTransaction tx = null;

       try {

           // 獲取實體管理對象

           em = JPAUtil.getEntityManager();

           // 獲取事務對象

           tx = em.getTransaction();

           // 開啓事務

           tx.begin();

           // 執行操做

           Customer c1 = em.find(Customer.class, 6L);

           em.remove(c1);

           // 提交事務

           tx.commit();

       } catch (Exception e) {

           // 回滾事務

           tx.rollback();

           e.printStackTrace();

       } finally {

           // 釋放資源

           em.close();

       }

    }
  1. 根據id查詢
  /**

     * 查詢一個: 使用當即加載的策略

     */

    @Test

    public void testGetOne() {

        // 定義對象

        EntityManager em = null;

        EntityTransaction tx = null;

        try {

            // 獲取實體管理對象

            em = JPAUtil.getEntityManager();

            // 獲取事務對象

            tx = em.getTransaction();

            // 開啓事務

            tx.begin();

            // 執行操做

            Customer c1 = em.find(Customer.class, 1L);

            // 提交事務

            tx.commit();

            System.out.println(c1); // 輸出查詢對象

        } catch (Exception e) {

            // 回滾事務

            tx.rollback();

            e.printStackTrace();

        } finally {

            // 釋放資源

            em.close();

        }

    }



    // 查詢實體的緩存問題

    @Test

    public void testGetOne() {

        // 定義對象

        EntityManager em = null;

        EntityTransaction tx = null;

        try {

            // 獲取實體管理對象

            em = JPAUtil.getEntityManager();

            // 獲取事務對象

            tx = em.getTransaction();

            // 開啓事務

            tx.begin();

            // 執行操做

            Customer c1 = em.find(Customer.class, 1L);

            Customer c2 = em.find(Customer.class, 1L);

            System.out.println(c1 == c2);// 輸出結果是true,EntityManager也有緩存

            // 提交事務

            tx.commit();

            System.out.println(c1);

        } catch (Exception e) {

            // 回滾事務

            tx.rollback();

            e.printStackTrace();

        } finally {

            // 釋放資源

            em.close();

        }

    }



    // 延遲加載策略的方法:

    /**

     * 查詢一個: 使用延遲加載策略

     */

    @Test

    public void testLoadOne() {

        // 定義對象

        EntityManager em = null;

        EntityTransaction tx = null;

        try {

            // 獲取實體管理對象

            em = JPAUtil.getEntityManager();

            // 獲取事務對象

            tx = em.getTransaction();

            // 開啓事務

            tx.begin();

            // 執行操做

            Customer c1 = em.getReference(Customer.class, 1L);

            // 提交事務

            tx.commit();

            System.out.println(c1);

        } catch (Exception e) {

            // 回滾事務

            tx.rollback();

            e.printStackTrace();

        } finally {

            // 釋放資源

            em.close();

        }

    }
  1. JPA中的複雜查詢

JPQL全稱Java Persistence Query Language

基於首次在EJB2.0中引入的EJB查詢語言(EJB QL),Java持久化查詢語言(JPQL)是一種可移植的查詢語言,旨在以面向對象表達式語言的表達式,將SQL語法和簡單查詢語義綁定在一塊兒·使用這種語言編寫的查詢是可移植的,能夠被編譯成全部主流數據庫服務器上的SQL。

其特徵與原生SQL語句相似,而且徹底面向對象,經過類名和屬性訪問,而不是表名和表的屬性。

  1. 查詢所有

 

//查詢全部客戶

    @Test

    public void findAll() {

        EntityManager em = null;

        EntityTransaction tx = null;

        try {

            //獲取實體管理對象

            em = JPAUtil.getEntityManager();

            //獲取事務對象

            tx = em.getTransaction();

            tx.begin();

            // 建立query對象

            String jpql = "from Customer";

            Query query = em.createQuery(jpql);

            // 查詢並獲得返回結果

            List list = query.getResultList(); // 獲得集合返回類型

            for (Object object : list) {

                System.out.println(object);

            }

            tx.commit();

        } catch (Exception e) {

            // 回滾事務

            tx.rollback();

            e.printStackTrace();

        } finally {

            // 釋放資源

            em.close();

        }

    }
  1. 分頁查詢
//分頁查詢客戶

    @Test

    public void findPaged () {

        EntityManager em = null;

        EntityTransaction tx = null;

        try {

            //獲取實體管理對象

            em = JPAUtil.getEntityManager();

            //獲取事務對象

            tx = em.getTransaction();

            tx.begin();



            //建立query對象

            String jpql = "from Customer";

            Query query = em.createQuery(jpql);

            //起始索引

            query.setFirstResult(0);

            //每頁顯示條數

            query.setMaxResults(2);

            //查詢並獲得返回結果

            List list = query.getResultList(); //獲得集合返回類型

            for (Object object : list) {

                System.out.println(object);

            }

            tx.commit();

        } catch (Exception e) {

            // 回滾事務

            tx.rollback();

            e.printStackTrace();

        } finally {

            // 釋放資源

            em.close();

        }

    }
  1. 條件查詢

 

//條件查詢

    @Test

    public void findCondition () {

        EntityManager em = null;

        EntityTransaction tx = null;

        try {

            //獲取實體管理對象

            em = JPAUtil.getEntityManager();

            //獲取事務對象

            tx = em.getTransaction();

            tx.begin();

            //建立query對象

            String jpql = "from Customer where custName like ? ";

            Query query = em.createQuery(jpql);

            //對佔位符賦值,從1開始

            query.setParameter(1, "傳智播客%");

            //查詢並獲得返回結果

            Object object = query.getSingleResult(); //獲得惟一的結果集對象

            System.out.println(object);

            tx.commit();

        } catch (Exception e) {

            // 回滾事務

            tx.rollback();

            e.printStackTrace();

        } finally {

            // 釋放資源

            em.close();

        }

    }
  1. 排序查詢

 

//根據客戶id倒序查詢全部客戶

    //查詢全部客戶

    @Test

    public void testOrder() {

        EntityManager em = null;

        EntityTransaction tx = null;

        try {

            //獲取實體管理對象

            em = JPAUtil.getEntityManager();

            //獲取事務對象

            tx = em.getTransaction();

            tx.begin();

            // 建立query對象

            String jpql = "from Customer order by custId desc";

            Query query = em.createQuery(jpql);

            // 查詢並獲得返回結果

            List list = query.getResultList(); // 獲得集合返回類型

            for (Object object : list) {

                System.out.println(object);

            }

            tx.commit();

        } catch (Exception e) {

            // 回滾事務

            tx.rollback();

            e.printStackTrace();

        } finally {

            // 釋放資源

            em.close();

        }

    }
  1. 統計查詢

 

//統計查詢

    @Test

    public void findCount() {

        EntityManager em = null;

        EntityTransaction tx = null;

        try {

            //獲取實體管理對象

            em = JPAUtil.getEntityManager();

            //獲取事務對象

            tx = em.getTransaction();

            tx.begin();

            // 查詢所有客戶

            // 1.建立query對象

            String jpql = "select count(custId) from Customer";

            Query query = em.createQuery(jpql);

            // 2.查詢並獲得返回結果

            Object count = query.getSingleResult(); // 獲得集合返回類型

            System.out.println(count);

            tx.commit();

        } catch (Exception e) {

            // 回滾事務

            tx.rollback();

            e.printStackTrace();

        } finally {

            // 釋放資源

            em.close();

        }

    }

Part 2

orm思想,hibernate,JPA的相關操做
	
* SpringDataJpa

第一 springDataJpa的概述

第二 springDataJpa的入門操做
	案例:客戶的基本CRUD
	i.搭建環境
		建立工程導入座標
		配置spring的配置文件(配置spring Data jpa的整合)
		編寫實體類(Customer),使用jpa註解配置映射關係
	ii.編寫一個符合springDataJpa的dao層接口
		* 只須要編寫dao層接口,不須要編寫dao層接口的實現類
		* dao層接口規範
			1.須要繼承兩個接口(JpaRepository,JpaSpecificationExecutor)
			2.須要提供響應的泛型
	
	* 
		findOne(id) :根據id查詢
		save(customer):保存或者更新(依據:傳遞的實體類對象中,是否包含id屬性)
		delete(id) :根據id刪除
		findAll() : 查詢所有

第三 springDataJpa的運行過程和原理剖析
	1.經過JdkDynamicAopProxy的invoke方法建立了一個動態代理對象
	2.SimpleJpaRepository當中封裝了JPA的操做(藉助JPA的api完成數據庫的CRUD)
	3.經過hibernate完成數據庫操做(封裝了jdbc)


第四 複雜查詢
	i.藉助接口中的定義好的方法完成查詢
		findOne(id):根據id查詢       當即加載
        count():統計總條數
        exists():是否存在
        getOne():根據id從數據庫查詢   延遲加載
	ii.jpql的查詢方式
		jpql : jpa query language  (jpq查詢語言)
		特色:語法或關鍵字和sql語句相似
			查詢的是類和類中的屬性
			
		* 須要將JPQL語句配置到接口方法上
			1.特有的查詢:須要在dao接口上配置方法
			2.在新添加的方法上,使用註解的形式配置jpql查詢語句
			3.註解 : @Query

	iii.sql語句的查詢
			1.特有的查詢:須要在dao接口上配置方法
			2.在新添加的方法上,使用註解的形式配置sql查詢語句
			3.註解 : @Query
				value :jpql語句 | sql語句
				nativeQuery :false(使用jpql查詢) | true(使用本地查詢:sql查詢)
					是否使用本地查詢
					
	iiii.方法名稱規則查詢

Part3

相關文章
相關標籤/搜索