JPA-SQL

RapidClipse bietet mit dem JPA-SQL Editor ein mächtiges Tool für die Formulierung Ihrer Datenbankabfragen. JPA-SQL ist eine domänenspezifische, datenbankunabhängige Sprache (DSL). Die Syntax wurde gezielt an SQL angelehnt, sodass JPA-SQL leicht erlernbar ist. JPA-SQL ist nicht zu verwechseln mit nativem SQL. In JPA-SQL formulierte Abfragen werden niemals an eine Datenbank versendet, sondern in Javacode umgewandelt, der auf der JPA Criteria API basiert. Damit erhalten Sie sämtliche Vorteile der JPA Criteria API, ohne jedoch JPA Criteria Code schreiben zu müssen.

Erst zur Laufzeit werden aus dem generierten JPA Criteria Code von Hibernate native SQL-Statements passend für die entsprechend angebundene Datenbank erzeugt und an die Datenbank versendet. JPA-SQL kombiniert somit die Einfachheit von SQL mit den zahlreichen Vorteilen der JPA Criteria API. 

Vorteile von JPA-SQL im Vergleich zur Verwendung von SQL-Strings:

  • Übersichtlichere Codestruktur
  • Typsicher
  • Beliebige Reihenfolge der Statements
  • IDE-Unterstützung
    • Code Completion - Erkennung von Schlüsselwörter, Operatoren und Entities 
    • Syntax-Highlighting
    • Code-Folding
    • Formatter

    • Inline Refactoring and Refactoring Participants for JDT Member Renames and Moves

    • Hovers

    • Linking (Ctrl+Click)

    • Outline View

    • Error/Warning-Markers with Quick Fixes

    • Code Templates

    • Integration in Eclipse build process

    • debuggbar (generierter JPA Criteria Code)
  • Query-Methode im DAO wird automatisch generiert
  • Datenbankunabhängig

Vorteile von JPA-SQL im Vergleich zur JPA Criteria API:

  • SQL-ähnliche Syntax und Codestruktur
  • Deutlich geringere Komplexität
  • Übersichtlicherer Code
  • Leicht erlernbar


  1. Klicken Sie im Project Management > Data Access das DAO an, über das Sie eine Datenbankabfrage durchführen möchten, z.B. CustomerDAO.java.
  2. Drücken Sie Strg + Space und wählen Sie in der folgenden Autovervollständigung query - create new query aus.
  3. Geben Sie bei der generierten Methode einen geeigneten Methodennamen an, z.B. findAllCustomer.

    findAllCustomer()
    {
    	select * from 
    }
  4. Geben Sie nach dem Schlüsselwort from > C ein, drücken Sie Strg + Space und wählen Sie Customer aus.
  5. Klicken Sie auf Speichern.


Ergebnis:
  • Queries - JPA-SQL Code.

    import com.company.test.entities.Customer
    
    findAllCustomer()
    {
    	select * from Customer
    }
  • Java - Generierte Java Code auf Basis der JPA Criteria API. Zu der Query-Methode werden auch die notwendigen Imports generiert. 

    /**
     * @queryMethod Do not edit, method is generated by editor!
     */
    public List<Customer> findAllCustomer() {
    	EntityManager entityManager = em();
    
    	CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    
    	CriteriaQuery<Customer> criteriaQuery = criteriaBuilder.createQuery(Customer.class);
    
    	Root<Customer> root = criteriaQuery.from(Customer.class);
    
    	TypedQuery<Customer> query = entityManager.createQuery(criteriaQuery);
    	return query.getResultList();
    }
Examples:
  • Find all 

    findAllCustomer()
    {
    	select * from Customer
    }
    

    Alternativ erlaubte Schreibweise:

    findAllCustomer()
    {
    	from Customer
    }
  • Where Condition

    findAllCustomerWhere()
    {
    	select * from Customer where city = "London"
    }
  • Where Condition mit Parameter

    findAllCustomerWhere(String city)
    {
    	select * from Customer where city = :city
    }

    Als Parameter können auch Objekte übergeben werden:

    findAllCustomerWhere(Customer customer)
    {
    	select * from Customer where customer = :customer
    }
  • Like Operator

    findAllCustomerLike()
    {
    	select * from Customer where city like "%L"
    }
  • Concat Funktion

    findAllCustomerLike(String city)
    {
    	select * from Customer where city like concat("%", :city)
    }
  • Rückgabe bestimmter Spalten

    findAllCustomerColumn()
    {
    	select customerid, city, address from Customer
    }
  • Speichert das Abfrageergebnis in eine andere Klasse

    findAllCustomer()
    {
    	select customerid, city, address from Customer
        into FlatCustomer
    }
  • Alias

    findAllCustomerAs()
    {
    	select * from Customer as c
        where c.city = "London"
    }
  • Logisch AND

    findAllCustomerAnd()
    {
    	select * from Customer where city = "London" and country = "UK"
    }
  • Logisch OR

    findAllCustomerOr()
    {
    	select * from Customer where city = "London" or city = "Berlin"
    }
  • MAX Funktion - Gibt den höchsten Unitprice zurück

    getOrderDetailMaxPrice()
    {
    	select max(unitprice) from Orderdetail result single
    }
    
    
  • MIN Funktion - Gibt den niedrigsten Unitprice zurück

    getOrderDetailMinPrice()
    {
    	select min(unitprice) from Orderdetail result single
    }
  • AVG Funktion - Gruppiert nach dem Produktnamen und berechnet den durchschnittlichen Bestellwert der Orderdetails

    getOrderDetailAvgPrice()
    {
    	select avg(unitprice) from Orderdetail
    	group by product.productname
    }
    getOrderDetailAvgPrice()
    {
    	select avg(unitprice) as price, product.productname from Orderdetail
    	group by product.productname
    }
  • ORDER BY Funktion 

    • Absteigende Sortierung

      getAllCustomerWithOrderByDesc()
      {
      	select * from Customer order by city desc
      }
    • Aufsteigende Sortierung

      getAllCustomerWithOrderByAsc()
      {
      	select * from Customer order by city asc
      }
  • Count Funktion

    getCountFromCustomerByCountry()
    {
    	select count(customerid) from Customer group by country
    }
  • Subselects

    getOrderDetailsFromLondon()
    {
    	select * from Orderdetail as detail
    	where detail.`order`.orderid in (select orderid from Order where customer.city = "London")
    }

    Alternative zu Subselects:

    getOrderDetailsFromLondon()
    {
    	select * from Orderdetail
    	where `order`.customer.city = "London"
    }
  • Komplexe Queries
    • Gibt alle Bestellungen aus London zurück und Gruppiert diese um die Summe aller Bestellungen aus London

      getOrderDetailsSumFromLondon()
      {
      	select sum(detail.unitprice) from Orderdetail as detail
      	where detail.`order`.orderid in (select orderid from Order where customer.city = "London")
      	group by detail.`order`.customer.city
      	result single
      }
    • Mögliche Kurzform

      getOrderDetailsSumFromLondon()
      {
      	select sum(unitprice) from Orderdetail
      	where `order`.customer.city = "London"
      	group by `order`.customer.city
      	result single
      }
Hinweis:
  • JPA-SQL Funktionsumfang - JPA-SQL wurde entwickelt, um den Einsatz der JPA Criteria API zu vereinfachen. Der Funktionsumfang von JPA-SQL ist dadurch auf den Funktionsumfang der JPA Criteria API begrenzt.
  • Generierten Code editieren - Die Generierung des Java JPA Criteria Codes erfolgt unidirektional. D.h., Änderungen dürfen nur im JPA-SQL Code vorgenommen werden. Der generierte Java JPA Criteria Code darf nicht editiert werden.
  • Mehrere Query-Methoden - In einer DAO Klasse können sich beliebig viele Query-Methoden befinden.

    import com.company.test.entities.Customer
    findAllCustomer()
    {
    	select * from Customer 
    }
    
    
    findCustomerByID()
    {
    	select * from Customer where customerid = "BOLID"
    }

JPA-SQL Sprach-Spezifikation