Tutorial Belajar Spring Framework Part VI: Java Persistence API (JPA)

Setelah pada artikel sebelumnya kita telah membuat fungsi CRUD menggunakan spring JDBC. Sekarang kita akan membahas cara lain dalam mengakses database melalui aplikasi java berbasis spring boot yang kita gunakan. Kali ini kita akan membahas mengenai Object Relational Mapping(ORM). ORM merupakan sebuah teknik yang bertujuan untuk melakukan mapping antara object oriented data dengan relational data pada database(RDBMS). Konsep ORM bermula dari 5 masalah yang dihadapi saat aplikasi berbasis obejct oriented kita berhubungan dengan relational table pada database,

  • Granularity

Object model yang kita miliki biasanya lebih granular dari pada tabel pada database. Granular disini bisa kita artikan lebih banyak, jadi kita biasanya memiliki jumlah class lebih banyak dibandingkan tabel pada database.

class Outlet{
    private String nama;
    private Alamat alamat;

    //getter and setter
}
class Alamat{
    private String kecamatan;
    private String kabupaten;
    
    //getter and setter
}
Tabel Outlet
nama
kecamatan
kabupaten
  • Subtypes

Subtypes disini berarti inheritance, dimana inheritance merupakan sebuah hal yang wajar dalam paradigma object oriented namun tidak dengan relational database.

  • Identity

Dalam relational database, column primary key menjadi sebuah identitas unique untuk setiap record. Namun dalam object model untuk menemukan kesamaan sebuah object terdapat 2 cara yaitu dengan equality(equals) dan juga ‘==’ yang berarti 2 object merefrensikan pada object yang sama.

  • Assosiactions

Dalam object model kita mengenal adanya assosiasi, sebagai contoh

class Outlet{
    private String nama;
    private Alamat alamat;

    //getter and setter
}
class Alamat{
    private String kecamatan;
    private String kabupaten;

    //getter and setter
}

Kita bisa mengakses object alamat dari object outlet, namun kita tidak bisa melakukan sebaliknya. Berbeda dengan relasi tabel pada relational database kita akan menggunakan foreign key.

  • Data Navigation

Data navigation disini berarti perbedaan dalam cara mengakses data dalam object oriented dan relational database.

Dari 5 masalah itu maka muncul konsep Object Relational Mapping(ORM) untuk menyelesaikan permasalahan missmatch antara object dan tabel pada relational database. Lalu Java melalui Java Community Process mengadopsi konsep tersebut dan membuat standarisasi untuk ORM dan management persistence yang disebut dengan Java Persistence API (JPA). Persistence disini kita artikan secara sederhana dimana object data yang dihasilkan dari aplikasi kita tersedia dalam jangka waktu yang lama saat aplikasi sedang berjalan. Berdasarkan standarisasi JPA, object model pada aplikasi kita diwakilkan oleh entity. Entity merupakan sebuah class dimana nantinya class ini akan persisted dengan tabel yang ada pada relational database yang kita gunakan.

Sebagai contoh kita akan membuat 2 tabel pada database yaitu tabel departemen dan tabel karyawan,

CREATE DATABASE IF NOT EXISTS `belajar_spring_boot`;
USE `belajar_spring_boot`;

DROP TABLE IF EXISTS `departemen`;

CREATE TABLE `departemen` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nama` varchar(200) NOT NULL,
`kode` varchar(7) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3;

INSERT INTO `departemen` VALUES (1,'Teknologi Informasi','0000001'),(2,'Sales','0000002');

DROP TABLE IF EXISTS `karyawan`;

CREATE TABLE `karyawan` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nama` varchar(200) NOT NULL,
`tanggal_lahir` date NOT NULL,
`gaji` decimal(12,2) NOT NULL,
`departemen_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_karyawan_departemen_id_idx` (`departemen_id`),
CONSTRAINT `fk_karyawan_departemen_id` FOREIGN KEY (`departemen_id`) REFERENCES `departemen` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=4;

INSERT INTO `karyawan` VALUES (1,'Budi Luhur','1995-12-19',2000000.00,1),(2,'Sri Rejeki','1993-03-22',1500000.00,2),(3,'Yanti Widi','1991-10-03',3000000.00,2);

Setelah membuat 2 tabel pada database, sekarang kita buat 2 buah entity. Entity yang kita buat sesuai dengan tabel pada database yaitu entity Karyawan dan Departemen. Berikut contoh entitynya,

Entity Karyawan
package com.github.model;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "karyawan")
public class Karyawan implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;
    @Column(name = "nama")
    private String nama;
    @Column(name = "tanggal_lahir")
    @Temporal(TemporalType.DATE)
    private Date tanggalLahir;
    @Column(name = "gaji")
    private BigDecimal gaji;
    @JoinColumn(name = "departemen_id", referencedColumnName = "id")
    @ManyToOne
    private Departemen departemenId;

    public Karyawan() {
    }

    public Karyawan(Integer id) {
        this.id = id;
    }

    public Karyawan(Integer id, String nama, Date tanggalLahir, BigDecimal gaji) {
        this.id = id;
        this.nama = nama;
        this.tanggalLahir = tanggalLahir;
        this.gaji = gaji;
    }

    public Integer getId() {
        return id;
    }

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

    public String getNama() {
        return nama;
    }

    public void setNama(String nama) {
        this.nama = nama;
    }

    public Date getTanggalLahir() {
        return tanggalLahir;
    }

    public void setTanggalLahir(Date tanggalLahir) {
        this.tanggalLahir = tanggalLahir;
    }

    public BigDecimal getGaji() {
        return gaji;
    }

    public void setGaji(BigDecimal gaji) {
        this.gaji = gaji;
    }

    public Departemen getDepartemenId() {
        return departemenId;
    }

    public void setDepartemenId(Departemen departemenId) {
        this.departemenId = departemenId;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Karyawan)) {
            return false;
        }
        Karyawan other = (Karyawan) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.github.model.Karyawan[ id=" + id + " ]";
    }
    
}

Entity Departemen

package com.github.model;

import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "departemen")
public class Departemen implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;
    @Column(name = "nama")
    private String nama;
    @Column(name = "kode")
    private String kode;
    @OneToMany(mappedBy = "departemenId")
    private List<Karyawan> karyawanList;

    public Departemen() {
    }

    public Departemen(Integer id) {
        this.id = id;
    }

    public Departemen(Integer id, String nama, String kode) {
        this.id = id;
        this.nama = nama;
        this.kode = kode;
    }

    public Integer getId() {
        return id;
    }

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

    public String getNama() {
        return nama;
    }

    public void setNama(String nama) {
        this.nama = nama;
    }

    public String getKode() {
        return kode;
    }

    public void setKode(String kode) {
        this.kode = kode;
    }

    public List<Karyawan> getKaryawanList() {
        return karyawanList;
    }

    public void setKaryawanList(List<Karyawan> karyawanList) {
        this.karyawanList = karyawanList;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Departemen)) {
            return false;
        }
        Departemen other = (Departemen) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.github.model.Departemen[ id=" + id + " ]";
    }
    
}

Dapat kita lihat setiap column pada tabel di database kita buatkan propertynya pada entity. Ada beberapa annotation yang kita gunakan pada contoh diatas, kalau kita cermati semua annotation tersebut berasal dari package javax.persistence.*. Itu artinya kita membuat entity sesuai dengan spesifikasi dari JPA, tinggal nanti kita memilih JPA provider yang akan kita gunakan pada data access layer. Untuk lebih lengkap mengenai annotation yang bisa digunakan sesuai spesifikasi JPA bisa dilihat pada link berikut https://docs.oracle.com/javaee/7/api/javax/persistence/package-summary.html . Ada beberapa hal yang bisa kita pertimbangkan kenapa memilih menggunakan ORM dalam hal ini JPA dari pada menggunakan plain JDBC,

  • Menghindari boilerplate code
  • Mempermudah dalam mapping object model ke relational tabel pada database
  • Menghindari sql native
  • Flexibel (tidak terikat pada 1 vendor JPA provider)
  • Standart JavaEE

Untuk link source code bisa dilihat pada link github berikut https://github.com/leonardusdani/blog-tutorial-spring-framework/releases/tag/6.0

 

Advertisements

2 thoughts on “Tutorial Belajar Spring Framework Part VI: Java Persistence API (JPA)

  1. kak, mau tanya.. kak pernah buat paper tentang IMPLEMENTASI QUESTION ANSWERING SYSTEM BERDASARKAN PERTANYAAN FACTOID MENGGUNAKAN WORDNET BAHASA INDONESIA? boleh baca papernya kak?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s