Apa itu JPA? Pengenalan API Ketekunan Java

Sebagai spesifikasi, Java Persistence API berkaitan dengan kegigihan , yang secara longgar berarti mekanisme mana objek Java melebihi proses aplikasi yang membuatnya. Tidak semua objek Java perlu bertahan, tetapi kebanyakan aplikasi tetap menjadi objek perniagaan utama. Spesifikasi JPA memungkinkan Anda menentukan objek mana yang harus bertahan, dan bagaimana objek tersebut harus bertahan dalam aplikasi Java Anda.

Dengan sendirinya, JPA bukanlah alat atau kerangka kerja; sebaliknya, ia menentukan sekumpulan konsep yang dapat dilaksanakan oleh alat atau kerangka apa pun. Walaupun model pemetaan objek-relasional (ORM) JPA pada asalnya didasarkan pada Hibernate, model itu telah berkembang. Begitu juga, sementara JPA pada awalnya dimaksudkan untuk digunakan dengan pangkalan data relasional / SQL, beberapa implementasi JPA telah diperluas untuk digunakan dengan toko data NoSQL. Rangka kerja popular yang menyokong JPA dengan NoSQL adalah EclipseLink, pelaksanaan rujukan untuk JPA 2.2.

JPA 2.2 di Jakarta EE

Java Persistence API pertama kali dirilis sebagai bagian dari spesifikasi EJB 3.0 (JSR 220) di Java EE 5. Sejak itu telah berkembang sebagai spesifikasi sendiri, dimulai dengan peluncuran JPA 2.0 di Java EE 6 (JSR 317). Pada penulisan ini, JPA 2.2 telah diadopsi untuk kelanjutan sebagai bagian dari Jakarta EE.

JPA dan Hibernate

Kerana sejarah mereka yang saling berkaitan, Hibernate dan JPA sering berpasangan. Namun, seperti spesifikasi Java Servlet, JPA telah menghasilkan banyak alat dan kerangka kerja yang serasi; Hibernate adalah salah satu daripadanya.

Dikembangkan oleh Gavin King dan dikeluarkan pada awal tahun 2002, Hibernate adalah perpustakaan ORM untuk Java. King mengembangkan Hibernate sebagai alternatif untuk kacang entiti untuk kegigihan. Kerangka ini sangat popular, dan sangat diperlukan pada masa itu, sehingga banyak ideanya diterima dan dikodifikasi dalam spesifikasi JPA pertama.

Hari ini, Hibernate ORM adalah salah satu pelaksanaan JPA yang paling matang, dan masih merupakan pilihan yang popular untuk ORM di Java. Hibernate ORM 5.3.8 (versi semasa penulisan ini) melaksanakan JPA 2.2. Selain itu, keluarga alat Hibernate telah berkembang untuk merangkumi alat popular seperti Hibernate Search, Hibernate Validator, dan Hibernate OGM, yang menyokong ketekunan model domain untuk NoSQL.

JPA dan EJB

Seperti yang dinyatakan sebelumnya, JPA diperkenalkan sebagai subset EJB 3.0, tetapi sejak itu berkembang sebagai spesifikasinya sendiri. EJB adalah spesifikasi dengan fokus yang berbeza dari JPA, dan dilaksanakan dalam wadah EJB. Setiap bekas EJB merangkumi lapisan ketekunan, yang ditentukan oleh spesifikasi JPA.

Apa itu Java ORM?

Walaupun mereka berbeza dalam pelaksanaan, setiap pelaksanaan JPA memberikan semacam lapisan ORM. Untuk memahami alat yang sesuai dengan JPA dan JPA, anda perlu memahami ORM dengan baik.

Pemetaan objek-relasional adalah tugas –satu yang pembangun mempunyai alasan yang baik untuk mengelakkannya dilakukan secara manual. Rangka kerja seperti Hibernate ORM atau EclipseLink mengkodifikasikan tugas itu ke perpustakaan atau kerangka kerja, lapisan ORM . Sebagai sebahagian daripada seni bina aplikasi, lapisan ORM bertanggungjawab untuk mengatur penukaran objek perisian untuk berinteraksi dengan jadual dan lajur dalam pangkalan data hubungan. Di Java, lapisan ORM mengubah kelas dan objek Java sehingga dapat disimpan dan dikendalikan dalam pangkalan data relasional.

Secara lalai, nama objek yang dikekalkan menjadi nama jadual, dan bidang menjadi lajur. Setelah meja disiapkan, setiap baris tabel sesuai dengan objek dalam aplikasi. Pemetaan objek boleh dikonfigurasi, tetapi lalai cenderung berfungsi dengan baik.

JPA dengan NoSQL

Sehingga baru-baru ini, pangkalan data bukan hubungan adalah rasa ingin tahu yang tidak biasa. Pergerakan NoSQL mengubah semua itu, dan sekarang berbagai pangkalan data NoSQL tersedia untuk pengembang Java. Beberapa pelaksanaan JPA telah berkembang untuk merangkul NoSQL, termasuk Hibernate OGM dan EclipseLink.

Rajah 1 menggambarkan peranan JPA dan lapisan ORM dalam pembangunan aplikasi.

JavaWorld /

Mengkonfigurasi lapisan Java ORM

Semasa anda membuat projek baru untuk menggunakan JPA, anda perlu mengkonfigurasi penyimpanan data dan penyedia JPA. Anda akan mengkonfigurasi penyambung penyimpanan data untuk menyambung ke pangkalan data pilihan anda (SQL atau NoSQL). Anda juga akan memasukkan dan mengkonfigurasi penyedia JPA , yang merupakan kerangka seperti Hibernate atau EclipseLink. Walaupun anda dapat mengkonfigurasi JPA secara manual, banyak pembangun memilih untuk menggunakan sokongan Spring yang tidak ada. Lihat " Pemasangan dan penyediaan JPA " di bawah untuk demonstrasi pemasangan dan penyediaan JPA manual dan Spring.

Objek Data Java

Objek Data Java adalah kerangka ketekunan standard yang berbeza dari JPA terutamanya dengan menyokong logik kegigihan dalam objek, dan oleh sokongannya yang lama untuk bekerja dengan penyimpanan data yang tidak berkaitan. JPA dan JDO cukup serupa sehingga penyedia JDO juga sering menyokong JPA. Lihat Projek JDO Apache untuk mengetahui lebih lanjut mengenai JDO berhubung dengan standard ketekunan lain seperti JPA dan JDBC.

Ketekunan data di Jawa

Dari perspektif pengaturcaraan, lapisan ORM adalah lapisan penyesuai : ia menyesuaikan bahasa grafik objek dengan bahasa SQL dan jadual hubungan. Lapisan ORM membolehkan pemaju berorientasikan objek untuk membina perisian yang berterusan data tanpa meninggalkan paradigma berorientasikan objek.

Apabila anda menggunakan JPA, anda membuat peta dari datastore ke objek model data aplikasi anda. Daripada menentukan bagaimana objek disimpan dan diambil, anda menentukan pemetaan antara objek dan pangkalan data anda, kemudian meminta JPA untuk meneruskannya. Sekiranya anda menggunakan pangkalan data hubungan, sebahagian besar hubungan sebenar antara kod aplikasi dan pangkalan data anda akan dikendalikan oleh JDBC, Java Database Connectivity API.

Sebagai spesifikasi, JPA menyediakan anotasi metadata , yang Anda gunakan untuk menentukan pemetaan antara objek dan pangkalan data. Setiap pelaksanaan JPA menyediakan enjinnya sendiri untuk anotasi JPA. Spesifikasi JPA juga menyediakan PersistanceManageratau EntityManager, yang merupakan titik kontak utama dengan sistem JPA (di mana kod logik perniagaan anda memberitahu sistem apa yang harus dilakukan dengan objek yang dipetakan).

Untuk membuat semua ini lebih konkrit, pertimbangkan Penyenaraian 1, yang merupakan kelas data mudah untuk memodelkan pemuzik.

Penyenaraian 1. Kelas data sederhana di Jawa

 public class Musician { private Long id; private String name; private Instrument mainInstrument; private ArrayList performances = new ArrayList(); public Musician( Long id, String name){ /* constructor setters... */ } public void setName(String name){ this.name = name; } public String getName(){ return this.name; } public void setMainInstrument(Instrument instr){ this.instrument = instr; } public Instrument getMainInstrument(){ return this.instrument; } // ...Other getters and setters... } 

The Musiciankelas di dalam Senarai 1 digunakan untuk data ditahan. Ia boleh mengandungi data primitif seperti bidang nama . Ia juga dapat menjalin hubungan dengan kelas lain seperti mainInstrumentdan performances.

Musician's reason for being is to contain data. This type of class is sometimes known as a DTO, or data transfer object. DTOs are a common feature of software development. While they hold many kinds of data, they do not contain any business logic. Persisting data objects is a ubiquitous challenge in software development.

Data persistence with JDBC

One way to save an instance of the Musician class to a relational database would be to use the JDBC library. JDBC is a layer of abstraction that lets an application issue SQL commands without thinking about the underlying database implementation.

Listing 2 shows how you could persist the Musician class using JDBC.

Listing 2. JDBC inserting a record

 Musician georgeHarrison = new Musician(0, "George Harrison"); String myDriver = "org.gjt.mm.mysql.Driver"; String myUrl = "jdbc:mysql://localhost/test"; Class.forName(myDriver); Connection conn = DriverManager.getConnection(myUrl, "root", ""); String query = " insert into users (id, name) values (?, ?)"; PreparedStatement preparedStmt = conn.prepareStatement(query); preparedStmt.setInt (1, 0); preparedStmt.setString (2, "George Harrison"); preparedStmt.setString (2, "Rubble"); preparedStmt.execute(); conn.close(); // Error handling removed for brevity 

The code in Listing 2 is fairly self-documenting. The georgeHarrison object could come from anywhere (front-end submit, external service, etc.), and has its ID and name fields set. The fields on the object are then used to supply the values of an SQL insert statement. (The PreparedStatement class is part of JDBC, offering a way to safely apply values to an SQL query.)

While JDBC allows the control that comes with manual configuration, it is cumbersome compared to JPA. In order to modify the database, you first need to create an SQL query that maps from your Java object to the tables in a relational database. You then have to modify the SQL whenever an object signature change. With JDBC, maintaining the SQL becomes a task in itself.

Data persistence with JPA

Now consider Listing 3, where we persist the Musician class using JPA.

Listing 3. Persisting George Harrison with JPA

 Musician georgeHarrison = new Musician(0, "George Harrison"); musicianManager.save(georgeHarrison); 

Listing 3 replaces the manual SQL from Listing 2 with a single line, session.save(), which instructs JPA to persist the object. From then on, the SQL conversion is handled by the framework, so you never have to leave the object-oriented paradigm.

Metadata annotations in JPA

The magic in Listing 3 is the result of a configuration, which is created using JPA's annotations. Developers use annotations to inform JPA which objects should be persisted, and how they should be persisted.

Listing 4 shows the Musician class with a single JPA annotation.

Listing 4. JPA's @Entity annotation

 @Entity public class Musician { // ..class body } 

Persistent objects are sometimes called entities. Attaching @Entity to a class like Musician informs JPA that this class and its objects should be persisted.

XML vs. annotation-based configuration

JPA also supports using external XML files, instead of annotations, to define class metadata. But why would you do that to yourself?

Configuring JPA

Like most modern frameworks, JPA embraces coding by convention (also known as convention over configuration), in which the framework provides a default configuration based on industry best practices. As one example, a class named Musician would be mapped by default to a database table called Musician.

The conventional configuration is a timesaver, and in many cases it works well enough. It is also possible to customize your JPA configuration. As an example, you could use JPA's @Table annotation to specify the table where the Musician class should be stored.

Listing 5. JPA's @Table annotation

 @Entity @Table(name="musician") public class Musician { // ..class body } 

Listing 5 tells JPA to persist the entity (Musician class) to the musician table.

Primary key

In JPA, the primary key is the field used to uniquely identify each object in the database. The primary key is useful for referencing and relating objects to other entities. Whenever you store an object in a table, you will also specify the field to use as its primary key.

In Listing 6, we tell JPA what field to use as Musician's primary key.

Listing 6. Specifying the primary key

 @Entity public class Musician { @Id private Long id; 

In this case, we've used JPA's @Id annotation to specify the id field as Musician's primary key. By default, this configuration assumes the primary key will be set by the database--for instance, when the field is set to auto-increment on the table.

JPA supports other strategies for generating an object's primary key. It also has annotations for changing individual field names. In general, JPA is flexible enough to adapt to any persistence mapping you might need.

CRUD operations

Once you've mapped a class to a database table and established its primary key, you have everything you need to create, retrieve, delete, and update that class in the database. Calling session.save() will create or update the specified class, depending on whether the primary-key field is null or applies to en existing entity. Calling entityManager.remove() will delete the specified class.

Entity relationships in JPA

Simply persisting an object with a primitive field is only half the equation. JPA also has the capability to manage entities in relation to one another. Four kinds of entity relationships are possible in both tables and objects:

    1. One-to-many
    2. Many-to-one
    3. Many-to-many
    4. One-to-one

Each type of relationship describes how an entity relates to other entities. For example, the Musician entity could have a one-to-many relationship with Performance, an entity represented by a collection such as List or Set.

If the Musician included a Band field, the relationship between these entities could be many-to-one, implying collection of Musicians on the single Band class. (Assuming each musician only performs in a single band.)

If Musician included a BandMates field, that could represent a many-to-many relationship with other Musician entities.

Akhir sekali, Musicianmungkin mempunyai hubungan satu-sama-satu dengan Quoteentiti, digunakan untuk mewakili quote terkenal: Quote famousQuote = new Quote().

Menentukan jenis hubungan

JPA mempunyai anotasi untuk setiap jenis pemetaan hubungannya. Penyenaraian 7 menunjukkan bagaimana anda dapat memberi penjelasan mengenai hubungan satu-ke-banyak antara Musiciandan Performances.

Penyenaraian 7. Menggambarkan hubungan satu-ke-banyak