@SpringBootApplication adalah salah satu anotasi inti di Spring Boot yang berfungsi untuk mengatur konfigurasi utama aplikasi. Ini adalah anotasi kombinasi yang menyatukan tiga anotasi penting lainnya:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
@RestController adalah anotasi yang digunakan di Spring untuk membuat kelas menjadi controller berbasis RESTful. Ini adalah kombinasi dari dua anotasi:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyRestController {
@GetMapping("/hello")
public String sayHello() {
return "Hello, World!";
}
}
Dengan @RestController, Anda dapat dengan mudah membangun layanan web RESTful tanpa harus secara eksplisit menyebutkan @ResponseBody di setiap metode.
@RequestMapping adalah anotasi di Spring yang digunakan untuk memetakan permintaan HTTP ke metode atau kelas tertentu dalam aplikasi. Anotasi ini sangat fleksibel dan mendukung berbagai atribut untuk menangani URL, metode HTTP, header, parameter, dan lainnya. Anda dapat menggunakan @RequestMapping di tingkat kelas atau tingkat metode.
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class MyController {
// Memetakan permintaan GET ke /api/hello
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String sayHello() {
return "Hello, World!";
}
// Memetakan permintaan POST ke /api/greet
@RequestMapping(value = "/greet", method = RequestMethod.POST)
public String greet() {
return "Greetings!";
}
}
Tingkat Kelas:
Tingkat Metode:
Fitur Tambahan:
Meskipun @RequestMapping sangat fleksibel, dalam praktik modern Spring (Spring 4.3 ke atas), Anda lebih sering melihat anotasi yang lebih spesifik seperti:
Anotasi @GetMapping, @PostMapping, @PutMapping, dan @DeleteMapping adalah bagian dari Spring Framework yang diperkenalkan pada Spring 4.3. Mereka digunakan untuk memetakan jenis permintaan HTTP (GET, POST, PUT, DELETE) ke metode tertentu dalam sebuah controller. Ini merupakan cara yang lebih ringkas dan intuitif dibandingkan dengan menggunakan @RequestMapping.
@GetMapping Digunakan untuk menangani permintaan HTTP GET, biasanya untuk mendapatkan data.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@GetMapping("/users")
public String getUsers() {
return "List of users";
}
}
@PostMapping Digunakan untuk menangani permintaan HTTP POST, biasanya untuk membuat data baru.
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@RestController
public class MyController {
@PostMapping("/users")
public String createUser(@RequestBody String user) {
return "User created: " + user;
}
}
@PutMapping Digunakan untuk menangani permintaan HTTP PUT, biasanya untuk memperbarui data yang sudah ada.
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
@RestController
public class MyController {
@PutMapping("/users/{id}")
public String updateUser(@RequestBody String user, @PathVariable String id) {
return "User updated with ID " + id + ": " + user;
}
}
@DeleteMapping Digunakan untuk menangani permintaan HTTP DELETE, biasanya untuk menghapus data.
import org.springframework.web.bind.annotation.DeleteMapping;
@RestController
public class MyController {
@DeleteMapping("/users/{id}")
public String deleteUser(@PathVariable String id) {
return "User with ID " + id + " deleted";
}
}
Dengan menggunakan anotasi ini, kode Anda menjadi lebih bersih dan lebih mudah dipahami.
@Autowired adalah anotasi di Spring Framework yang digunakan untuk menyuntikkan (inject) dependency secara otomatis ke dalam sebuah bean. Dengan menggunakan anotasi ini, Spring akan secara otomatis mencari dan menyuntikkan bean yang sesuai ke dalam properti, konstruktor, atau metode setter, sehingga mempermudah proses Dependency Injection (DI).
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyService {
public void serve() {
System.out.println("Service is running...");
}
}
@Component
public class MyController {
@Autowired
private MyService myService;
public void process() {
myService.serve();
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyController {
private final MyService myService;
@Autowired
public MyController(MyService myService) {
this.myService = myService;
}
public void process() {
myService.serve();
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyController {
private MyService myService;
@Autowired
public void setMyService(MyService myService) {
this.myService = myService;
}
public void process() {
myService.serve();
}
}
Anotasi @Service di Spring adalah bagian dari anotasi berbasis stereotype yang digunakan untuk menandai sebuah kelas sebagai komponen layanan (service layer). Dengan menambahkan anotasi ini, Spring secara otomatis mendaftarkan kelas tersebut sebagai bean dalam konteks aplikasi, sehingga dapat digunakan dengan fitur seperti Dependency Injection.
Fungsi :
import org.springframework.stereotype.Service;
@Service
public class MyService {
public String getServiceMessage() {
return "This is a service message!";
}
}
Contoh penggunaan dalam controller:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@Autowired
private MyService myService;
@GetMapping("/message")
public String getMessage() {
return myService.getServiceMessage();
}
}
Perbedaan dengan @Component
@Service pada dasarnya adalah turunan dari @Component. Secara teknis, keduanya berfungsi sama dalam hal registrasi bean, tetapi @Service memberikan semantik tambahan bahwa kelas tersebut adalah bagian dari logika bisnis.
Anotasi @Repository di Spring digunakan untuk menandai sebuah kelas sebagai komponen yang berperan sebagai repository, yaitu tempat logika akses data didefinisikan. Dengan menambahkan anotasi ini, Spring akan mengenali kelas tersebut sebagai bean dan memungkinkan penerapan fitur seperti translasi otomatis pengecualian basis data dengan Spring Data Access Exception.
Fungsi @Repository
import org.springframework.stereotype.Repository;
@Repository
public class MyRepository {
public String getDataFromDatabase() {
// Logika untuk mengakses basis data
return "Data dari database";
}
}
Ketika menggunakan Spring Data JPA, Anda sering tidak perlu mendefinisikan implementasi langsung karena Spring dapat secara otomatis menghasilkan metode CRUD. Contoh:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository {
// Tidak perlu implementasi manual untuk operasi CRUD standar
User findByUsername(String username); // Contoh query khusus
}
Perbedaan dengan @Service dan @Component:
Anotasi @Component di Spring Boot digunakan untuk mendeklarasikan sebuah kelas sebagai Spring Bean. Dengan menambahkan anotasi ini, Spring secara otomatis akan mendeteksi kelas tersebut selama proses component scanning dan mendaftarkannya dalam ApplicationContext. Ini memungkinkan kelas tersebut di-inject ke dalam komponen lain menggunakan mekanisme Dependency Injection (DI).
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
public String getMessage() {
return "Hello from MyComponent!";
}
}
Dengan anotasi @Component, kelas MyComponent akan dikenali oleh Spring dan didaftarkan sebagai bean. Anda bisa menyuntikkan MyComponent ke dalam kelas lain menggunakan @Autowired:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyService {
@Autowired
private MyComponent myComponent;
public void printMessage() {
System.out.println(myComponent.getMessage());
}
}
Perbedaan dengan Anotasi Lain:
Anotasi @Component memberikan dasar untuk semua anotasi stereotype lainnya, menjadikannya fleksibel untuk digunakan dalam berbagai skenario.
Anotasi @Configuration dalam Spring Boot digunakan untuk menunjukkan bahwa sebuah kelas adalah kelas konfigurasi yang mendefinisikan satu atau lebih bean yang akan dikelola oleh Spring IoC (Inversion of Control) container. Ini adalah bagian penting dari konfigurasi berbasis Java di Spring.
Fungsi Utama @Configuration
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
@Bean
public MyRepository myRepository() {
return new MyRepository();
}
}
class MyService {
public String serve() {
return "Service is serving!";
}
}
class MyRepository {
public String getData() {
return "Repository data retrieved!";
}
}
Anotasi @Bean di Spring Framework digunakan untuk mendefinisikan bean secara manual dalam konteks aplikasi. Bean ini akan dikelola oleh Spring IoC (Inversion of Control) container. Dengan @Bean, Anda dapat mendeklarasikan dan mengonfigurasi bean di dalam kelas konfigurasi yang biasanya ditandai dengan @Configuration.
Fungsi Utama @Bean
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
class MyService {
public void serve() {
System.out.println("Service is running...");
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
private final MyService myService;
@Autowired
public MyComponent(MyService myService) {
this.myService = myService;
}
public void execute() {
myService.serve();
}
}
Anotasi @EnableAutoConfiguration di Spring Boot adalah salah satu fitur inti yang memungkinkan Spring Boot untuk secara otomatis mengkonfigurasi aplikasi berdasarkan dependensi yang ada di classpath. Dengan anotasi ini, Spring Boot mencoba mengatur konfigurasi yang paling sesuai untuk aplikasi Anda, tanpa perlu membuat konfigurasi manual untuk setiap komponen.
Fungsi Utama
Secara umum, Anda tidak perlu menambahkan @EnableAutoConfiguration secara eksplisit, karena sudah termasuk dalam anotasi @SpringBootApplication:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Namun, jika Anda ingin menggunakan @EnableAutoConfiguration secara terpisah:
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
public class MyConfig {
// Konfigurasi tambahan jika diperlukan
}
Anotasi @Qualifier di Spring Boot digunakan untuk menyelesaikan konflik bean autowiring ketika ada lebih dari satu bean dengan tipe yang sama dalam konteks aplikasi. Dengan @Qualifier, Anda dapat menentukan secara eksplisit bean mana yang harus di-inject ke dalam dependensi, sehingga menghindari ambiguitas.
Mengapa Menggunakan @Qualifier?
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
public class MyController {
@Autowired
@Qualifier("myServiceA")
private MyService myService;
public void process() {
myService.serve();
}
}
@Component("myServiceA")
class MyServiceA implements MyService {
@Override
public void serve() {
System.out.println("Service A is running...");
}
}
@Component("myServiceB")
class MyServiceB implements MyService {
@Override
public void serve() {
System.out.println("Service B is running...");
}
}
interface MyService {
void serve();
}
@Autowired
public MyController(@Qualifier("myServiceA") MyService myService) {
this.myService = myService;
}
@Qualifier memberikan fleksibilitas untuk memilih bean tertentu dalam konteks aplikasi Spring, sehingga mempermudah pengelolaan aplikasi yang memiliki implementasi atau jenis bean yang sama.
Anotasi @Value di Spring Boot digunakan untuk menyuntikkan nilai ke dalam variabel atau properti dari sumber konfigurasi, seperti file application.properties, application.yml, atau bahkan variabel lingkungan. Dengan @Value, Anda dapat menyuntikkan nilai literal atau mengikat pengaturan aplikasi ke dalam bean Anda.
Fungsi Utama @Value
Contoh Pertama : Menyuntikkan Nilai Properti dari application.properties: Misalkan Anda memiliki properti berikut di file application.properties:
app.name=My Spring Boot Application
app.version=1.0.0
Anda dapat menggunakan @Value untuk menyuntikkan nilai:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppInfo {
@Value("${app.name}")
private String appName;
@Value("${app.version}")
private String appVersion;
public void printInfo() {
System.out.println("Application Name: " + appName);
System.out.println("Application Version: " + appVersion);
}
}
Contoh Ke-Dua : Menyuntikkan Nilai Default: Jika properti tidak ada di file konfigurasi, Anda bisa menetapkan nilai default menggunakan sintaks :defaultValue:
@Value("${app.description:Default description}")
private String appDescription;
Jika properti app.description tidak didefinisikan, maka variabel appDescription akan berisi “Default description”.
Contoh Ke-Tiga : Menyuntikkan Nilai dari Variabel Lingkungan: Anda bisa menyuntikkan variabel lingkungan seperti berikut:
@Value("${JAVA_HOME}")
private String javaHome;
Contoh Ke-Empat : Menggunakan Ekspresi SpEL: Anda juga dapat menyuntikkan nilai dengan ekspresi Spring:
@Value("#{5 + 10}")
private int result;
@Value("#{'Hello ' + 'World'}")
private String greeting;
Anotasi @Transactional di Spring digunakan untuk mengelola transaksi secara otomatis pada metode atau kelas. Dengan menggunakan anotasi ini, Anda dapat menentukan bahwa sebuah operasi (seperti operasi database) harus dieksekusi dalam kerangka transaksi, sehingga menjamin konsistensi data dan menangani skenario kegagalan dengan benar (melalui rollback).
Fungsi Utama @Transactional
Anotasi pada Metode:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class MyService {
@Transactional
public void performTransactionalOperation() {
// Operasi yang melibatkan banyak query ke database
saveData();
updateData();
// Jika terjadi exception di sini, semua perubahan sebelumnya akan di-rollback
}
private void saveData() {
// Logika penyimpanan data
}
private void updateData() {
// Logika pembaruan data
}
}
Anotasi pada Kelas:
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Service;
@Service
@Transactional
public class MyService {
public void saveData() {
// Logika penyimpanan data
}
public void updateData() {
// Logika pembaruan data
}
}
@Transactional(rollbackFor = Exception.class)
public void performOperation() {
// Logika operasi
}
Properti yang Dapat Dikonfigurasi:
Manfaat @Transactional:
Anotasi @ExceptionHandler di Spring digunakan untuk menangani pengecualian (exceptions) secara khusus dalam sebuah controller atau REST controller. Dengan menggunakan anotasi ini, Anda dapat menentukan metode yang akan dipanggil secara otomatis saat pengecualian tertentu terjadi selama pemrosesan permintaan.
Fungsi @ExceptionHandler
Menggunakan di dalam Controller:
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@GetMapping("/example")
public String example() {
// Mungkin terjadi exception
if (true) {
throw new IllegalArgumentException("Invalid argument provided!");
}
return "Success";
}
@ExceptionHandler(IllegalArgumentException.class)
public String handleIllegalArgument(IllegalArgumentException e) {
// Respons jika exception terjadi
return "Error: " + e.getMessage();
}
}
Penjelasan:
Menggunakan di Kelas Global Controller Advice: Untuk menangani pengecualian secara global (berlaku untuk seluruh controller), Anda bisa menggunakan anotasi @ControllerAdvice:
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public String handleIllegalArgument(IllegalArgumentException e) {
return "Global Error: " + e.getMessage();
}
@ExceptionHandler(Exception.class)
public String handleGenericException(Exception e) {
return "An unexpected error occurred: " + e.getMessage();
}
}
Penjelasan:
Urutan Prioritas:
Penerapan pada REST API:
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity handleIllegalArgument(IllegalArgumentException e) {
return new ResponseEntity<>("Error: " + e.getMessage(), HttpStatus.BAD_REQUEST);
}
Penanganan Berlapis:
@ExceptionHandler({IllegalArgumentException.class, NullPointerException.class})
public String handleMultipleExceptions(Exception e) {
return "Error: " + e.getMessage();
}
Menentukan bahwa kelas adalah suatu entitas. Anotasi ini dapat diterapkan pada Kelas, Interface dari Enums.
import javax.persistence.Entity;
@Entity
public class Employee implements Serializable {
}
Menentukan tabel dalam database yang digunakan untuk memetakan suatu entitas. Pada contoh di bawah, data akan disimpan di tabel employee. Atribut nama anotasi @Table digunakan untuk menentukan nama tabel.
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "employee")
public class Employee implements Serializable {
}
Anotasi ini menentukan nama kolom pada table.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "employee")
public class Employee implements Serializable {
@Column(name = "fullname")
private String employeeName;
}
Anotasi ini menentukan primary key dari sebuah entitas.
import javax.persistence.*;
@Entity
@Table(name = "employee")
public class Employee implements Serializable {
@Id
@Column(name = "id")
private Long id;
}
Anotasi @GeneratedValue digunakan untuk menentukan strategi pengisian nilai otomatis untuk kolom primary key (atau atribut ID) dalam entitas. Ini membantu memastikan bahwa setiap entitas memiliki nilai unik untuk primary key tanpa perlu memberikan nilai tersebut secara manual.
Ketika Anda menggunakan anotasi @GeneratedValue, Anda bisa menentukan strategi bagaimana nilai ID akan dihasilkan. Ada beberapa strategi yang didukung, yaitu:
@Entity
@Table(name = "employee")
public class Employee implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // Strategi IDENTITY
private Long id;
private String fullname;
// Getter dan Setter
}
Anotasi @Version digunakan untuk mendukung optimistic locking dalam aplikasi yang berinteraksi dengan database. Optimistic locking adalah mekanisme untuk mencegah konflik data selama operasi pembaruan atau penghapusan, terutama dalam lingkungan dengan banyak pengguna atau transaksi.
@Entity
@Table(name = "employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String fullname;
private double height;
@Version
private int version; // Menyimpan versi entitas
// Getter dan Setter
}
Dalam contoh di atas:
Keuntungan @Version:
Anotasi ini digunakan untuk menentukan urutan data berdaskan suatu kolom. Pada contoh di bawah ini, ini akan mengurutkan semua employee_addresses berdasarkan id mereka dalam urutan menaik
@OrderBy("id asc")
private Set employee_addresses;
Anotasi yang digunakan untuk menunjukkan bahwa suatu kolom atau bidang tidak perlu disimpan dalam database. Dengan kata lain, kolom atau bidang ini akan diabaikan saat operasi penyimpanan dan pengambilan entitas dari database
@Transient
Private int employeePhone;
Anotasi @Lob digunakan untuk menunjukkan bahwa atribut entitas yang dianotasi mewakili tipe objek besar (Large Object). LOB (Large Object) adalah tipe data variabel panjang yang digunakan untuk menyimpan objek besar seperti teks atau data biner. Ada dua jenis utama LOB:
@Entity
public class FileEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Lob
private byte[] data; // Menyimpan data biner sebagai BLOB
// Getter dan Setter
}
Anotasi @OneToOne digunakan untuk mendefinisikan hubungan satu-ke-satu (one-to-one) antara dua entitas. Artinya, setiap instance dari satu entitas hanya dapat berhubungan dengan satu instance dari entitas lain, dan sebaliknya.
Anotasi ini membantu Anda memetakan relasi yang erat antara dua tabel di database menjadi model objek dalam aplikasi. Hal ini umum digunakan dalam kasus seperti:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "profile_id", referencedColumnName = "id")
private Profile profile;
//Jika ingin menggunakan id yang sama
//@OneToOne(cascade = CascadeType.MERGE)
//@PrimaryKeyJoinColumn
//private Profile profile;
// Getter dan Setter
}
@Entity
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String bio;
private String avatar;
// Getter dan Setter
}
Penjelasan pada Contoh:
Keuntungan Menggunakan Relation:
Penggunaan @OneToMany dalam JPA membantu membangun hubungan “satu ke banyak” antara dua entitas dalam aplikasi Anda. Anotasi ini sangat berguna untuk memodelkan hubungan database yang kompleks dalam kode Java.
@Entity
public class Kelas {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nama;
@OneToMany(mappedBy = "kelas", cascade = CascadeType.ALL, orphanRemoval = true)
private List siswaList = new ArrayList<>();
// Getter, Setter, Constructor, dll.
}
@Entity
public class Siswa {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nama;
@ManyToOne
@JoinColumn(name = "kelas_id")
private Kelas kelas;
// Getter, Setter, Constructor, dll.
}
Anda juga dapat menggunakan JPQL atau Criteria API untuk melakukan query terhadap hubungan ini. Contoh sederhana:
List siswaList = entityManager
.createQuery("SELECT s FROM Siswa s WHERE s.kelas.id = :kelasId", Siswa.class)
.setParameter("kelasId", 1L)
.getResultList();
Anotasi @ManyToMany dalam JPA digunakan untuk mendefinisikan hubungan “banyak ke banyak” antara dua entitas. Hubungan ini terjadi ketika banyak entitas pada satu sisi terhubung dengan banyak entitas pada sisi lainnya. Contoh kasusnya adalah hubungan antara Mahasiswa dan MataKuliah, di mana seorang mahasiswa bisa mengambil banyak mata kuliah, dan satu mata kuliah bisa diikuti oleh banyak mahasiswa.
@Entity
public class Mahasiswa {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nama;
@ManyToMany
@JoinTable(
name = "mahasiswa_matakuliah",
joinColumns = @JoinColumn(name = "mahasiswa_id"),
inverseJoinColumns = @JoinColumn(name = "matakuliah_id")
)
private List mataKuliahList = new ArrayList<>();
// Getter, Setter, Constructor, dll.
}
@Entity
public class MataKuliah {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nama;
@ManyToMany(mappedBy = "mataKuliahList")
private List mahasiswaList = new ArrayList<>();
// Getter, Setter, Constructor, dll.
}
Digunakan untuk secara otomatis menghasilkan metode getter untuk semua atau beberapa bidang (fields) dalam sebuah kelas
import lombok.Getter;
@Getter
public class Person {
private String name;
private int age;
// Lombok akan otomatis membuat metode:
// public String getName() { return this.name; }
// public int getAge() { return this.age; }
}
import lombok.Getter;
public class Car {
@Getter
private String brand;
private int year; // Tidak memiliki getter karena tidak ada anotasi @Getter di bidang ini
}
Digunakan untuk secara otomatis menghasilkan metode setter untuk bidang (fields) dalam sebuah kelas. Untuk penggunaan sama seperti @Getter untuk menggernerate fungsi setField().
Digunakan untuk secara otomatis menghasilkan metode toString() untuk sebuah kelas. Metode ini memberikan representasi string dari objek, yang sangat berguna untuk debugging atau logging, tanpa harus menulis metode toString() secara manual.
import lombok.ToString;
@ToString
//@ToString(exclude = "age") => "Person(name=John)"
public class Person {
private String name;
private int age;
// Lombok akan menghasilkan metode:
// @Override
// public String toString() {
// return "Person(name=John, age=30)";
// }
}
Digunakan untuk secara otomatis menghasilkan metode equals() dan hashCode() untuk sebuah kelas. Metode ini penting untuk membandingkan objek berdasarkan nilai atribut mereka, dan juga berguna saat menggunakan koleksi seperti HashSet atau HashMap.
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class Person {
private String name;
private int age;
// Lombok akan menghasilkan metode:
// - equals(): membandingkan atribut 'name' dan 'age'
// - hashCode(): menghitung nilai hash berdasarkan 'name' dan 'age'
}
Digunakan untuk secara otomatis menghasilkan konstruktor yang mencakup semua bidang (fields) dalam sebuah kelas. Anotasi ini sangat berguna untuk menghindari penulisan kode boilerplate konstruktur secara manual, terutama pada kelas dengan banyak atribut.
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class Person {
private String name;
private int age;
// Lombok akan menghasilkan:
// public Person(String name, int age) {
// this.name = name;
// this.age = age;
// }
}
Digunakan untuk secara otomatis menghasilkan konstruktor tanpa parameter (no-args constructor) dalam sebuah kelas. Anotasi ini sangat membantu terutama untuk kelas dengan banyak bidang (fields), sehingga Anda tidak perlu menulis konstruktur tanpa parameter secara manual.
import lombok.NoArgsConstructor;
@NoArgsConstructor
public class Person {
private String name;
private int age;
// Lombok akan menghasilkan:
// public Person() {}
}
Digunakan untuk secara otomatis menghasilkan konstruktor dengan parameter untuk semua bidang yang bersifat final atau diberi anotasi @NonNull. Hal ini membantu memastikan bahwa atribut penting diinisialisasi selama pembuatan objek.
Ketika Anda menerapkan @RequiredArgsConstructor pada sebuah kelas, Lombok akan membuat konstruktor untuk semua bidang:
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class User {
private final String username;
@NonNull
private Integer age;
private String address; // Tidak termasuk dalam konstruktor
// Lombok akan menghasilkan:
// public User(String username, Integer age) {
// this.username = username;
// if (age == null) {
// throw new NullPointerException("age is marked non-null but is null");
// }
// this.age = age;
// }
}
Digunakan untuk memastikan bahwa nilai untuk suatu atribut atau parameter tidak boleh null. Jika ada upaya untuk menetapkan nilai null pada atribut atau parameter yang dianotasi dengan @NonNull, maka kode akan memunculkan NullPointerException secara otomatis. Anotasi ini sering digunakan untuk mencegah bug akibat nilai null
import lombok.NonNull;
public class Person {
@NonNull
private String name;
public Person(@NonNull String name) {
this.name = name; // Akan melempar NullPointerException jika name = null
}
}
Anotasi @Data dalam Lombok adalah solusi serbaguna yang menggabungkan beberapa anotasi Lombok lainnya untuk menghasilkan berbagai metode penting secara otomatis dalam sebuah kelas. Anotasi ini sangat ideal untuk membuat kelas sederhana seperti POJO (Plain Old Java Object), DTO (Data Transfer Object), atau model data.
Ketika Anda menggunakan @Data, Lombok akan menghasilkan:
import lombok.Data;
@Data
public class Person {
private String name;
private int age;
// Lombok akan otomatis menghasilkan metode:
// - public String getName()
// - public void setName(String name)
// - public int getAge()
// - public void setAge(int age)
// - public String toString()
// - public boolean equals(Object o)
// - public int hashCode()
// - public Person(String name, int age) [jika ada atribut final atau @NonNull]
}
Bidang final dan beranotasi @NonNull akan dipaksa untuk diinisialisasi melalui konstruktor:
import lombok.Data;
import lombok.NonNull;
@Data
public class Employee {
@NonNull
private String id;
private String name;
private final int age;
// Konstruktor akan dihasilkan untuk 'id' dan 'age', karena 'id' memiliki @NonNull dan 'age' bersifat final.
}
Lombok mendukung kombinasi @Data dengan anotasi lain seperti:
Digunakan untuk menciptakan kelas immutable (tidak dapat diubah) yang berfungsi sebagai objek nilai (value object). Semua atribut dalam kelas yang menggunakan @Value secara otomatis menjadi final, dan kelas itu sendiri bersifat final. Anotasi ini sangat ideal untuk membuat data model yang tetap dan konsisten.
Saat Anda menggunakan @Value, Lombok akan melakukan hal berikut:
import lombok.Value;
@Value
public class Person {
String name;
int age;
// Lombok akan menghasilkan:
// - Getter untuk 'name' dan 'age'
// - Konstruktor untuk menginisialisasi 'name' dan 'age'
// - toString(), equals(), dan hashCode()
// - Kelas bersifat final, dan semua bidang bersifat final
}
Anda dapat mengkombinasikan @Value dengan @Builder untuk menciptakan pola builder yang fleksibel sambil mempertahankan sifat immutable:
import lombok.Value;
import lombok.Builder;
@Value
@Builder
public class Employee {
String id;
String name;
int salary;
}
Dengan kombinasi ini, Anda dapat membuat objek menggunakan pendekatan builder:
Employee employee = Employee.builder()
.id("001")
.name("Alice")
.salary(5000)
.build();
Digunakan untuk mengimplementasikan pola builder pada kelas atau metode. Pola ini memungkinkan Anda membuat objek secara fleksibel, dengan menyusun parameter satu per satu. Ini sangat berguna saat Anda memiliki kelas dengan banyak atribut atau parameter opsional.
Ketika diterapkan pada kelas, Lombok akan membuatkan kelas builder secara otomatis untuk semua atribut dalam kelas tersebut. Berikut contoh sederhana:
import lombok.Builder;
@Builder
public class Person {
private String name;
private int age;
// Dengan @Builder, Anda dapat membuat objek seperti ini:
// Person person = Person.builder()
// .name("John")
// .age(30)
// .build();
}
Anda dapat mengkombinasikan @Builder dengan anotasi seperti @AllArgsConstructor atau @RequiredArgsConstructor untuk menyesuaikan bagaimana pola builder digunakan berdasarkan konstruktor Anda:
import lombok.Builder;
import lombok.AllArgsConstructor;
@Builder
@AllArgsConstructor
public class Employee {
private final String id;
private final String name;
private int salary;
// Employee emp = Employee.builder()
// .id("001")
// .name("Alice")
// .salary(5000)
// .build();
}
Anda juga dapat menggunakan @Builder di tingkat metode untuk membuat builder hanya untuk metode tertentu:
import lombok.Builder;
public class Calculation {
@Builder
public static String performOperation(String operand1, String operand2, String operator) {
return operand1 + " " + operator + " " + operand2;
}
// Pemanggilan:
// String result = Calculation.builder()
// .operand1("5")
// .operand2("3")
// .operator("+")
// .build();
}
Digunakan untuk mempermudah pengelolaan koleksi (collections) dalam pola builder. Dengan @Singular, Anda dapat menambahkan elemen ke dalam koleksi satu per satu atau menetapkan seluruh koleksi secara langsung saat membangun objek menggunakan builder.
import lombok.Builder;
import lombok.Singular;
@Builder
public class Team {
private String teamName;
@Singular
private List members;
}
// Membuat objek:
Team team = Team.builder()
.teamName("Development Team")
.member("Alice")
.member("Bob")
.member("Charlie")
.build();
// Hasilnya, koleksi `members` berisi ["Alice", "Bob", "Charlie"].
import lombok.Builder;
import lombok.Singular;
@Builder
public class Organization {
private String orgName;
@Singular
private Set departments;
}
// Membuat objek:
Organization org = Organization.builder()
.orgName("TechCorp")
.department("Engineering")
.department("Marketing")
.build();
import lombok.Builder;
import lombok.Singular;
@Builder
public class Configuration {
@Singular
private Map properties;
}
// Membuat objek:
Configuration config = Configuration.builder()
.property("key1", "value1")
.property("key2", "value2")
.build();