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.