2015-05-17 35 views
7
  • JPA ölçüt API'sinde select deyimini ne zaman kullanılır? <code>CriteriaQuery#select()</code> kullanmadan

      :

      public List<Address> getAddressOfManager(String designation, String name, String orderByColumn) { 
      
          Boolean ascending = false; 
          CriteriaBuilder cb = emanager.getCriteriaBuilder(); 
          CriteriaQuery<Address> cq = cb.createQuery(Address.class); 
          Root<Address> root = cq.from(Address.class); 
          //cq.select(root); <------------- 
          Join<Address, Employee> employeeAddress = root.join(Address_.employee); 
          Join<Employee,Project> employeeProject = employeeAddress.join(Employee_.project); 
          cq.where(cb.or(cb.equal(employeeProject.get(Project_.name), name),cb.equal(employeeAddress.get(Employee_.designation), designation))); 
          Order order = ascending ? cb.asc(root.get(orderByColumn)) 
            : cb.desc(root.get(orderByColumn)); 
          cq.orderBy(order); 
          List<Address> result = emanager.createQuery(cq).getResultList(); 
          return result; 
      } 
      
    1. CriteriaQuery#select() olarak:

      public List<Address> getAddressOfManager(String designation, String name, String orderByColumn) { 
      
          Boolean ascending = false; 
          CriteriaBuilder cb = emanager.getCriteriaBuilder(); 
          CriteriaQuery<Address> cq = cb.createQuery(Address.class); 
          Root<Address> root = cq.from(Address.class); 
          cq.select(root); //<---------------- 
          Join<Address, Employee> employeeAddress = root.join(Address_.employee); 
          Join<Employee,Project> employeeProject = employeeAddress.join(Employee_.project); 
          cq.where(cb.or(cb.equal(employeeProject.get(Project_.name), name),cb.equal(employeeAddress.get(Employee_.designation), designation))); 
          Order order = ascending ? cb.asc(root.get(orderByColumn)) 
            : cb.desc(root.get(orderByColumn)); 
          cq.orderBy(order); 
          List<Address> result = emanager.createQuery(cq).getResultList(); 
          return result; 
      } 
      

      Şimdi, JPA kriterleri sorguda select() ne zaman kullanılacağına olarak karıştı.

  • +0

    'cq.select (kök);' ilişkili taraftaki bütün alanları (ler) de ve seçecektir JPA ölçütünde çıkarılır dolayısıyla karşılık gelen veritabanı tablosu (ler) den. Ancak, bunlardan birkaçını seçmek istediğinizde açık olmanız gerekir. – Tiny

    cevap

    9

    projeksiyon terimini belirtmek için temelde iki yolu (veya basitçe seçim terimini diyerek) sorgu sonucu belirtilmelidir olduğu CriteriaQuery<T> arabiriminde vardır:

    CriteriaQuery<T> select(Selection<? extends T> selection); 
    CriteriaQuery<T> multiselect(Selection<?>... selections); 
    

    Çoğunlukla, kullanılan yansıtma terimi, sorgunun kendisinde bulunan aday sınıftır (örneklerinizdeki Address). İlk örneğinizde olduğu gibi örtük olabilir.

    İlk örneğindeki Address varlığından gelen sorgu, projeksiyon terimini açıkça belirtmez ve bu durumda aday sınıfın kendisini açıkça seçmeyle aynıdır. Tek bir yansıtma ifadesi olarak aday perspektif bir varlığın, dolaylı olarak çıkarıldığı sonucuna varılmıştır.


    sorgunun tahmini sonuç Ancak, aday kalıcı varlık kendisi başka birşey, diğer bazı yapılar sorgunun sonucunu şekillendirmek için kullanılabilir. Bu yapılar, CriteriaBuilder arabiriminde kullanılabilir.

    yöntemleri sorgu sonucu şekil: Bütünlük adına

    CompoundSelection<Y> construct(Class<Y> result, Selection<?>... terms); 
    CompoundSelection<Object[]> array(Selection<?>... terms); 
    CompoundSelection<Tuple> tuple(Selection<?>... terms); 
    

    sadece bunlardan her biri için basit bir örnek ile sırayla onların her göstermek için çalışacaktır.


    construct() bir sınıfın örnekleri, (a olmayan, kalıcı işletme) içine sorgu sonucu Şekillendirme:

    construct() yöntemi verilen sınıf bağımsız değişken bir örneğini oluşturur ve olmayan (bir kurucu çağırır -personel varlık) giriş seçim terimlerinden değerlerle. Kalıcı olmayan bir varlığın yapıcısına yapılan bu argümanlar (bir varlık, düz bir Java sınıfı bile değil), örneğin, giriş seçim terimlerine karşılık gelen değerlerle, sayı ve sırayla (veri türü) eşleşmelidir. Bir (empName için) tip String iki parametre alır yapıcı ve (salary için) BigDecimal sahiptir kalıcı olmayan varlık - bu durumda

    CriteriaQuery<EmployeeDetails> q = cb.createQuery(EmployeeDetails.class); 
    Root<Employee> root = q.from(Employee.class); 
    q.select(cb.construct(EmployeeDetails.class, root.get(Employee_.empName), root.get(Employee_.salary)); 
    

    EmployeeDetails

    , düz bir Java sınıftır.

    Sorgu, bir List<EmployeeDetails> - kalıcı bir varlık olan seçili olmayan Employee s'den kalıcı olmayan bir varlık döndürür. Örneğin, döndürülen satırların sayısına bağlı olarak, sorgu EmployeeDetails örneğini kullanarak getSingleResult() yöntemini kullanarak da döndürebilir (örneğin,).

    Birden çok seçim öğesi, aşağıda gösterildiği gibi Object[] veya Tuple'u temsil eden bileşik seçim terimiyle birleştirilebilir.

    bir Object[] içine sorgu sonucu Şekillendirme:

    de görülebileceği

    CriteriaQuery<Object[]> q = cb.createQuery(Object[].class); 
    Root<Employee> root = q.from(Employee.class); 
    q.select(cb.array(root.get(Employee_.empName), root.get(Employee_.salary)); 
    List<Object[]> list = entityManager.createQuery(q).getResultList(); 
    
    , sorgu List<Object[]> döndürür. Bu listenin her bir öğesi Object s - Object[] - 0 tabanlı bir dizi içerir.

    bir Tuple içine sorgu sonucunu şekillendirme:

    CriteriaQuery<Tuple> q = cb.createTupleQuery(); 
    Root<Employee> root = q.from(Employee.class); 
    Selection<String> empName = root.get(Employee_.empName).alias("empName"); 
    q.select(cb.tuple(empName, root.get(Employee_.salary).alias("salary"); 
    List<Tuple> list = entityManager.createQuery(q).getResultList(); 
    
    String employeeName = list.get(0).get("empName");//Referring to by using its alias (empName) 
    String employeeSalary = list.get(0).get(1);//Referring to by using its index (salary) 
    
    //Iterate over a list of tuples through a foreach loop using alias. 
    
    for (Tuple tuple : list) { 
        System.out.println(tuple.get("empName") + " : " + tuple.get("salary")); 
    } 
    

    sorgusu List<Tuple> döndürür. Tuple tarafından tutulan değerlere TupleElement'un bir diğer adı kullanılarak veya TupleElement tarafından doğrudan 0 temelli bir tamsayı dizini tarafından erişilebilir.

    CriteriaBuilder#createTupleQuery(), CriteriaBuilder#createQuery(Tuple.class) ile aynıdır.

    sonuç türüne göre terimleri yorumlama multiselect() kullanarak:

    giriş koşulları otomatik olarak otomatik sonucu şekline gelmesi CriteriaQuery sonucu türüne göre multiselect() yöntemi ile yorumlanır - CriteriaQuery'un geri dönüş tipi. Örneğin, bu cevaptaki ilk örnek, aşağıdaki gibi multiselect() kullanılarak yeniden yazılabilir.

    CriteriaQuery<EmployeeDetails> q = cb.createQuery(EmployeeDetails.class); 
    Root<Employee> root = q.from(Employee.class); 
    q.multiselect(root.get(Employee_.empName), root.get(Employee_.salary)); 
    

    sonuç türü EmployeeDetails olduğu

    , multiselect() yöntem EmployeeDetails arasında kurucu bağımsız olarak bağımsız değişken çıkıntı koşullar yorumlar. İlk örnekte kullanılan bu gibi bir yapı,, cb.construct(EmployeeDetails.class, root.get(Employee_.empName), root.get(Employee_.salary) sahip değildir

    Uyarı otomatik terimi dönüş türüne göre argümanı projeksiyon koşullar yorumlar ve uygun bir çağırır multiselect() kullanılarak önceki örnekte kullanılmak üzere sonuç sınıfındaki kurucu - EmployeeDetails.

    sorgu olsaydı

    bir Tuple (veya Tuple s bir listesi), Tuple örnekleri yerine, aşağıda gösterildiği gibi yaratacak aynı argüman multiselect() yöntem dönmek belirtilecektir.

    CriteriaQuery<Tuple> q = cb.createTupleQuery(); 
    Root<Employee> root = q.from(Employee.class); 
    q.multiselect(root.get(Employee_.empName), root.get(Employee_.salary)); 
    

    Tabii söz ama aynı şey, aynı zamanda bir Object[] (Object[] s veya liste) döndürmek için tekrar yazılabilir.sırasıyla Tuple ve Object[] olan daha önce sözü geçen her iki durumda da

    CriteriaQuery<Object[]> q = cb.createQuery(Object[].class); 
    Root<Employee> root = q.from(Employee.class); 
    q.multiselect(root.get(Employee_.empName), root.get(Employee_.salary)); 
    

    , muliselect() yöntem otomatik olarak sorgu dönüş türüne göre argümanı projeksiyon koşullar yorumlar.

    Ayrıca EcliseLink this question gösterildiği gibi multiselect() kullanarak bu şekilde tek bir Boolean seçim terimi getirilirken sabit hareketsiz bir bug sahip olduğu not edilmelidir. Farklı JPA sağlayıcılar bağlı olarak


    , multiselect() yöntemin davranışı multiselect() yöntem tek bir seçim dönemi, dönüş tipi kullanılır

    • Eğer bir sonuç türü olarak Object ilginç olur seçili terimdir.
    • Ancak, multiselect() yöntemi birden fazla giriş terim/seçim terimi/yansıtma terimi içeriyorsa, sonuç türü Object[]'dur.

    farklı sağlayıcılar, ancak bir dizi ya da bir toplama (veya tuple değerli bileşik terimi) olmayabilir multiselect() yöntemi ile belirtilen seçim koşulları hakkında emin değilim. multiselect() argümanı olarak izin verilebilecek tek terim terimleri, temelde tek bir elemanı sırasıyla temsil eden construct() yöntemiyle oluşturulanlardır. Yukarıdaki konstruktlarına ilave olarak


    , CriteriaQuery#select(Selection<? extends T> selection) kullanımı skaler/grup/agrega/tek değerli özelliklerini kullanırken oldukça yaygındır, bu nedenle count(), max(), min() vs gibi ve alt sorgular. Alt sorguların kullanımı, bu cevaptan kısaltma için hariç tutulmuştur.

    A Selection bir sorgu tarafından seçilir neyi tanımlar. Bir Seçim, herhangi bir nesne ifadesi, öznitelik ifadesi, işlev, alt seçim, yapıcı veya toplama işlevi olabilir. . Diğer ad() API'si kullanılarak Selection için bir takma ad tanımlanabilir.

    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); 
    
    // Count the total employees 
    CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(); 
    Root employee = criteriaQuery.from(Employee.class); 
    criteriaQuery.select(criteriaBuilder.count(employee)); //<------ 
    Query query = entityManager.createQuery(criteriaQuery); 
    Long result = query.getSingleResult(); 
    
    // Maximum salary 
    CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(); 
    Root employee = criteriaQuery.from(Employee.class); 
    criteriaQuery.select(criteriaBuilder.max(employee.get("salary")); //<------ 
    Query query = entityManager.createQuery(criteriaQuery); 
    Long result = query.getSingleResult(); 
    

    http://en.wikibooks.org/wiki/Java_Persistence/Criteria#Selection

    +0

    Teşekkürler Tiny, Ama hala bu konuda çok net değilim. Referans için herhangi bir URL çok yardımcı olabilir. – Prem

    +0

    [JBoss Referansı] (https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/querycriteria.html), [Oracle Öğreticiler - Java EE 7] (http://docs.oracle. com/javaee/7/tutorial/persistence-criteria.htm), [JPA WikiBook] (http://en.wikibooks.org/wiki/Java_Persistence/Criteria). – Tiny

    +0

    Kod parçacıklarını veya uzun metin bilgilerini anlamada bazı zorluklar mı yaşıyorsunuz? Birkaç kez tekrarlanan tek, basit ve kesik bir örnektir. Hatırladığım bir bloga dayanarak cevap verdim. Bu blogdan birçok şey alıntılamak istedim ama maalesef şu anda bu bağlantıyı bulamıyorum.Bu arada, somut soruyu tek bir ifade ile yanıtlıyor, "* Tek bir projeksiyon terimi olarak adayın kalıcı bir varlığı, dolaylı olarak çıkarıldı. *" – Tiny