Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare ist ein Scribd-Unternehmen logo
Michael Kurz | IRIAN


JSF und JPA effizient kombinieren
Agenda

•   Motivation
•   Architektur mit/ohne EE 6-Container
•   Integration von JPA und JSF
•   Demonstration anhand eines Beispiels:
    – MyMail 01: Architektur, JPA, JSF
    – MyMail 02: Paging
    – MyMail 03: Selektion
Motivation

• Große Datenmengen effizient darstellen
• Übersichtlichkeit durch Paging
• Performance durch gezieltes Laden aus DB
• Selektion einzelner Zeilen
• JPA und JSF ermöglichen mit Bordmitteln
  eine einfache und performante Lösung
• Leichtgewichtige Java EE 6-Architektur
Architektur und Technologie-Stack

  Architektur   Mit EE 6-Container   Ohne EE 6-Container


 Präsentation   JSF, CDI, CODI        JSF, CDI, CODI



   Service         EJB, CDI             CDI, CODI



 Datenzugriff      EJB, JPA           CDI, CODI, JPA
MyFaces Extensions CDI

• Portable Erweiterung für CDI
• Vereinfacht Arbeit mit CDI und JSF
• Mehrere Module:
   – JSF 1.2 und 2.0
   – JPA, Bean-Validation, Message, Scripting...
• Funktioniert mit:
   – CDI: OpenWebBeans, Weld
   – JSF: MyFaces, Mojarra (1.2 und 2.0)
• Stabile Version 1.0.1 verfügbar
Verwaltung des Persistenzkontexts

• Mit Java EE-Container
  – EntityManager vom Container verwaltet
    @javax.ejb.Stateless
    public class CustomerRepository {
      @PersistenceContext private EntityManager em;
    }

• Ohne Java EE-Container (mit CDI)
  – EntityManager von MyFaces CODI verwaltet
    @ApplicationScoped
    public class CustomerRepository {
      @Inject private EntityManager em;
    }
Verwaltung von Transaktionen

• Mit Java EE-Container
  – Transaktionen vom Container verwaltet
  – Steuerung über @TransactionAttribute
• Ohne Java EE-Container (mit CDI)
  – Transaktionen von MyFaces CODI verwaltet
    @ApplicationScoped
    public class CustomerService {
      @Inject
      private CustomerRepository customerRepository;

        @Transactional
        public void saveUser(User user) {...}
    }
Demonstration




Beispiel MyMail 01
• Architektur
• Integration JPA und JSF

Beispiel unter: https://github.com/jsflive/mymail-owb
Abfragen mit JPQL

• JPA 1: Stringbasierte Abfragen mit JPQL
  String queryStr = "select m from Mail m where
    m.subject like :subj order by m.date desc";

• Ausführen der Abfrage mit EntityManager
  Query query = em.createQuery(queryStr);
  query.setParameter("subj", "%108_");
  return query.getResultList();

• Nachteile:
  – Überprüfung erst zur Laufzeit
  – Dynamische Abfragen komplex
Abfragen mit Criteria API 1/2

• JPA 2: Abfragen mit dem Criteria API
• CriteriaBuilder ist Einstiegspunkt
  CriteriaBuilder b = em.getCriteriaBuilder();

• CriteriaQuery ist Container für Abfrage
  CriteriaQuery<Mail> c = b.createQuery(Mail.class);

• CriteriaQuery bietet Methoden für Klauseln
  Root<Mail> root = c.from(Mail.class);
  c.select(root);
  c.where(b.like(root.<String>get("subject"),
      b.parameter(String.class, "subj")));
  c.orderBy(b.desc(root.get("date")));
Abfragen mit Criteria API 2/2

• Ausführen der Abfrage mit EntityManager
  TypedQuery<Mail> query = em.createQuery(crit);
  query.setParameter("subj", "%108_");
  return query.getResultList();

• Vorteile:
   –   Typsicher
   –   Statisch überprüfbar zur Kompilierzeit
   –   Abfragen mit Java-Sprachmittel bauen
   –   Flexibler für dynamische Abfragen
   –   Mehr Funktionalität im Vergleich zu JPQL
Typsicherheit mit dem JPA-Metamodell

• JPA 2: Statisches, kanonisches Metamodell
  – Eine Metamodell-Klasse pro verwalteter Klasse
  – Wird im Normallfall generiert
  @StaticMetamodel(Mail.class)
  public class Mail_ {
    public static volatile
      SingularAttribute<Mail, String> subject;
    public static volatile
      ListAttribute<Mail, Attachment> attachments;
  }

  c.where(b.like(root.get(Mail_.subject),
      b.parameter(String.class, "subj")));
  c.orderBy(b.desc(root.get(Mail_.date)));
Demonstration




Beispiel MyMail 01
• JPA 2 Criteria API



Beispiel unter: https://github.com/jsflive/mymail-owb
Wie funktioniert h:dataTable?

• Anzuzeigende Daten im Attribut value
    – Arrays, Listen, ResultSet, DataModel
•   Zeilenweise Abarbeitung der Daten
•   Ein Datenelement wird zu einer Zeile
•   Variablenname aktueller Zeile in Attribut var
•   h:column für jede Zeile ausgeführt
    <h:dataTable var="mail" value="#{mailBean.mails}">
      <h:column>
        <h:outputText value="#{mail.subject}"/>
      </h:column>
    </h:dataTable>
Paging mit JSF

• h:dataTable unterstützt bereits Paging
  – Attribut first: erste Zeile der Page
  – Attribut rows: Größe der Page
   item00
   item01               Property 1     Property 2
   item02
            first="2"
   item03
                        item02.prop1   item02.prop2
            rows="2"
   item04               item03.prop1   item03.prop2
   item05
   item06


• Paginator-Komponente um first zu setzen
  – Keine Komponente im Standard
• Problem: Nur Daten für Page aus DB laden
Klasse DataModel in JSF

• javax.faces.model.DataModel<E>
  –   public void setRowIndex(int rowIndex)
  –   public E getRowData()
  –   public int getRowCount()
  –   public int getRowIndex()
  –   public boolean isRowAvailable()
  –   public Object getWrappedData()
  –   public void setWrappedData(Object data)
• Eigene Variante PageableDataModel<E>
  – Lädt und cacht Daten für aktuelle Page
Demonstration




Beispiel MyMail 02
• Paging



Beispiel unter: https://github.com/jsflive/mymail-owb
DataModel mit Selektion

• SelectableDataModel mit Set für Selektion
  public class SelectableDataModel<T>
      extends PageableDataModel<T> {
      private Set<T> selectedObjects;
      public Set<T> getSelectedObjects() {...}
      public Map<T, Boolean> getRowSelected() {...}
  }

• Selektion in Seite via Map
  <h:dataTable var="mail" value="#{mailBean.mails}">
    <h:column>
      <h:selectBooleanCheckbox
          value="#{mailBean.mails.rowSelected[mail]}"/>
    </h:column>
  </h:dataTable>
Demonstration




Beispiel MyMail 03
• Selektion



Beispiel unter: https://github.com/jsflive/mymail-owb
Fazit

• Leichtgewichtige Entwicklung mit Java EE 6
• Mit/Ohne EE 6-Container möglich
• Kombination von JPA und JSF bereits
  mit Bordmitteln sehr mächtig
• Standardisierte Lösung
• JPA 2 Criteria API flexibel, aber komplex
Neugierig?




• Marinschek, Kurz, Müllan:
  JavaServer Faces 2.0, dpunkt.Verlag
• Irian JSF@Work Online-Tutorial
  http://jsfatwork.irian.at
• JSFlive Weblog
  http://jsflive.wordpress.com

Weitere ähnliche Inhalte

JSF und JPA effizient kombinieren (W-JAX 2011)

  • 1. Michael Kurz | IRIAN JSF und JPA effizient kombinieren
  • 2. Agenda • Motivation • Architektur mit/ohne EE 6-Container • Integration von JPA und JSF • Demonstration anhand eines Beispiels: – MyMail 01: Architektur, JPA, JSF – MyMail 02: Paging – MyMail 03: Selektion
  • 3. Motivation • Große Datenmengen effizient darstellen • Übersichtlichkeit durch Paging • Performance durch gezieltes Laden aus DB • Selektion einzelner Zeilen • JPA und JSF ermöglichen mit Bordmitteln eine einfache und performante Lösung • Leichtgewichtige Java EE 6-Architektur
  • 4. Architektur und Technologie-Stack Architektur Mit EE 6-Container Ohne EE 6-Container Präsentation JSF, CDI, CODI JSF, CDI, CODI Service EJB, CDI CDI, CODI Datenzugriff EJB, JPA CDI, CODI, JPA
  • 5. MyFaces Extensions CDI • Portable Erweiterung für CDI • Vereinfacht Arbeit mit CDI und JSF • Mehrere Module: – JSF 1.2 und 2.0 – JPA, Bean-Validation, Message, Scripting... • Funktioniert mit: – CDI: OpenWebBeans, Weld – JSF: MyFaces, Mojarra (1.2 und 2.0) • Stabile Version 1.0.1 verfügbar
  • 6. Verwaltung des Persistenzkontexts • Mit Java EE-Container – EntityManager vom Container verwaltet @javax.ejb.Stateless public class CustomerRepository { @PersistenceContext private EntityManager em; } • Ohne Java EE-Container (mit CDI) – EntityManager von MyFaces CODI verwaltet @ApplicationScoped public class CustomerRepository { @Inject private EntityManager em; }
  • 7. Verwaltung von Transaktionen • Mit Java EE-Container – Transaktionen vom Container verwaltet – Steuerung über @TransactionAttribute • Ohne Java EE-Container (mit CDI) – Transaktionen von MyFaces CODI verwaltet @ApplicationScoped public class CustomerService { @Inject private CustomerRepository customerRepository; @Transactional public void saveUser(User user) {...} }
  • 8. Demonstration Beispiel MyMail 01 • Architektur • Integration JPA und JSF Beispiel unter: https://github.com/jsflive/mymail-owb
  • 9. Abfragen mit JPQL • JPA 1: Stringbasierte Abfragen mit JPQL String queryStr = "select m from Mail m where m.subject like :subj order by m.date desc"; • Ausführen der Abfrage mit EntityManager Query query = em.createQuery(queryStr); query.setParameter("subj", "%108_"); return query.getResultList(); • Nachteile: – Überprüfung erst zur Laufzeit – Dynamische Abfragen komplex
  • 10. Abfragen mit Criteria API 1/2 • JPA 2: Abfragen mit dem Criteria API • CriteriaBuilder ist Einstiegspunkt CriteriaBuilder b = em.getCriteriaBuilder(); • CriteriaQuery ist Container für Abfrage CriteriaQuery<Mail> c = b.createQuery(Mail.class); • CriteriaQuery bietet Methoden für Klauseln Root<Mail> root = c.from(Mail.class); c.select(root); c.where(b.like(root.<String>get("subject"), b.parameter(String.class, "subj"))); c.orderBy(b.desc(root.get("date")));
  • 11. Abfragen mit Criteria API 2/2 • Ausführen der Abfrage mit EntityManager TypedQuery<Mail> query = em.createQuery(crit); query.setParameter("subj", "%108_"); return query.getResultList(); • Vorteile: – Typsicher – Statisch überprüfbar zur Kompilierzeit – Abfragen mit Java-Sprachmittel bauen – Flexibler für dynamische Abfragen – Mehr Funktionalität im Vergleich zu JPQL
  • 12. Typsicherheit mit dem JPA-Metamodell • JPA 2: Statisches, kanonisches Metamodell – Eine Metamodell-Klasse pro verwalteter Klasse – Wird im Normallfall generiert @StaticMetamodel(Mail.class) public class Mail_ { public static volatile SingularAttribute<Mail, String> subject; public static volatile ListAttribute<Mail, Attachment> attachments; } c.where(b.like(root.get(Mail_.subject), b.parameter(String.class, "subj"))); c.orderBy(b.desc(root.get(Mail_.date)));
  • 13. Demonstration Beispiel MyMail 01 • JPA 2 Criteria API Beispiel unter: https://github.com/jsflive/mymail-owb
  • 14. Wie funktioniert h:dataTable? • Anzuzeigende Daten im Attribut value – Arrays, Listen, ResultSet, DataModel • Zeilenweise Abarbeitung der Daten • Ein Datenelement wird zu einer Zeile • Variablenname aktueller Zeile in Attribut var • h:column für jede Zeile ausgeführt <h:dataTable var="mail" value="#{mailBean.mails}"> <h:column> <h:outputText value="#{mail.subject}"/> </h:column> </h:dataTable>
  • 15. Paging mit JSF • h:dataTable unterstützt bereits Paging – Attribut first: erste Zeile der Page – Attribut rows: Größe der Page item00 item01 Property 1 Property 2 item02 first="2" item03 item02.prop1 item02.prop2 rows="2" item04 item03.prop1 item03.prop2 item05 item06 • Paginator-Komponente um first zu setzen – Keine Komponente im Standard • Problem: Nur Daten für Page aus DB laden
  • 16. Klasse DataModel in JSF • javax.faces.model.DataModel<E> – public void setRowIndex(int rowIndex) – public E getRowData() – public int getRowCount() – public int getRowIndex() – public boolean isRowAvailable() – public Object getWrappedData() – public void setWrappedData(Object data) • Eigene Variante PageableDataModel<E> – Lädt und cacht Daten für aktuelle Page
  • 17. Demonstration Beispiel MyMail 02 • Paging Beispiel unter: https://github.com/jsflive/mymail-owb
  • 18. DataModel mit Selektion • SelectableDataModel mit Set für Selektion public class SelectableDataModel<T> extends PageableDataModel<T> { private Set<T> selectedObjects; public Set<T> getSelectedObjects() {...} public Map<T, Boolean> getRowSelected() {...} } • Selektion in Seite via Map <h:dataTable var="mail" value="#{mailBean.mails}"> <h:column> <h:selectBooleanCheckbox value="#{mailBean.mails.rowSelected[mail]}"/> </h:column> </h:dataTable>
  • 19. Demonstration Beispiel MyMail 03 • Selektion Beispiel unter: https://github.com/jsflive/mymail-owb
  • 20. Fazit • Leichtgewichtige Entwicklung mit Java EE 6 • Mit/Ohne EE 6-Container möglich • Kombination von JPA und JSF bereits mit Bordmitteln sehr mächtig • Standardisierte Lösung • JPA 2 Criteria API flexibel, aber komplex
  • 21. Neugierig? • Marinschek, Kurz, Müllan: JavaServer Faces 2.0, dpunkt.Verlag • Irian JSF@Work Online-Tutorial http://jsfatwork.irian.at • JSFlive Weblog http://jsflive.wordpress.com