Database
 sql >> Baza danych >  >> RDS >> Database

Co to jest technologia Java JPA?

JPA (Adnotacja dotycząca trwałości Java ) to standardowe rozwiązanie Javy, które wypełnia lukę między obiektowymi modelami domen a relacyjnymi systemami baz danych. Pomysł polega na odwzorowaniu klas Java na tabele relacyjne, a właściwości tych klas na wiersze w tabeli. Zmienia to semantykę ogólnego doświadczenia związanego z kodowaniem Java poprzez bezproblemową współpracę dwóch różnych technologii w ramach tego samego paradygmatu programowania. Ten artykuł zawiera przegląd i wspierającą implementację w Javie.

Przegląd

Relacyjne bazy danych są prawdopodobnie najbardziej stabilną ze wszystkich technologii utrwalania dostępnych w informatyce, a nie wszystkich związanych z tym złożoności. Dzieje się tak, ponieważ dziś, nawet w dobie tak zwanych „big danych”, relacyjne bazy danych „NoSQL” są stale poszukiwane i rozwijają się. Relacyjne bazy danych to stabilna technologia nie przez same słowa, ale przez lata istnienia. NoSQL może być dobry do obsługi dużych ilości ustrukturyzowanych danych w przedsiębiorstwie, ale liczne obciążenia transakcyjne są lepiej obsługiwane przez relacyjne bazy danych. Ponadto istnieje kilka świetnych narzędzi analitycznych związanych z relacyjnymi bazami danych.

Aby komunikować się z relacyjną bazą danych, ANSI ustandaryzowało język o nazwie SQL (Ustrukturyzowany język zapytań ). Oświadczenie napisane w tym języku może służyć zarówno do definiowania danych, jak i do manipulowania nimi. Ale problem SQL w kontaktach z Javą polega na tym, że mają niedopasowaną strukturę składniową i bardzo różnią się w rdzeniu, co oznacza, że ​​SQL jest proceduralny, podczas gdy Java jest zorientowana obiektowo. Poszukuje się więc działającego rozwiązania, aby Java mogła mówić w sposób obiektowy, a relacyjna baza danych nadal byłaby w stanie zrozumieć się nawzajem. JPA jest odpowiedzią na to wezwanie i zapewnia mechanizm do ustanowienia działającego rozwiązania między nimi.

Związek z mapowaniem obiektów

Programy Java współdziałają z relacyjnymi bazami danych za pomocą JDBC (Połączenie z bazą danych Java ) API. Sterownik JDBC jest kluczem do łączności i umożliwia programowi Java manipulowanie tą bazą danych za pomocą interfejsu API JDBC. Po nawiązaniu połączenia program Java uruchamia zapytania SQL w postaci String s do komunikacji tworzenia, wstawiania, aktualizowania i usuwania operacji. Jest to wystarczające do wszystkich praktycznych celów, ale niewygodne z punktu widzenia programisty Java. Co by było, gdyby strukturę tabel relacyjnych można było przemodelować do postaci czystych klas Javy, a następnie można by sobie z nimi poradzić w zwykły sposób obiektowy? Struktura tabeli relacyjnej jest logiczną reprezentacją danych w formie tabelarycznej. Tabele składają się z kolumn opisujących atrybuty encji, a wiersze są zbiorami encji. Na przykład tabela PRACOWNIK może zawierać następujące jednostki wraz z ich atrybutami.

Emp_number Nazwa nr_działu Wynagrodzenie Miejsce
112233 Piotr 123 1200 LA
112244 Promień 234 1300 NY
112255 Piaskowanie 123 1400 NJ
112266 Kalpana 234 1100 LA

Wiersze są unikatowe według klucza podstawowego (emp_number) w tabeli; umożliwia to szybkie wyszukiwanie. Tabela może być powiązana z jedną lub kilkoma tabelami za pomocą jakiegoś klucza, takiego jak klucz obcy (dept_no), który odnosi się do równoważnego wiersza w innej tabeli.

Zgodnie ze specyfikacją Java Persistence 2.1, JPA dodaje obsługę generowania schematów, metod konwersji typów, użycia grafu encji w zapytaniach i operacji wyszukiwania, niezsynchronizowanego kontekstu trwałości, wywoływania procedur składowanych i wstrzykiwania do klas nasłuchiwania encji. Zawiera również ulepszenia języka zapytań Java Persistence, Criteria API oraz mapowanie zapytań natywnych.

Krótko mówiąc, robi wszystko, aby stworzyć iluzję, że nie ma części proceduralnej w kontaktach z relacyjnymi bazami danych i wszystko jest zorientowane obiektowo.

Wdrożenie JPA

JPA opisuje zarządzanie danymi relacyjnymi w aplikacji Java. Jest to specyfikacja i istnieje wiele jej implementacji. Niektóre popularne implementacje to Hibernate, EclipseLink i Apache OpenJPA. JPA definiuje metadane za pomocą adnotacji w klasach Java lub za pomocą plików konfiguracyjnych XML. Jednak do opisania metadanych możemy użyć zarówno XML, jak i adnotacji. W takim przypadku konfiguracja XML zastępuje adnotacje. Jest to uzasadnione, ponieważ adnotacje są zapisywane w kodzie Java, podczas gdy pliki konfiguracyjne XML są zewnętrzne względem kodu Java. Dlatego później, jeśli w ogóle, należy wprowadzić zmiany w metadanych; w przypadku konfiguracji opartej na adnotacjach wymaga bezpośredniego dostępu do kodu Java. To zawsze może nie być możliwe. W takim przypadku możemy zapisać nową lub zmienioną konfigurację metadanych w pliku XML bez żadnej wskazówki co do zmian w oryginalnym kodzie i nadal przynosić pożądany efekt. To jest zaleta korzystania z konfiguracji XML. Jednak konfiguracja oparta na adnotacjach jest wygodniejsza w użyciu i jest popularnym wyborem wśród programistów.

  • Hibernacja jest popularną i najbardziej zaawansowaną spośród wszystkich implementacji JPA dzięki Red Hat. Wykorzystuje własne poprawki i dodatkowe funkcje, które mogą być używane oprócz implementacji JPA. Ma większą społeczność użytkowników i jest dobrze udokumentowany. Niektóre z dodatkowych własnościowych funkcji to obsługa wielu dzierżawców, dołączanie niepowiązanych jednostek w zapytaniach, zarządzanie znacznikami czasu i tak dalej.
  • EclipseLink jest oparty na TopLink i jest referencyjną implementacją wersji JPA. Zapewnia standardowe funkcje JPA oprócz kilku interesujących własnościowych funkcji, takich jak obsługa wielu dzierżawców, obsługa zdarzeń zmian w bazie danych i tak dalej.

Korzystanie z JPA w programie Java SE

Aby użyć JPA w programie Java, potrzebujesz dostawcy JPA, takiego jak Hibernate lub EclipseLink, lub dowolnej innej biblioteki. Potrzebny jest również sterownik JDBC, który łączy się z określoną relacyjną bazą danych. Na przykład w poniższym kodzie użyliśmy następujących bibliotek:

  • Dostawca: EclipseLink
  • Sterownik JDBC: Sterownik JDBC dla MySQL (złącze/J)

Ustalimy relację między dwiema tabelami — Pracownik i Dział — jako jeden do jednego i jeden do wielu, jak pokazano na poniższym diagramie EER (patrz Rysunek 1).


Rysunek 1: Relacje między tabelami

Pracownik tabela jest mapowana na klasę jednostki za pomocą adnotacji w następujący sposób:

package org.mano.jpademoapp;

import javax.persistence.*;

@Entity
@Table(name = "employee")
public class Employee {
   @Id
   private int id;
   private String name;
   private String phone;
   private String email;
   @OneToOne
   private Department department;
   public Employee() {
      super();
   }

   public Employee(int id, String name, String phone,
         String email) {
      super();
      this.id = id;
      this.name = name;
      this.phone = phone;
      this.email = email;
   }

   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public String getPhone() {
      return phone;
   }

   public void setPhone(String phone) {
      this.phone = phone;
   }

   public String getEmail() {
      return email;
   }

   public void setEmail(String email) {
      this.email = email;
   }

   public Department getDepartment() {
      return department;
   }

   public void setDepartment(Department department) {
      this.department = department;
   }
}

I departament tabela jest mapowana na klasę encji w następujący sposób:

package org.mano.jpademoapp;

import java.util.*;
import javax.persistence.*;

@Entity
@Table(name = "department")
public class Department {

   @Id
   private int id;
   private String location;
   @OneToMany
   private List<Employee> employees = new ArrayList<>();

   public Department() {
      super();
   }

   public Department(int id, String location) {
      super();
      this.id = id;
      this.location = location;
   }

   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public String getLocation() {
      return location;
   }

   public void setLocation(String location) {
      this.location = location;
   }

   public List<Employee> getEmployees() {
      return employees;
   }

   public void setEmployees(List<Employee> employees) {
      this.employees = employees;
   }
}

Plik konfiguracyjny persistence.xml , jest tworzony w META-INF informator. Ten plik zawiera konfigurację połączenia, taką jak używany sterownik JDBC, nazwa użytkownika i hasło dostępu do bazy danych oraz inne istotne informacje wymagane przez dostawcę JPA do nawiązania połączenia z bazą danych.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
   
   xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi_schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
   http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
   <persistence-unit name="JPADemoProject"
      transaction-type="RESOURCE_LOCAL">
      <class>org.mano.jpademoapp.Employee</class>
      <class>org.mano.jpademoapp.Department</class>
      <properties>
         <property name="javax.persistence.jdbc.driver"
            value="com.mysql.jdbc.Driver" />
         <property name="javax.persistence.jdbc.url"
            value="jdbc:mysql://localhost:3306/testdb" />
         <property name="javax.persistence.jdbc.user"
            value="root" />
         <property name="javax.persistence.jdbc.password"
            value="secret" />
         <property name="javax.persistence.schema-generation
            .database.action"
            value="drop-and-create"/>
         <property name="javax.persistence.schema-generation
            .scripts.action"
            value="drop-and-create"/>
         <property name="eclipselink.ddl-generation"
            value="drop-and-create-tables"/>
      </properties>
   </persistence-unit>
</persistence>

Jednostki nie utrzymują się same. Logika musi być zastosowana do manipulowania jednostkami, aby zarządzać ich trwałym cyklem życia. EntityManager Interfejs udostępniany przez JPA pozwala aplikacji zarządzać i wyszukiwać encje w relacyjnej bazie danych. Tworzymy obiekt zapytania za pomocą EntityManager do komunikacji z bazą danych. Aby uzyskać EntityManager dla danej bazy danych użyjemy obiektu, który implementuje EntityManagerFactory berło. Jest statyczny o nazwie createEntityManagerFactory , w sekcji Wytrwałość klasa, która zwraca EntityManagerFactory dla jednostki trwałości określonej jako String argument. W poniższej podstawowej implementacji zaimplementowaliśmy logikę.

package org.mano.jpademoapp;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public enum PersistenceManager {
   INSTANCE;
   private EntityManagerFactory emf;

   private PersistenceManager() {
      emf=Persistence.createEntityManagerFactory("JPADemoProject");
   }

   public EntityManager getEntityManager() {
      return emf.createEntityManager();
   }

   public void close() {
      emf.close();
   }
}

Teraz jesteśmy gotowi do stworzenia głównego interfejsu aplikacji. Tutaj zaimplementowaliśmy tylko operację wstawiania ze względu na prostotę i ograniczenia przestrzeni.

package org.mano.jpademoapp;

import javax.persistence.EntityManager;

public class Main {

   public static void main(String[] args) {

      Department d1=new Department(11, "NY");
      Department d2=new Department(22, "LA");

      Employee e1=new Employee(111, "Peter",
         "9876543210", "[email protected]");
      Employee e2=new Employee(222, "Ronin",
         "993875630", "[email protected]");
      Employee e3=new Employee(333, "Kalpana",
         "9876927410", "[email protected]");
      Employee e4=new Employee(444, "Marc",
         "989374510", "[email protected]");
      Employee e5=new Employee(555, "Anik",
         "987738750", "[email protected]");
      d1.getEmployees().add(e1);
      d1.getEmployees().add(e3);
      d1.getEmployees().add(e4);
      d2.getEmployees().add(e2);
      d2.getEmployees().add(e5);

      EntityManager em=PersistenceManager
         .INSTANCE.getEntityManager();
      em.getTransaction().begin();
      em.persist(e1);
      em.persist(e2);
      em.persist(e3);
      em.persist(e4);
      em.persist(e5);
      em.persist(d1);
      em.persist(d2);
      em.getTransaction().commit();
      em.close();
      PersistenceManager.INSTANCE.close();
   }
}
Uwaga: Zapoznaj się z odpowiednią dokumentacją Java API, aby uzyskać szczegółowe informacje na temat interfejsów API używanych w poprzednim kodzie.

Wniosek

Jak powinno być oczywiste, podstawowa terminologia kontekstu JPA i Persistence jest obszerniejsza niż wgląd podany tutaj, ale rozpoczęcie od szybkiego przeglądu jest lepsze niż długi, zawiły, brudny kod i jego konceptualne szczegóły. Jeśli masz niewielkie doświadczenie w programowaniu w rdzeniu JDBC, bez wątpienia docenisz, jak JPA może ułatwić Ci życie. Stopniowo zagłębimy się w JPA w miarę rozwoju kolejnych artykułów.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Klonowanie baz danych za pomocą PSDatabaseClone

  2. KLUCZ OBCY SQL

  3. Ogłoszenie ogólnej dostępności SQL Secure 4.0

  4. Jak utworzyć dokument Excel z programu Java za pomocą Apache POI

  5. Naprawianie utraty danych za pomocą przesyłania dzienników z opóźnionym odzyskiwaniem