Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Integrating MyBatis with Spring Boot Applications

Tech May 15 1

Database Schema Setup

Create the user table with the following SQL definition:

CREATE TABLE `tb_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
  `username` varchar(50) NOT NULL COMMENT 'User Name',
  `age` int(11) NOT NULL COMMENT 'User Age',
  `ctm` datetime NOT NULL COMMENT 'Creation Timestamp',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `tb_user` (`username`, `age`, `ctm`) VALUES 
('John Doe', '25', NOW()),
('Jane Smith', '30', NOW());

Maven Dependencies Configuration

Configure the project's pom.xml with required dependencies:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>spring-mybatis-integration</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>
  
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.0</version>
  </parent>
  
  <dependencies>
    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.2.2</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.33</version>
    </dependency>
  </dependencies>
  
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

Application Properties Configuration

Define database connection and MyBatis settings in application.yml:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/user_database
    username: admin
    password: secret123

mybatis:
  mapper-locations: classpath:mapping/*.xml
  config-location: classpath:mybatis-config.xml
  type-aliases-package: com.example.model

MyBatis XML Mapping File

Create UserRepository.xml for SQL operations:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.repository.UserRepository">
  
  <resultMap id="UserMap" type="com.example.model.UserEntity">
    <id column="id" property="identifier" jdbcType="INTEGER" />
    <result column="username" property="name" jdbcType="VARCHAR" />
    <result column="age" property="userAge" jdbcType="INTEGER" />
    <result column="ctm" property="createdTime" jdbcType="TIMESTAMP" />
  </resultMap>
  
  <sql id="columns">id, username, age, ctm</sql>
  
  <select id="findAllUsers" resultMap="UserMap">
    SELECT <include refid="columns" /> FROM tb_user
  </select>
  
  <select id="findUserById" parameterType="int" resultMap="UserMap">
    SELECT <include refid="columns" /> FROM tb_user WHERE id = #{userId}
  </select>
  
  <insert id="createUser" parameterType="com.example.model.UserEntity">
    INSERT INTO tb_user (username, age, ctm) 
    VALUES (#{name}, #{userAge}, NOW())
  </insert>
  
  <update id="modifyUser" parameterType="map">
    UPDATE tb_user 
    SET username = #{userData.name}, age = #{userData.userAge} 
    WHERE id = #{identifier}
  </update>
  
  <delete id="removeUser" parameterType="int">
    DELETE FROM tb_user WHERE id = #{userId}
  </delete>
  
</mapper>

MyBatis Configuration File

Basic mybatis-config.xml setup:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
  
<configuration>
  <settings>
    <setting name="mapUnderscoreToCamelCase" value="true" />
  </settings>
  <typeAliases>
    <package name="com.example.model" />
  </typeAliases>
</configuration>

Data Model Class

Define the entity class in UserEntity.java:

package com.example.model;

import java.util.Date;

public class UserEntity {
  private Integer identifier;
  private String name;
  private Integer userAge;
  private Date createdTime;
  
  // Constructors
  public UserEntity() {}
  
  public UserEntity(String name, Integer userAge) {
    this.name = name;
    this.userAge = userAge;
  }
  
  // Getters and Setters
  public Integer getIdentifier() { return identifier; }
  public void setIdentifier(Integer identifier) { this.identifier = identifier; }
  
  public String getName() { return name; }
  public void setName(String name) { this.name = name; }
  
  public Integer getUserAge() { return userAge; }
  public void setUserAge(Integer userAge) { this.userAge = userAge; }
  
  public Date getCreatedTime() { return createdTime; }
  public void setCreatedTime(Date createdTime) { this.createdTime = createdTime; }
}

Repository Interface

Create the data access interface:

package com.example.repository;

import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.example.model.UserEntity;

@Repository
public interface UserRepository {
  UserEntity findUserById(Integer userId);
  List<UserEntity> findAllUsers();
  int createUser(UserEntity user);
  int modifyUser(@Param("identifier") Integer id, @Param("userData") UserEntity user);
  int removeUser(Integer userId);
}

Service Layer Implementation

Business logic service interfaces and implementation:

package com.example.service;

import java.util.List;
import com.example.model.UserEntity;

public interface UserManagementService {
  UserEntity retrieveUser(Integer id);
  List<UserEntity> getAllUsers();
  boolean registerUser(UserEntity user);
  boolean updateUserProfile(Integer id, UserEntity user);
  boolean deleteUserAccount(Integer id);
}
package com.example.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.model.UserEntity;
import com.example.repository.UserRepository;
import com.example.service.UserManagementService;

@Service
public class UserManagementServiceImpl implements UserManagementService {
  
  @Autowired
  private UserRepository userRepository;
  
  @Override
  public UserEntity retrieveUser(Integer id) {
    return userRepository.findUserById(id);
  }
  
  @Override
  public List<UserEntity> getAllUsers() {
    return userRepository.findAllUsers();
  }
  
  @Override
  public boolean registerUser(UserEntity user) {
    return userRepository.createUser(user) > 0;
  }
  
  @Override
  public boolean updateUserProfile(Integer id, UserEntity user) {
    return userRepository.modifyUser(id, user) > 0;
  }
  
  @Override
  public boolean deleteUserAccount(Integer id) {
    return userRepository.removeUser(id) > 0;
  }
}

REST Controller

Web layer for handling HTTP requsets:

package com.example.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.example.model.UserEntity;
import com.example.service.UserManagementService;
import com.example.util.ApiResponse;

@RestController
@RequestMapping("/api/users")
public class UserRestController {
  
  @Autowired
  private UserManagementService userService;
  
  @GetMapping("/{userId}")
  public ResponseEntity<ApiResponse> getUser(@PathVariable Integer userId) {
    ApiResponse response = new ApiResponse();
    try {
      UserEntity user = userService.retrieveUser(userId);
      response.setData(user);
      response.setMessage("Success");
      return ResponseEntity.ok(response);
    } catch (Exception ex) {
      response.setError(ex.getMessage());
      return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
    }
  }
}

Response Utility Class

Standard API response wrapper:

package com.example.util;

public class ApiResponse {
  private String message;
  private Object data;
  private String error;
  
  public String getMessage() { return message; }
  public void setMessage(String message) { this.message = message; }
  
  public Object getData() { return data; }
  public void setData(Object data) { this.data = data; }
  
  public String getError() { return error; }
  public void setError(String error) { this.error = error; }
}

Application Bootstrap Class

Main application entry point:

package com.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.repository")
public class ApplicationBootstrap {
  public static void main(String[] args) {
    SpringApplication.run(ApplicationBootstrap.class, args);
  }
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

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