Fading Coder

One Final Commit for the Last Sprint

Home > Notes > Content

Annotation-Driven CRUD Operations with MyBatis and Lombok

Notes 1

Lombok streamlines Java development by generating boilerplate code at compile time through annotations. To integrate it, add the following dependency:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>provided</scope>
</dependency>

Core annotations include @Getter and @Setter for property accessors, @ToString for debugging output, @EqualsAndHashCode for object comparison, and the composite @Data annotation which bundles all four. For constructor generation, @NoArgsConstructor creates empty constructors while @AllArgsConstructor generates ones initializing all instance fields.

Consider a traditional entity without Lombok:

package com.example.persistence.domain;

public class Product {
    private Long identifier;
    private String productCode;
    private Integer availableUnits;

    public Long getIdentifier() {
        return identifier;
    }

    public void setIdentifier(Long identifier) {
        this.identifier = identifier;
    }

    public String getProductCode() {
        return productCode;
    }

    public void setProductCode(String productCode) {
        this.productCode = productCode;
    }

    public Integer getAvailableUnits() {
        return availableUnits;
    }

    public void setAvailableUnits(Integer availableUnits) {
        this.availableUnits = availableUnits;
    }

    @Override
    public String toString() {
        return "Product{" +
                "identifier=" + identifier +
                ", productCode='" + productCode + '\'' +
                ", availableUnits=" + availableUnits +
                '}';
    }
}

Using Lombok annotations, this reduces to:

package com.example.persistence.domain;

import lombok.*;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product {
    private Long identifier;
    private String productCode;
    private Integer availableUnits;
}

To configure MyBatis connectivity, populate application.properties with you're database credentials:

spring.datasource.url=jdbc:mysql://localhost:3306/warehouse_db?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
spring.datasource.username=db_admin
spring.datasource.password=secure_pass
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

Define the repository interface using @Mapper too trigger MyBatis proxy generation:

package com.example.persistence.repository;

import com.example.persistence.domain.Product;
import org.apache.ibatis.annotations.*;
import java.util.List;

@Mapper
public interface ProductRepository {

    @Delete("DELETE FROM inventory WHERE item_id = #{itemId}")
    void removeById(Long itemId);

    @Select("SELECT * FROM inventory")
    List<Product> fetchAllItems();

    @Insert("INSERT INTO inventory(product_code, quantity) VALUES(#{productCode}, #{availableUnits})")
    @Options(useGeneratedKeys = true, keyProperty = "identifier")
    void persist(Product entity);

    @Update("UPDATE inventory SET product_code = #{productCode}, quantity = #{availableUnits} WHERE item_id = #{identifier}")
    void modify(Product entity);
}

Verify functionality through integration testing:

package com.example.persistence;

import com.example.persistence.domain.Product;
import com.example.persistence.repository.ProductRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;

@SpringBootTest
class PersistenceLayerTests {

    @Autowired
    private ProductRepository repository;

    @Test
    void verifyDeletion() {
        repository.removeById(6L);
    }

    @Test
    void verifyRetrieval() {
        List<Product> items = repository.fetchAllItems();
        items.forEach(System.out::println);
    }

    @Test
    void verifyInsertion() {
        Product newItem = new Product(null, "TECH-001", 100);
        repository.persist(newItem);
    }

    @Test
    void verifyUpdate() {
        Product existing = new Product(1L, "TECH-002", 50);
        repository.modify(existing);
    }
}

Related Articles

Designing Alertmanager Templates for Prometheus Notifications

How to craft Alertmanager templates to format alert messages, improving clarity and presentation. Alertmanager uses Go’s text/template engine with additional helper functions. Alerting rules referenc...

Deploying a Maven Web Application to Tomcat 9 Using the Tomcat Manager

Tomcat 9 does not provide a dedicated Maven plugin. The Tomcat Manager interface, however, is backward-compatible, so the Tomcat 7 Maven Plugin can be used to deploy to Tomcat 9. This guide shows two...

Skipping Errors in MySQL Asynchronous Replication

When a replica halts because the SQL thread encounters an error, you can resume replication by skipping the problematic event(s). Two common approaches are available. Methods to Skip Errors 1) Skip a...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.