Spring Boot Persistence with MyBatis

MyBatis is a lightweight SQL-mapping framweork that removes most JDBC boiler-plate while still giving full control over SQL. The following walkthrough shows how to integrate it into a Spring Boot project and perform common CRUD operations.

  1. Project bootstrap and data source configuration

  1. Create a new Spring Boot project with the spring-boot-starter-web, mysql-connector-j and mybatis-spring-boot-starter dependencies.
  2. Create the database schema and a matching Java entity. For example:
CREATE TABLE emp (
  id          INT AUTO_INCREMENT PRIMARY KEY,
  username    VARCHAR(20)  NOT NULL UNIQUE,
  password    VARCHAR(64)  NOT NULL,
  full_name   VARCHAR(50),
  gender      TINYINT,
  avatar_url  VARCHAR(255),
  job         TINYINT,
  hire_date   DATE,
  dept_id     INT,
  created_at  DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at  DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
    private Integer id;
    private String username;
    private String password;
    private String fullName;
    private Short gender;
    private String avatarUrl;
    private Short job;
    private LocalDate hireDate;
    private Integer deptId;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

Add the four mandatory connection parameters to application.properties:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=demo
spring.datasource.password=demo

To watch the generated SQL in the console, append:

mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
  1. Mapper interfaces and SQL annotations

Define a mapper interface and mark it with @Mapper. Method-level annotations such as @Select, @Insert, @Update and @Delete hold the SQL statements:

@Mapper
public interface EmployeeMapper {

    @Select("SELECT * FROM emp")
    List<Employee> findAll();

    @Select("SELECT * FROM emp WHERE id = #{id}")
    Optional<Employee> findById(Integer id);

    @Insert("INSERT INTO emp(username, password, full_name, gender, avatar_url, job, hire_date, dept_id) " +
            "VALUES(#{username}, #{password}, #{fullName}, #{gender}, #{avatarUrl}, #{job}, #{hireDate}, #{deptId})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(Employee e);

    @Update("UPDATE emp SET full_name = #{fullName}, gender = #{gender}, avatar_url = #{avatarUrl}, " +
            "job = #{job}, hire_date = #{hireDate}, dept_id = #{deptId}, updated_at = NOW() WHERE id = #{id}")
    int update(Employee e);

    @Delete("DELETE FROM emp WHERE id = #{id}")
    int delete(Integer id);
}

Spring Boot automatically creates a proxy implementation and registers it as a singleton bean, so you can inject the mapper anywhere:

@SpringBootTest
class EmployeeMapperTests {

    @Autowired
    EmployeeMapper mapper;

    @Test
    void shouldReturnAllRows() {
        List<Employee> list = mapper.findAll();
        assertThat(list).isNotEmpty();
    }
}
  1. Connection pooling

Spring Boot ships with HikariCP by default. If you prefer Alibaba’s Druid for its monitoring console, replace the starter:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.20</version>
</dependency>

No additional code changes are required.

  1. Lombok for POJOs

Instead of hand-writing constructors, getters, setters and toString, add Lombok to the classpath and annotate the entity with @Data, @NoArgsConstructor and @AllArgsConstructor as shown above. IntelliJ IDEA already bundles the required plugin.

  1. XML mapping alternative

If you prefer externalized SQL, place a file named EmployeeMapper.xml under src/main/resources/mapper:

<?xml version="1.0" encoding="UTF-8"?>

<mapper namespace="com.example.demo.mapper.EmployeeMapper">

    <select id="findAll" resultType="com.example.demo.entity.Employee">
        SELECT * FROM emp
    </select>

    <select id="findById" resultType="com.example.demo.entity.Employee">
        SELECT * FROM emp WHERE id = #{id}
    </select>

    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO emp(username, password, full_name, gender, avatar_url, job, hire_date, dept_id)
        VALUES(#{username}, #{password}, #{fullName}, #{gender}, #{avatarUrl}, #{job}, #{hireDate}, #{deptId})
    </insert>

</mapper>

Enable XML scanning in application.properties:

mybatis.mapper-locations=classpath:mapper/*.xml

With these pieces in place you have a fully working MyBatis layer ready for service and conrtoller integration.

Tags: MyBatis Spring Boot HikariCP druid Lombok

Posted on Wed, 20 May 2026 08:09:11 +0000 by AceE