Episode ini membahas akses database di Java: JDBC dasar dengan koneksi, statement, dan result set, connection pooling dan resource cleanup, pengenalan JPA dan Hibernate sebagai ORM modern, entity mapping, repository pattern, dan transaction management.

Hampir semua aplikasi produksi menyimpan data di database. Episode 10 membahas database access dan persistence di Java — dimulai dari JDBC sebagai fondasi, lalu naik ke JPA dan Hibernate sebagai ORM modern. Kalian akan memahami dua level: kontrol penuh dan produktivitas tinggi.
JDBC (Java Database Connectivity) adalah API standar untuk akses database relasional. Tambahkan driver database yang sesuai — misalnya PostgreSQL:
mvn dependency:get -Dartifact=org.postgresql:postgresql:42.7.4Buka koneksi dengan DriverManager, lalu jalankan query dengan Statement:
import java.sql.*;
public class DemoJdbc {
public static void main(String[] args) throws SQLException {
String url = "jdbc:postgresql://localhost:5432/toko";
try (Connection conn = DriverManager.getConnection(url, "user", "password");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, nama FROM produk")) {
while (rs.next()) {
System.out.println(rs.getLong("id") + " - " + rs.getString("nama"));
}
}
}
}DriverManager.getConnection(url, "user", "password") membuka koneksi. Try-with-resources menutup koneksi, statement, dan result set secara otomatis.
Gunakan PreparedStatement untuk query berparameter — ini mencegah SQL injection:
String sql = "SELECT * FROM produk WHERE harga > ?";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setDouble(1, 50000);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getString("nama"));
}
}
}Membuka koneksi database untuk setiap query sangat mahal. Connection pooling menyimpan kumpulan koneksi yang dipakai ulang. HikariCP adalah pool paling populer dan default di Spring Boot:
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
public class Pool {
public static void main(String[] args) {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:postgresql://localhost:5432/toko");
config.setUsername("user");
config.setPassword("password");
config.setMaximumPoolSize(10);
HikariDataSource ds = new HikariDataSource(config);
System.out.println("Pool siap dengan " + ds.getMaximumPoolSize() + " koneksi");
}
}Aturan emas: tutup dalam urutan terbalik — ResultSet, lalu Statement, lalu Connection. Dengan try-with-resources, hal ini ditangani otomatis. Jangan pernah membocorkan koneksi; pool yang habis membuat aplikasi terlihat hang.
JPA (Jakarta Persistence API) adalah spesifikasi ORM (Object-Relational Mapping). Hibernate adalah implementasi JPA yang paling populer. Dengan ORM, kalian memetakan tabel database ke objek Java sehingga tidak menulis SQL manual.
Menambahkan Hibernate dan driver:
mvn dependency:get -Dartifact=org.hibernate.orm:hibernate-core:6.5.2.FinalEntity adalah class yang dipetakan ke tabel. Gunakan anotasi @Entity, @Table, @Id, dan @GeneratedValue:
import jakarta.persistence.*;
@Entity
@Table(name = "produk")
public class Produk {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String nama;
private double harga;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getNama() { return nama; }
public void setNama(String nama) { this.nama = nama; }
public double getHarga() { return harga; }
public void setHarga(double harga) { this.harga = harga; }
}@GeneratedValue(strategy = GenerationType.IDENTITY) membuat id di-generate otomatis oleh database.
Repository pattern mengabstraksi akses data menjadi interface yang bersih. Dalam Spring Data JPA, repository disediakan secara otomatis:
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ProdukRepository extends JpaRepository<Produk, Long> {
List<Produk> findByHargaGreaterThan(double harga);
}Method findByHargaGreaterThan diimplementasikan otomatis berdasarkan penamaan.
Transaction memastikan sekelompok operasi database berjalan atomik — semua berhasil atau semuanya dibatalkan. Anotasi @Transactional mengelompokkan operasi:
import org.springframework.transaction.annotation.Transactional;
public class TransferService {
@Transactional
public void transfer(Long dariId, Long keId, double jumlah) {
// kurangi saldo dariId
// tambah saldo keId
// jika satu gagal, keduanya dibatalkan
}
}@Transactional menjamin rollback otomatis saat terjadi exception, menjaga konsistensi data.
Episode 10 mengajarkan akses database: JDBC dengan koneksi, statement, dan result set, connection pooling dengan HikariCP, JPA dan Hibernate sebagai ORM, entity mapping dengan anotasi, repository pattern, serta transaction management dengan @Transactional.
Inti yang harus dibawa pulang:
PreparedStatement mencegah SQL injection pada query berparameter.@Entity, @Id, dan @GeneratedValue.@Transactional menjamin operasi database berjalan atomik.Di episode 11 selanjutnya kita akan membahas konfigurasi dan environment variables — konfigurasi aplikasi dengan file properties, YAML, dan environment variable, penggunaan java.util.Properties dan library modern, penanganan konfigurasi multiple environment, serta best practice menyimpan secret dan kredensial. Saatnya membuat aplikasi yang mudah dikonfigurasi!