Sobes.tech
Junior

Czym jest JPA (Java Persistence API)?

sobes.tech AI

Odpowiedź od AI

JPA jest specyfikacją API do zarządzania trwałością danych w aplikacjach Java. Zapewnia standardowy sposób mapowania obiektów Java na relacyjne bazy danych (lub inne magazyny danych) i odwrotnie. JPA jest częścią platformy Java EE (obecnie Jakarta EE) i może być również używana w aplikacjach standalone.

Kluczowe komponenty JPA:

  • Entity: zwykłe klasy Java (POJO), oznaczone adnotacją @Entity, reprezentujące dane w bazie danych.
  • EntityManager: interfejs do interakcji z kontekstem trwałości. Używany do wyszukiwania, tworzenia, aktualizacji i usuwania encji.
  • Kontekst trwałości: zbiór encji zarządzanych przez EntityManager. Śledzi on zmiany encji przed synchronizacją z bazą danych.
  • JPQL (Java Persistence Query Language): obiektowy język zapytań, podobny do SQL, ale operujący na encjach i ich relacjach zamiast na tabelach i kolumnach.
  • Criteria API: obiektowe API do wykonywania dynamicznych zapytań.
  • persistence.xml: plik konfiguracyjny opisujący jednostki trwałości (persistence units) i ich właściwości (np. informacje o połączeniu z bazą danych, strategie mapowania).

JPA nie jest konkretną implementacją ORM (Object-Relational Mapping), a jedynie określa kontrakty i API. Istnieje wiele dostawców JPA implementujących tę specyfikację, z których najpopularniejsze to:

  • Hibernate
  • EclipseLink
  • Apache OpenJPA

Przykład definicji encji:

// Encja reprezentująca wpis w tabeli `products`
@Entity
// Nazwa tabeli w bazie danych
@Table(name = "products")
public class Product {

    // Klucz główny
    @Id
    // Strategia generowania klucza głównego
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    // Kolumna `name` w tabeli
    private String name;

    // Kolumna `price` w tabeli
    private BigDecimal price;

    // Konstruktory, gettery i settery
    // ...
}

Przykład użycia EntityManager:

// Uzyskanie EntityManager z EntityManagerFactory
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPersistenceUnit");
EntityManager em = emf.createEntityManager();

try {
    // Rozpoczęcie transakcji
    em.getTransaction().begin();

    // Utworzenie nowej encji
    Product newProduct = new Product();
    newProduct.setName("Laptop");
    newProduct.setPrice(new BigDecimal("1200.00"));

    // Zapis encji w bazie
    em.persist(newProduct);

    // Szukanie encji po kluczu głównym
    Product foundProduct = em.find(Product.class, 1L);
    System.out.println("Znaleziony produkt: " + foundProduct.getName());

    // Wykonanie zapytania JPQL
    List<Product> allProducts = em.createQuery("SELECT p FROM Product p", Product.class).getResultList();
    for (Product p : allProducts) {
        System.out.println(p.getName());
    }

    // Zatwierdzenie transakcji
    em.getTransaction().commit();

} catch (Exception e) {
    // Wycofanie transakcji w przypadku błędu
    if (em.getTransaction().isActive()) {
        em.getTransaction().rollback();
    }
    e.printStackTrace();
} finally {
    // Zamknięcie EntityManager
    em.close();
    // Zamknięcie EntityManagerFactory
    emf.close();
}

Głównym celem JPA jest uproszczenie rozwoju aplikacji pracujących z bazami danych poprzez abstrakcję niskopoziomowych szczegółów pracy z JDBC i SQL, zapewniając podejście obiektowe do trwałości. To zwiększa przenośność kodu i zmniejsza jego zależność od konkretnej bazy danych.