SpringBoot(十一):整合 Mybatis

郎家岭伯爵 2023年07月20日 377次浏览

前言

SpringBoot 整合 Mybatis

实现

创建一个新的 SpringBoot 项目。

pom.xml

pom.xml 中引入以下依赖:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.11</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

application.properties

application.properties 中添加如下配置项:

# 数据库配置
spring.datasource.username=root
spring.datasource.password=
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# mybatis的xml文件扫描路径,*.xml代表所有xml文件
mybatis.mapper-locations=classpath:mapper/*.xml
# 开启驼峰命名规则的自动映射
mybatis.configuration.map-underscore-to-camel-case=true

# 开启MyBatis的SQL语句输出
logging.level.com.langjialing.mybatisdemo.mapper.UserMapper=debug
  • mybatis.configuration.map-underscore-to-camel-case=true,这个配置告诉 MyBatis 是否开启驼峰命名规则的自动映射。当设置为 true 时,MyBatis 会将数据库中的下划线命名方式(如first_name)自动映射为 Java 对象的驼峰命名方式(如firstName)。
  • logging.level.com.langjialing.mybatisdemo.mapper.UserMapper=debug,这个配置开启 Mybatis 的SQL语句输出。但要注意要写明 Mapper 接口类的位置。

User.java

创建 User.java 实体类。

package com.langjialing.mybatisdemo.entity;

import lombok.Builder;
import lombok.Data;
import lombok.experimental.Tolerate;

/**
 * @author 郎家岭伯爵
 * @time 2023/7/19 11:27
 */
@Data
@Builder
public class User {
    private Integer userId;
    private Integer age;
    private String userName;
    private String password;

    @Tolerate
    User() {}
}

这里使用了 lombok

  • @Data 注解自动生成 getter/setter
  • @Builder 生成链式调用
  • 由于 @Data@Builder 配合使用的时候会导致无参构造方法丢失,所以我们主动声明了无参构造方法,并使用 @Tolerate 注解来告诉 lombok 请允许我们的无参构造方法存在(没有无参构造方法的时候会导致 ORM 映射出错)

Mapper接口类

创建 Mapper 接口类:

package com.langjialing.mybatisdemo.mapper;

import com.langjialing.mybatisdemo.entity.User;

import java.util.List;

/**
 * @author 郎家岭伯爵
 * @time 2023/7/19 11:38
 */
public interface UserMapper {

    /**
     * 获取所有用户。
     * @return 所有用户。
     */
    List<User> getAll();

    /**
     * 根据用户ID获取用户。
     * @param id 用户ID。
     * @return 用户。
     */
    User getOne(Long id);

    /**
     * 新增用户。
     * @param user 用户。
     */
    void insert(User user);

    /**
     * 更新用户。
     * @param user 用户。
     */
    void update(User user);

    /**
     * 根据用户ID删除用户。
     * @param id 用户ID。
     */
    void delete(Long id);
}

Mapper.xml文件

resources 文件下创建 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.langjialing.mybatisdemo.mapper.UserMapper">
    <resultMap id="BaseResultMap" type="com.langjialing.mybatisdemo.entity.User">
        <id column="user_id" property="userId"/>
        <result column="user_name" property="userName"/>
        <result column="age" property="age"/>
        <result column="password" property="password"/>
    </resultMap>

    <sql id="Base_Column_List">
        user_id, user_name, age, password
    </sql>

    <select id="getAll" resultType="com.langjialing.mybatisdemo.entity.User">
        select
        <include refid="Base_Column_List" />
        from `user`
    </select>

    <select id="getOne" parameterType="java.lang.Long" resultType="com.langjialing.mybatisdemo.entity.User" >
        SELECT
        <include refid="Base_Column_List" />
        FROM `user`
        WHERE user_id = #{id}
    </select>

    <insert id="insert" parameterType="com.langjialing.mybatisdemo.entity.User">
        insert into
            `user`
            (user_name,age,password)
        values
            (#{userName},#{age},#{password});
    </insert>
    <update id="update" parameterType="com.langjialing.mybatisdemo.entity.User">
        update
        `user`
        set
        <if test="userName != null">user_name=#{userName},</if>
        <if test="password != null">password=#{password},</if>
        age=#{age}
        where user_id=#{userId}
    </update>
    <delete id="delete">
        delete from
            `user`
        where
            user_id=#{id}
    </delete>
</mapper>

Service层

Service 接口类:

package com.langjialing.mybatisdemo.service;

import com.langjialing.mybatisdemo.entity.User;

import java.util.List;

/**
 * @author 郎家岭伯爵
 * @time 2023/7/20 10:08
 */
public interface UserService {
    /**
     * 获取所有用户。
     * @return 所有用户。
     */
    List<User> getAll();

    /**
     * 根据用户ID获取用户。
     * @param id 用户ID。
     * @return 用户。
     */
    User getOne(Long id);

    /**
     * 新增用户。
     * @param user 用户。
     */
    void insert(User user);

    /**
     * 更新用户。
     * @param user 用户。
     */
    void update(User user);

    /**
     * 根据用户ID删除用户。
     * @param id 用户ID。
     */
    void delete(Long id);
}

Service 接口实现类:

package com.langjialing.mybatisdemo.service.impl;

import com.langjialing.mybatisdemo.entity.User;
import com.langjialing.mybatisdemo.mapper.UserMapper;
import com.langjialing.mybatisdemo.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author 郎家岭伯爵
 * @time 2023/7/20 10:09
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

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

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

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

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

    @Override
    public void delete(Long id) {
        userMapper.delete(id);
    }
}

Controller层

在 Controller 层创建对应各功能点的接口,用于后续的测试:

package com.langjialing.mybatisdemo.controller;

import com.langjialing.mybatisdemo.entity.User;
import com.langjialing.mybatisdemo.service.UserService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author 郎家岭伯爵
 * @time 2023/7/19 13:31
 */
@RestController
public class UserController {

    @Resource
    private UserService userService;

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

    @GetMapping("/getAll")
    public List<User> getAll() {
        return userService.getAll();
    }

    @GetMapping("/getOne")
    public User getOne() {
        return userService.getOne(1L);
    }

    @PostMapping("/insert")
    public void insert(@RequestBody User user) {
        userService.insert(user);
    }

    @PostMapping("/update")
    public void update(@RequestBody User user) {
        userService.update(user);
    }

    @GetMapping("/delete")
    public void delete(@RequestParam Long id) {
        userService.delete(id);
    }
}

主启动类

在主启动类添加 @MapperScan() 注解,用于扫描指定路径下的 Mapper 接口类。

package com.langjialing.mybatisdemo;

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

@SpringBootApplication
@MapperScan(basePackages = "com.langjialing.mybatisdemo.mapper")
public class MybatisDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(MybatisDemoApplication.class, args);
    }

}

@MapperScan配置扫描路径

测试功能

启动项目后,用 POSTMAN 调用接口测试功能。

查找所有用户

更新用户

总结

SpringBoot 整合 Mybatis