Spring Boot Integration with MyBatis-Plus: Configuration and Best Practices

Integrating MyBatis-Plus with Spring Boot

1. Dependency Setup

To begin integrating MyBatis-Plus into your Spring Boot project, add the following dependencies to your pom.xml:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
    <version>3.5.11</version>
</dependency>

<!-- Pagination plugin with matching version -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-jsqlparser</artifactId>
    <version>3.5.11</version>
</dependency>

2. Database Configuration

Configure your database connection in the application.yml file:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/project_db?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: admin
    password: secure_password

3. Entity Class Creation

Create your entity class with proper annotations:

@NoArgsConstructor
@AllArgsConstructor
@Data
@TableName("`customer`")
public class Customer {

    @TableId(type = IdType.AUTO)
    private Long customerId;
    private String fullName;
    private String credentials;
    private String nickname;
    private String emailAddress;

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime registrationTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime lastModified;

    @Version
    private Integer recordVersion;
}

4. Mapper Interface

Create a mapper interface that extends the BaseMapper:

@Mapper
public interface CustomerMapper extends BaseMapper<Customer> {
}

5. Basic Usage Example

Here's how to use the mapper in your service:

@Autowired
private CustomerMapper customerRepository;

public void addNewCustomer() {
    Customer newCustomer = new Customer();
    newCustomer.setFullName("John Doe");
    customerRepository.insert(newCustomer);
}

6. Advanced Features: Optimistic Locking and Pagination

6.1 Configuration Class

Create a configuration class for interceptors:

@Configuration
public class MybatisPlusConfiguration {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

6.2 Optimistic Locking

Ensure your entity has the @Version annotation:

@Version
private Integer recordVersion;

6.3 Pagination Implementation

Implement pagination in your service:

public List<Customer> getPaginatedCustomers() {
    Page<Customer> customerPage = new Page<>(2, 3);
    QueryWrapper<Customer> queryWrapper = new QueryWrapper<>();
    queryWrapper.orderByDesc("customerId");
    return customerRepository.selectPage(customerPage, queryWrapper).getRecords();
}

7. Automatic Timestmap Management

7.1 Database Setup

Create timestamp columns in your database table:

  • registration_time (datetime)
  • last_modified (datetime)

7.2 Entity Annotations

Add field annotations for automatic timestamp filling:

@TableField(fill = FieldFill.INSERT)
private LocalDateTime registrationTime;

@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime lastModified;

7.3 Custom Handler Implementation

Create a meta object handler:

@Component
public class TimestampHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "registrationTime", LocalDateTime.class, LocalDateTime.now());
        this.strictUpdateFill(metaObject, "lastModified", LocalDateTime.class, LocalDateTime.now());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "lastModified", LocalDateTime.class, LocalDateTime.now());
    }
}

Data Validation with Spring Boot

1. Validation Dependencies

Add validation starter to your project:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>3.2.2</version>
</dependency>

2. Validation Implementation

Apply validation to your controller methods:

@Validated
@PostMapping("/authenticate")
public Response authenticate(
    @Pattern(regexp = "^\\S{5,16}$") String username, 
    @Pattern(regexp = "^\\S{5,16}$") String password) {
    
    Customer customer = customerRepository.findByUsername(username);
    
    if (customer == null) {
        return Response.error("User not found");
    }
    
    if (customer.getCredentials().equals(PasswordUtil.encrypt(password))) {
        Map<String, Object> payload = new HashMap<>();
        payload.put("id", customer.getCustomerId());
        payload.put("name", customer.getFullName());
        String token = TokenUtil.generate(payload);
        return Response.success(token);
    }
    
    return Response.error("Invalid credentials");
}

JWT Token Implementation

1. JWT Dependencies

Add the JWT library to your project:

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>4.4.0</version>
</dependency>

2. Token Utility Class

Create a utility class for token operations:

public class TokenUtil {
    private static final String SECRET_KEY = "SecureSecretKey123";
    
    public static String generate(Map<String, Object> claims) {
        return JWT.create()
            .withClaim("payload", claims)
            .withExpiresAt(new Date(System.currentTimeMillis() + 12 * 60 * 60 * 1000))
            .sign(Algorithm.HMAC256(SECRET_KEY));
    }
    
    public static Map<String, Object> verify(String token) {
        return JWT.require(Algorithm.HMAC256(SECRET_KEY))
            .build()
            .verify(token)
            .getClaim("payload")
            .asMap();
    }
}

3. Authentication Interceptor

Create an interceptor for token validation:

@Component
public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String token = request.getHeader("Authorization");
        
        try {
            TokenUtil.verify(token);
            return true;
        } catch (Exception e) {
            response.setStatus(401);
            return false;
        }
    }
}

4. Interceptor Configuration

Register the interceptor in your Web configuration:

@Configuration
public class WebSecurityConfig implements WebMvcConfigurer {
    @Autowired
    private AuthInterceptor authInterceptor;
    
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authInterceptor)
            .excludePathPatterns("/api/auth/login", "/api/auth/register");
    }
}

5. Global Exception Handler

Create a centralized exception handler:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public Response handleException(Exception e) {
        return Response.error(e.getMessage() != null ? e.getMessage() : "Operation failed");
    }
}

MD5 Encryption Utility

public class PasswordUtil {
    private static final char[] hexChars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    
    public static String encrypt(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(input.getBytes());
            byte[] digest = md.digest();
            char[] result = new char[digest.length * 2];
            int position = 0;
            
            for (byte b : digest) {
                result[position++] = hexChars[(b & 0xF0) >>> 4];
                result[position++] = hexChars[b & 0x0F];
            }
            
            return new String(result);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Unified Response Structure

@Builder
@Data
public class Response<T> {
    private int statusCode;
    private String message;
    private T data;
    
    private static final int SUCCESS = 0;
    private static final String SUCCESS_MESSAGE = "Operation successful";
    private static final int ERROR = 1;
    private static final String ERROR_MESSAGE = "Operation failed";
    
    public static <T> Response<T> success(T data) {
        return new Response<>(SUCCESS, SUCCESS_MESSAGE, data);
    }
    
    public static <T> Response<T> success(String message, T data) {
        return new Response<>(SUCCESS, message, data);
    }
    
    public static <T> Response<T> error() {
        return new Response<>(ERROR, ERROR_MESSAGE, null);
    }
    
    public static <T> Response<T> error(String message) {
        return new Response<>(ERROR, message, null);
    }
    
    public static <T> Response<T> error(int code, String message) {
        return new Response<>(code, message, null);
    }
}

Customer Controller with Authentication

@CrossOrigin
@RestController
@RequestMapping("/api/customers")
public class CustomerController {
    
    @Autowired
    private CustomerMapper customerRepository;
    
    @PostMapping("/register")
    public Response register(
        @Pattern(regexp = "^\\S{5,16}$") String username, 
        @Pattern(regexp = "^\\S{5,16}$") String password) {
        
        if (customerRepository.existsByUsername(username)) {
            return Response.error("Username already exists");
        }
        
        Customer newCustomer = new Customer();
        newCustomer.setFullName(username);
        newCustomer.setCredentials(PasswordUtil.encrypt(password));
        customerRepository.insert(newCustomer);
        
        return Response.success("Registration successful");
    }
    
    @PostMapping("/login")
    public Response login(
        @Pattern(regexp = "^\\S{5,16}$") String username, 
        @Pattern(regexp = "^\\S{5,16}$") String password) {
        
        Customer customer = customerRepository.findByUsername(username);
        
        if (customer == null) {
            return Response.error("User not found");
        }
        
        if (customer.getCredentials().equals(PasswordUtil.encrypt(password))) {
            Map<String, Object> payload = new HashMap<>();
            payload.put("id", customer.getCustomerId());
            payload.put("name", customer.getFullName());
            String token = TokenUtil.generate(payload);
            return Response.success(token);
        }
        
        return Response.error("Invalid credentials");
    }
}

Tags: Spring Boot mybatis-plus JWT Validation MD5

Posted on Sun, 18 Oct 2026 16:39:41 +0000 by rhathid