1. 程式人生 > >JPA(七)查詢總結

JPA(七)查詢總結

一、根據id查詢

  顧名思義:即根據主鍵查詢一個實體。在 JPA 中提供了兩個方法。分別是:
  find(Class entityClass,Object id);
  getReference(Class entityClass,Object id);
他們的區別是:

查詢的時機不一樣:
  find 的方法是立即載入,只要一呼叫方法就馬上發起查詢。
  getReference 方法是延遲載入,只有真正用到資料時才發起查 詢。(按需載入)
返回的結果不一樣:
  find 方法返回的是實體類物件。
  getReference 方法返回的是實體類的代理物件。
示例

//查詢一個
//立即載入
@Test
public void testFindOne() {
    EntityManager em = JPAUtil.createEntityManager();
    EntityTransaction tx = em.getTransaction();
    tx.begin();
    Customer c = em.find(Customer.class, 1);
    System.out.println(c);
    tx.commit();
    em.close();
}
//查詢一個
//懶載入(延遲載入)
@Test
public void testFindOne2() { 
    EntityManager em = JPAUtil.createEntityManager
(); EntityTransaction tx = em.getTransaction(); tx.begin(); Customer c = em.getReference(Customer.class, 1); System.out.println(c.toString()); tx.commit(); em.close(); }

二、物件導航查詢

此種查詢方式,是根據已知實體,呼叫該實體中的 getXXX 方法獲取到關聯物件的資訊。
例如:
Customer 物件中有一個 LinkMan 的集合屬性,並生成了 get 和 set 方法。
我們就可以通過 getLinkMans()得到該客戶下的所有聯絡人資訊。
要求:
兩個實體必須有關聯關係,才能使用此種查詢方式。


示例:

/**
    * 根據客戶導航查詢聯絡人
    */
    @Test
    public void test() {
        // 定義物件
        EntityManager em = null;
        EntityTransaction tx = null;
        try {
            // 獲取實體管理物件
            em = JpaUtil.getEntityManager();
            // 獲取事務物件
            tx = em.getTransaction();
            // 開啟事務
            tx.begin();
            // 執行操作
            Customer c1 = em.find(Customer.class, 26L);
            System.out.println(c1); // 輸出查詢物件

            Set<LinkMan> linkMans = c1.getLinkMans();

            for (LinkMan linkMan : linkMans) {
                System.out.println(linkMan);
            }
            // 提交事務
            tx.commit();

        } catch (Exception e) {
            // 回滾事務
            tx.rollback();
            e.printStackTrace();
        } finally {
            // 釋放資源
            em.close();
        }
    }


    /**
    * 根據聯絡人導航查詢客戶
    */
    @Test
    public void test2() {
        // 定義物件
        EntityManager em = null;
        EntityTransaction tx = null;
        try {
            // 獲取實體管理物件
            em = JpaUtil.getEntityManager();
            // 獲取事務物件
            tx = em.getTransaction();
            // 開啟事務
            tx.begin();
            // 執行操作
            LinkMan linkMan = em.find(LinkMan.class, 35L);
            System.out.println(linkMan); // 輸出查詢物件

            Customer customer = linkMan.getCustomer();
            System.out.println(customer); //輸入導航查詢結果
            // 提交事務
            tx.commit();

        } catch (Exception e) {
            // 回滾事務
            tx.rollback();
            e.printStackTrace();
        } finally {
            // 釋放資源
            em.close();
        }
    }

三、JPQL查詢

   此種方式是使用 JPQL 語句查詢。全稱是 Java Persistence Query Language。JPQL 語句是 JPA 中定義的一種查詢語言。此種語言的用意是讓開發者忽略資料庫表和表中的欄位,而關注實體類及實體類中的屬性。更加契合操作實體類就相當於操作資料庫表的 ORM 思想。但是又不完全脫離 SQL 語句,例如:
排序,仍然使用 order 關鍵字。
聚合函式:在 JPQL 中也可以是使用。
它的寫法是:
把查詢的表名換成實體類名稱,把表中的欄位名換成實體類的屬性名稱。
注意:
此處我們必須明確,實體類屬性名稱指的是 get/set 方法後面的部分,且首字母改小寫。而非私
有類成員變數。只不過我們的 get/set 方法都是通過工具生成的,所以可以直接寫私有成員變數名稱。


    /**
    * 根據id查詢
    */
    @Test
    public void test() {
        // 定義物件
        EntityManager em = null;
        EntityTransaction tx = null;
        try {
            // 獲取實體管理物件
            em = JpaUtil.getEntityManager();
            // 獲取事務物件
            tx = em.getTransaction();
            // 開啟事務
            tx.begin();

            //JPQL建立查詢語句
            //Query query = em.createQuery("select c from Customer c where c.id = ?");
            //也可以勝率select c 
            Query query = em.createQuery(" from Customer where custId = ?");
            query.setParameter(1, 26L);

            // 執行操作
            List list = query.getResultList();

            for (Object object : list) {
                System.out.println(object);
            }
            // 提交事務
            tx.commit();

        } catch (Exception e) {
            // 回滾事務
            tx.rollback();
            e.printStackTrace();
        } finally {
            // 釋放資源
            em.close();
        }
    }

四、SQL查詢

  此種方式是使用原生SQL語句查詢資料庫。採用此種方式查詢,我們可以在資料庫視覺化編譯器中先把語句寫好,然後粘到程式碼中。
注意:
  一般採用 ORM 框架作為持久層解決方案時,很少使用原生 SQL 語句。(特定情況除外:例如統計分析的語句,一般用於複雜查詢)

/**
     * 根據id查詢
     */
    @Test
    public void test() {
        // 定義物件
        EntityManager em = null;
        EntityTransaction tx = null;
        try {
            // 獲取實體管理物件
            em = JpaUtil.getEntityManager();
            // 獲取事務物件
            tx = em.getTransaction();
            // 開啟事務
            tx.begin();

            Query query = em.createNativeQuery(
                    "select * from cst_customer", Customer.class);

            // 執行操作
            List<Customer> list = query.getResultList();

            for (Customer cust : list) {
                System.out.println(cust);
            }

            // 提交事務
            tx.commit();

        } catch (Exception e) {
            // 回滾事務
            tx.rollback();
            e.printStackTrace();
        } finally {
            // 釋放資源
            em.close();
        }
    }

五、QBC查詢

  QBC 全稱是 Query By Criteria。此種方式是一種更加面向物件的查詢方式。並且可擴充套件條件查詢 API,通過它完全不需要考慮資料庫底層如何實現,以及 SQL 語句如何編寫。
細節:
  JPQL 能查的,QBC 都能查,反之亦然。

/**
     * 
     * 5、查詢所有客戶
     */

    @Test
    public void findAll() {
        EntityManager em = null;
        EntityTransaction tx = null;
        // 1.獲取 JPA 的操作資料庫物件
        em = JpaUtil.getEntityManager();
        // 3.開啟事務
        tx = em.getTransaction();
        tx.begin();
        // 4.建立 CriteriaBuilder(條件構建)物件,該物件中定義著查詢條件涉及的方法,通過該物件設定查詢條件
        CriteriaBuilder cb = em.getCriteriaBuilder();

        // 5.獲取 QBC 的查詢的物件 CriteriaQuery.
        // 它可以加一些 SQL 的子句例如:where/group by/order by/having 等等。
        CriteriaQuery<Customer> cq = cb.createQuery(Customer.class);

        // 6.獲取實體類物件的封裝物件,有此物件之後,所有實體類都可以看成此型別
        Root<Customer> root = cq.from(Customer.class);

        // 7.建立條件物件
        Predicate p1 = cb.like(root.get("custName"), "%天%");
        Predicate p2 = cb.equal(root.get("custLevel"), "VIP 客戶");
        Predicate p3 = cb.between(root.get("custId"), 10, 20);

        // 8.構建排序條件,並獲取構建排序後的QBC 的查詢物件
        Order o = cb.desc(root.get("custId"));
        CriteriaQuery<Customer> cq1 = cq.orderBy(o);

        // 9.給查詢物件設定查詢條件
        cq1.where(p1, p2, p3);
        TypedQuery<Customer> createQuery = em.createQuery(cq1);
        // 10.執行查詢,獲取結果
        List list = createQuery.getResultList(); // 得到集合返回型別
        for (Object object : list) {
            System.out.println(object);
        }
        // 提交事物
        tx.commit();
        // 釋放資源
        em.close();
    }