【数据库系列】Spring Boot 中使用 MyBatis 详细指南

一、基础介绍

1.1 MyBatis

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO(Plain Old Java Objects)映射成数据库中的记录。

1.2 Spring Boot 集成 MyBatis 的优势

将 Spring Boot 和 MyBatis 集成,能够充分发挥 Spring Boot 的快速开发特性和 MyBatis 灵活的数据库操作能力。通过这种集成,可以快速搭建一个稳定、高效的数据库访问层,简化开发流程,提高开发效率。

二、集成步骤

2.1 创建 Spring Boot 项目

可以使用 Spring Initializr(https://start.spring.io/)来快速创建一个 Spring Boot 项目。在创建项目时,需要选择以下依赖:

  • Spring Web
  • Spring Data JPA
  • MySQL Driver
  • MyBatis Framework

2.2 配置数据源

application.properties 文件中配置数据库连接信息:

properties 复制代码
spring.datasource.url=jdbc:mysql://localhost:3306/yourdatabase
spring.datasource.username=yourusername
spring.datasource.password=yourpassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

2.3 配置 MyBatis

application.properties 文件中配置 MyBatis 的相关属性:

properties 复制代码
mybatis.mapper-locations=classpath:/mapper/*.xml
mybatis.type-aliases-package=com.example.demo.entity

mybatis.mapper-locations 配置 MyBatis 映射文件的位置,mybatis.type-aliases-package 配置实体类的包名,这样在 MyBatis 映射文件中就可以直接使用实体类名而无需写全限定名。

2.4 创建实体类

创建一个 Java 实体类,用于映射数据库表中的记录。例如,创建一个 User 实体类:

java 复制代码
package com.example.demo.entity;

public class User {
    private Long id;
    private String username;
    private String password;

    // 省略 getters 和 setters
}

2.5 创建 Mapper 接口

创建一个 Mapper 接口,用于定义数据库操作方法。例如,创建一个 UserMapper 接口:

java 复制代码
package com.example.demo.mapper;

import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface UserMapper {
    @Select("SELECT * FROM user")
    List<User> findAll();
}

@Mapper 注解用于将该接口标记为 MyBatis 的 Mapper 接口。

2.6 创建 Mapper 映射文件

resources/mapper 目录下创建一个 UserMapper.xml 文件,用于实现 Mapper 接口中的方法:

xml 复制代码
<?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.demo.mapper.UserMapper">
    <select id="findAll" resultType="com.example.demo.entity.User">
        SELECT * FROM user
    </select>
</mapper>

namespace 属性指定 Mapper 接口的全限定名,id 属性指定要实现的方法名,resultType 属性指定返回结果的类型。

2.7 创建 Service 层

创建一个 Service 层,用于调用 Mapper 接口中的方法。例如,创建一个 UserService 接口和其实现类 UserServiceImpl

java 复制代码
package com.example.demo.service;

import com.example.demo.entity.User;

import java.util.List;

public interface UserService {
    List<User> findAll();
}
java 复制代码
package com.example.demo.service.impl;

import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> findAll() {
        return userMapper.findAll();
    }
}

2.8 创建 Controller 层

创建一个 Controller 层,用于处理客户端请求。例如,创建一个 UserController

java 复制代码
package com.example.demo.controller;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping
    public List<User> findAll() {
        return userService.findAll();
    }
}

三、示例完整代码

1. 创建 application.yml

src/main/resources 目录下创建 application.yml 文件。

2. 配置数据源和 MyBatis

将原本 application.properties 中的配置内容转换为 YAML 格式,如下:

yaml 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/yourdatabase
    username: yourusername
    password: yourpassword
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  mapper-locations: classpath:/mapper/*.xml
  type-aliases-package: com.example.demo.entity

说明

  • 在 YAML 中,使用缩进表示层级关系。例如,springmybatis 是顶级配置项,datasourcespring 的子配置项,urlusernamepassworddriver-class-namedatasource 的子配置项。
  • 冒号后面需要跟一个空格,然后再写具体的值。

完整项目示例

以下是基于上述 application.yml 配置的完整项目示例,包括之前提到的各个部分:

项目结构
复制代码
src
├── main
│   ├── java
│   │   ├── com
│   │   │   ├── example
│   │   │   │   ├── demo
│   │   │   │   │   ├── controller
│   │   │   │   │   │   └── UserController.java
│   │   │   │   │   ├── entity
│   │   │   │   │   │   └── User.java
│   │   │   │   │   ├── mapper
│   │   │   │   │   │   ├── UserMapper.java
│   │   │   │   │   │   └── UserMapper.xml
│   │   │   │   │   ├── service
│   │   │   │   │   │   ├── UserService.java
│   │   │   │   │   │   └── impl
│   │   │   │   │   │       └── UserServiceImpl.java
│   │   │   │   │   └── DemoApplication.java
│   └── resources
│       ├── application.yml
│       └── mapper
│           └── UserMapper.xml
└── test
    └── java
        └── com
            └── example
                └── demo
                    └── DemoApplicationTests.java
依赖配置(pom.xml)
xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.6</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.9</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
实体类(User.java)
java 复制代码
package com.example.demo.entity;

public class User {
    private Long id;
    private String username;
    private String password;

    // 构造函数
    public User() {}

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    // getters 和 setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
Mapper 接口(UserMapper.java)
java 复制代码
package com.example.demo.mapper;

import com.example.demo.entity.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface UserMapper {
    @Select("SELECT * FROM user")
    List<User> findAll();

    @Select("SELECT * FROM user WHERE id = #{id}")
    User findById(Long id);

    @Insert("INSERT INTO user (username, password) VALUES (#{username}, #{password})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    void save(User user);

    @Update("UPDATE user SET username = #{username}, password = #{password} WHERE id = #{id}")
    void update(User user);

    @Delete("DELETE FROM user WHERE id = #{id}")
    void delete(Long id);
}
Mapper 映射文件(UserMapper.xml)
xml 复制代码
<?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.demo.mapper.UserMapper">
    <select id="findAll" resultType="com.example.demo.entity.User">
        SELECT * FROM user
    </select>
    <select id="findById" resultType="com.example.demo.entity.User">
        SELECT * FROM user WHERE id = #{id}
    </select>
    <insert id="save" keyProperty="id" useGeneratedKeys="true">
        INSERT INTO user (username, password) VALUES (#{username}, #{password})
    </insert>
    <update id="update">
        UPDATE user SET username = #{username}, password = #{password} WHERE id = #{id}
    </update>
    <delete id="delete">
        DELETE FROM user WHERE id = #{id}
    </delete>
</mapper>
Service 层

UserService.java

java 复制代码
package com.example.demo.service;

import com.example.demo.entity.User;

import java.util.List;

public interface UserService {
    List<User> findAll();
    User findById(Long id);
    void save(User user);
    void update(User user);
    void delete(Long id);
}

UserServiceImpl.java

java 复制代码
package com.example.demo.service.impl;

import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> findAll() {
        return userMapper.findAll();
    }

    @Override
    public User findById(Long id) {
        return userMapper.findById(id);
    }

    @Override
    public void save(User user) {
        userMapper.save(user);
    }

    @Override
    public void update(User user) {
        userMapper.update(user);
    }

    @Override
    public void delete(Long id) {
        userMapper.delete(id);
    }
}
Controller 层(UserController.java)
java 复制代码
package com.example.demo.controller;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping
    public ResponseEntity<List<User>> findAll() {
        List<User> users = userService.findAll();
        return new ResponseEntity<>(users, HttpStatus.OK);
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> findById(@PathVariable Long id) {
        User user = userService.findById(id);
        if (user!= null) {
            return new ResponseEntity<>(user, HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }

    @PostMapping
    public ResponseEntity<Void> save(@RequestBody User user) {
        userService.save(user);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @PutMapping
    public ResponseEntity<Void> update(@RequestBody User user) {
        userService.update(user);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(@PathVariable Long id) {
        userService.delete(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }
}
测试(DemoApplicationTests.java)
java 复制代码
package com.example.demo;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
public class DemoApplicationTests {
    @Autowired
    private UserService userService;

    @Test
    public void testFindAll() {
        assertEquals(0, userService.findAll().size());
    }

    @Test
    public void testSaveAndFindById() {
        User user = new User("testuser", "testpassword");
        userService.save(user);
        assertNotNull(userService.findById(user.getId()));
    }

    @Test
    public void testUpdate() {
        User user = new User("testuser", "testpassword");
        userService.save(user);
        user.setPassword("newpassword");
        userService.update(user);
        assertEquals("newpassword", userService.findById(user.getId()).getPassword());
    }

    @Test
    public void testDelete() {
        User user = new User("testuser", "testpassword");
        userService.save(user);
        userService.delete(user.getId());
        assertNull(userService.findById(user.getId()));
    }
}

通过上述配置和代码示例,你可以在 Spring Boot 项目中使用 application.yml 配置文件来集成 MyBatis,并实现完整的用户管理功能。

相关推荐
28岁青春痘老男孩19 小时前
JDK8+SpringBoot2.x 升级 JDK 17 + Spring Boot 3.x
java·spring boot
ruleslol19 小时前
MySQL的段、区、页、行 详解
数据库·mysql
天若有情67319 小时前
校园二手交易系统实战开发全记录(vue+SpringBoot+MySQL)
vue.js·spring boot·mysql
while(1){yan}20 小时前
MyBatis Generator
数据库·spring boot·java-ee·mybatis
奋进的芋圆20 小时前
DataSyncManager 详解与 Spring Boot 迁移指南
java·spring boot·后端
それども20 小时前
MySQL affectedRows 计算逻辑
数据库·mysql
是小章啊20 小时前
MySQL 之SQL 执行规则及索引详解
数据库·sql·mysql
计算机程序设计小李同学20 小时前
个人数据管理系统
java·vue.js·spring boot·后端·web安全
富士康质检员张全蛋20 小时前
JDBC 连接池
数据库
yangminlei20 小时前
集成Camunda到Spring Boot项目
数据库·oracle