Spring Boot 3中基于纯MyBatis的CURD开发实例

项目整理目录结构:

text 复制代码
└── aiosms
    ├── pom.xml
    └── src
        ├── main
        │   ├── java
        │   │   └── com       
        │   │       └── ivandu
        │   │           └── aiosms
        │   │               ├── Aiosms.java
        │   │               ├── controller
        │   │               │   └── UserController.java
        │   │               ├── entity
        │   │               │   └── User.java
        │   │               ├── mapper
        │   │               │   └── UserMapper.java    
        │   │               └── service
        │   │                   ├── UserService.java   
        │   │                   └── impl
        │   │                       └── UserServiceImpl.java
        │   └── resources
        │       ├── application.properties
        │       ├── mapper
        │       │   └── UserMapper.xml
        │       └── mybatis-config.xml
        └── test
            └── java

项目POM:

xml 复制代码
<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>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.10</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.ivandu.aiosms</groupId>
    <artifactId>aiosms</artifactId>
    <version>${revision}</version>
    <packaging>jar</packaging>

    <name>${project.artifactId}</name>

    <properties>
        <revision>1.0.0</revision>
        <java.version>17</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <maven.compiler.compilerVersion>${java.version}</maven.compiler.compilerVersion>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
        <spring.boot.version>${project.parent.version}</spring.boot.version>
        <spring.webmvc.version>6.1.13</spring.webmvc.version>
        <mysql.version>8.4.0</mysql.version>
        <mybatis.version>3.5.16</mybatis.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>${mysql.version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>huaweicloud</id>
            <name>huawei</name>
            <url>https://mirrors.huaweicloud.com/repository/maven/</url>
        </repository>
        <repository>
            <id>aliyunmaven</id>
            <name>aliyun</name>
            <url>https://maven.aliyun.com/repository/public</url>
        </repository>
    </repositories>

</project>

实体类(有参构造函数及setter、getter省略):

java 复制代码
package com.ivandu.aiosms.entity;

import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;

public class User implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;
    private Long userId;
    private String userType;
    private String fullName;
    private String userName;
    private String nickName;
    private String password;
    private Integer gender;
    private String avatar;
    private String department;
    private String cellphone;
    private String email;
    private String address;
    private Boolean status;
    private Boolean isDeleted;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
    private LocalDateTime loginTime;
    private String loginIp;
    private String remark;

    public User() {
    }

Mapper接口:

java 复制代码
package com.ivandu.aiosms.mapper;

import com.ivandu.aiosms.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper {

    User selectUserById(Long id);
}

UserService接口:

java 复制代码
package com.ivandu.aiosms.service;

import com.ivandu.aiosms.entity.User;

public interface UserService {
    User getUserById(Long id);
}

UserService实现类:

java 复制代码
package com.ivandu.aiosms.service.impl;

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

@Service
public class UserServiceImpl implements UserService {

    private UserMapper userMapper;

    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

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

Controller类:

java 复制代码
package com.ivandu.aiosms.controller;

import com.ivandu.aiosms.entity.User;
import com.ivandu.aiosms.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

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

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/{id}")
    public User findUserById(@PathVariable Long id) {
        return userService.getUserById(id);
    }
}

启动类:

java 复制代码
package com.ivandu.aiosms;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

配置文件properties:

properties 复制代码
server.port=10100

spring.main.banner-mode=off
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:23066/aiosms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=cm_aiosms
spring.datasource.password=C*x#1a2b

mybatis.type-aliases-package=com.ivandu.aiosms.entity
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.config-location=classpath:mybatis-config.xml

MyBatis配置mybatis-config.xml:

xml 复制代码
<?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="cacheEnabled"             value="true"   />
        <!-- 允许JDBC 支持自动生成主键 -->
        <setting name="useGeneratedKeys"         value="true"   />
        <!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
        <setting name="defaultExecutorType"      value="SIMPLE" />
        <!-- 指定 MyBatis 所用日志的具体实现 -->
        <setting name="logImpl"                  value="SLF4J"  />
        <!-- 使用驼峰命名法转换字段 -->
        <!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
    </settings>

</configuration>

Mapper文件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.ivandu.aiosms.mapper.UserMapper">

    <!-- 基础结果映射 -->
    <resultMap id="UserResultMap" type="com.ivandu.aiosms.entity.User">
        <id column="user_id" property="userId"/>
        <result column="user_type" property="userType"/>
        <result column="full_name" property="fullName"/>
        <result column="user_name" property="userName"/>
        <result column="nick_name" property="nickName"/>
        <result column="password" property="password"/>
        <result column="gender" property="gender"/>
        <result column="avatar" property="avatar"/>
        <result column="department" property="department"/>
        <result column="cellphone" property="cellphone"/>
        <result column="email" property="email"/>
        <result column="address" property="address"/>
        <result column="status" property="status"/>
        <result column="is_deleted" property="isDeleted"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
        <result column="login_time" property="loginTime"/>
        <result column="login_ip" property="loginIp"/>
        <result column="remark" property="remark"/>
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="selectUser">
        select user_id,
               user_type,
               full_name,
               user_name,
               nick_name,
               password,
               gender,
               avatar,
               department,
               cellphone,
               email,
               address,
               status,
               is_deleted,
               create_time,
               update_time,
               login_time,
               login_ip,
               remark
        from aiosms_user
    </sql>

    <!-- 根据ID查询用户 -->
    <select id="selectUserById" resultMap="UserResultMap" parameterType="Long">
        <include refid="selectUser"/>
        where user_id = #{userId} and is_deleted = 0 and status = 1
    </select>

    <!-- 查询用户列表 -->
    <select id="selectUserList" resultMap="UserResultMap">
        <include refid="selectUser"/>
        where is_deleted = 0
    </select>

    <!-- 插入用户 -->
    <insert id="insert" parameterType="com.ivandu.aiosms.entity.User">
        insert into aiosms_user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="userType != null">user_type,</if>
            <if test="fullName != null">full_name,</if>
            <if test="userName != null">user_name,</if>
            <if test="nickName != null">nick_name,</if>
            <if test="password != null">password,</if>
            <if test="gender != null">gender,</if>
            <if test="avatar != null">avatar,</if>
            <if test="department != null">department,</if>
            <if test="cellphone != null">cellphone,</if>
            <if test="email != null">email,</if>
            <if test="address != null">address,</if>
            <if test="status != null">status,</if>
            <if test="remark != null">remark,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="userType != null">#{userType},</if>
            <if test="fullName != null">#{fullName},</if>
            <if test="userName != null">#{userName},</if>
            <if test="nickName != null">#{nickName},</if>
            <if test="password != null">#{password},</if>
            <if test="gender != null">#{gender},</if>
            <if test="avatar != null">#{avatar},</if>
            <if test="department != null">#{department},</if>
            <if test="cellphone != null">#{cellphone},</if>
            <if test="email != null">#{email},</if>
            <if test="address != null">#{address},</if>
            <if test="status != null">#{status},</if>
            <if test="remark != null">#{remark},</if>
        </trim>
    </insert>

    <!-- 更新用户 -->
    <update id="updateById" parameterType="com.ivandu.aiosms.entity.User">
        update aiosms_user
        <set>
            <if test="userType != null">user_type = #{userType},</if>
            <if test="fullName != null">full_name = #{fullName},</if>
            <if test="userName != null">user_name = #{userName},</if>
            <if test="nickName != null">nick_name = #{nickName},</if>
            <if test="password != null">password = #{password},</if>
            <if test="gender != null">gender = #{gender},</if>
            <if test="avatar != null">avatar = #{avatar},</if>
            <if test="department != null">department = #{department},</if>
            <if test="cellphone != null">cellphone = #{cellphone},</if>
            <if test="email != null">email = #{email},</if>
            <if test="address != null">address = #{address},</if>
            <if test="status != null">status = #{status},</if>
            <if test="remark != null">remark = #{remark},</if>
        </set>
        where user_id = #{userId} and is_deleted = 0
    </update>

    <!-- 逻辑删除用户 -->
    <update id="deleteById">
        update aiosms_user
        set is_deleted = 1
        where user_id = #{userId}
          and is_deleted = 0
    </update>
</mapper>

MySQL建库、建表语句及示例数据:

sql 复制代码
DROP DATABASE IF EXISTS aiosms;
CREATE DATABASE aiosms;
-- CREATE USER 'cm_aiosms'@'10.1.1.3' IDENTIFIED BY 'C*x#1a2b';
CREATE USER 'cm_aiosms'@'%' IDENTIFIED BY 'C*x#1a2b';
-- GRANT ALL PRIVILEGES ON aiosms.* TO 'cm_aiosms'@'10.1.1.3';
-- FLUSH PRIVILEGES;
-- REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'cm_aiosms'@'10.1.1.3';
GRANT ALL PRIVILEGES ON aiosms.* TO 'cm_aiosms'@'%';
FLUSH PRIVILEGES;

-- 用户信息表
DROP TABLE IF EXISTS aiosms_user;
CREATE TABLE aiosms_user
(
    user_id     BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '唯一标识',
    user_type   CHAR(1)      NOT NULL DEFAULT '0' COMMENT '用户类型,0普通用户,1管理员,2超级管理员',
    full_name   VARCHAR(128) NOT NULL COMMENT '用户姓名',
    user_name   VARCHAR(128) NOT NULL UNIQUE COMMENT '用户账号',
    nick_name   VARCHAR(64)  NOT NULL COMMENT '用户昵称',
    password    VARCHAR(32)  NOT NULL COMMENT '用户密码',
    gender      TINYINT      NOT NULL DEFAULT 2 COMMENT '用户性别(0女 1男 2未知)',
    avatar      VARCHAR(128) NOT NULL DEFAULT 'images/avatar/0001.jpg' COMMENT '用户头像',
    department  VARCHAR(128) NOT NULL COMMENT '所属部门',
    cellphone   VARCHAR(15)  NOT NULL UNIQUE COMMENT '手机号',
    email       VARCHAR(128) NOT NULL UNIQUE COMMENT '邮箱地址',
    address     VARCHAR(255) COMMENT '通信地址',
    status      TINYINT      NOT NULL DEFAULT 1 COMMENT '当前状态,0禁用,1启用',
    is_deleted  TINYINT      NOT NULL DEFAULT 0 COMMENT '注销状态,0正常,1注销',
    create_time DATETIME              DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间',
    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '信息更新时间',
    login_time  DATETIME COMMENT '登录时间',
    login_ip    VARCHAR(45) COMMENT '登录IP',
    remark      VARCHAR(255) COMMENT '备注信息'
) ENGINE = InnoDB
  AUTO_INCREMENT = 1000
  DEFAULT CHARSET = utf8mb4 COMMENT ='用户信息表';

INSERT INTO aiosms_user (user_type, full_name, user_name, nick_name, password, gender, avatar, department, cellphone, email, address, status, is_deleted, login_time, login_ip, remark)
VALUES
    ('0', '张三', 'zhangsan', '张三', '123456', 1, 'images/avatar/0001.jpg', '技术部', '13800000001', 'zhangsan@example.com', '北京市海淀区', 1, 0, '2023-10-01 10:00:00', '192.168.1.1', '测试用户1'),
    ('1', '李四', 'lisi', '李四', '123456', 0, 'images/avatar/0002.jpg', '市场部', '13800000002', 'lisi@example.com', '上海市浦东新区', 1, 0, '2023-10-01 10:05:00', '192.168.1.2', '测试用户2'),
    ('2', '王五', 'wangwu', '王五', '123456', 2, 'images/avatar/0003.jpg', '销售部', '13800000003', 'wangwu@example.com', '广州市天河区', 1, 0, '2023-10-01 10:10:00', '192.168.1.3', '测试用户3'),
    ('0', '赵六', 'zhaoliu', '赵六', '123456', 1, 'images/avatar/0004.jpg', '财务部', '13800000004', 'zhaoliu@example.com', '深圳市南山区', 1, 0, '2023-10-01 10:15:00', '192.168.1.4', '测试用户4'),
    ('1', '孙七', 'sunqi', '孙七', '123456', 0, 'images/avatar/0005.jpg', '人力资源部', '13800000005', 'sunqi@example.com', '成都市武侯区', 1, 0, '2023-10-01 10:20:00', '192.168.1.5', '测试用户5'),
    ('2', '周八', 'zhouba', '周八', '123456', 2, 'images/avatar/0006.jpg', '技术部', '13800000006', 'zhouba@example.com', '杭州市西湖区', 1, 0, '2023-10-01 10:25:00', '192.168.1.6', '测试用户6'),
    ('0', '吴九', 'wujiu', '吴九', '123456', 1, 'images/avatar/0007.jpg', '市场部', '13800000007', 'wujiu@example.com', '南京市鼓楼区', 1, 0, '2023-10-01 10:30:00', '192.168.1.7', '测试用户7'),
    ('1', '郑十', 'zhengshi', '郑十', '123456', 0, 'images/avatar/0008.jpg', '销售部', '13800000008', 'zhengshi@example.com', '武汉市江汉区', 1, 0, '2023-10-01 10:35:00', '192.168.1.8', '测试用户8'),
    ('2', '钱十一', 'qianshiyi', '钱十一', '123456', 2, 'images/avatar/0009.jpg', '财务部', '13800000009', 'qianshiyi@example.com', '重庆市渝中区', 1, 0, '2023-10-01 10:40:00', '192.168.1.9', '测试用户9'),
    ('0', '孙十二', 'sunshier', '孙十二', '123456', 1, 'images/avatar/0010.jpg', '人力资源部', '13800000010', 'sunshier@example.com', '西安市雁塔区', 1, 0, '2023-10-01 10:45:00', '192.168.1.10', '测试用户10');

使用Thunder Client调用,返回结果:

json 复制代码
{
  "userId": 1001,
  "userType": "1",
  "fullName": "李四",
  "userName": "lisi",
  "nickName": "李四",
  "password": "123456",
  "gender": 0,
  "avatar": "images/avatar/0002.jpg",
  "department": "市场部",
  "cellphone": "13800000002",
  "email": "lisi@example.com",
  "address": "上海市浦东新区",
  "status": true,
  "isDeleted": false,
  "createTime": "2024-11-04T18:52:09",
  "updateTime": "2024-11-04T18:52:09",
  "loginTime": "2023-10-01T10:05:00",
  "loginIp": "192.168.1.2",
  "remark": "测试用户2"
}

部分调用日志:

log 复制代码
2024-11-06T14:40:00.437+08:00  INFO 35732 --- [io-10100-exec-1] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2024-11-06T14:40:00.604+08:00  INFO 35732 --- [io-10100-exec-1] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@254a87aa
2024-11-06T14:40:00.606+08:00  INFO 35732 --- [io-10100-exec-1] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.

以上例子中使用纯MyBatis实现了Spring Boot3中的数据查询功能,其余更新、插入、删除部分已在XML mapper中完成定义,参考上述操作步骤稍加改动即可完成。

相关推荐
砍材农夫7 小时前
物联网实战:Spring Boot + Netty 搭建 MQTT 统一接入层
java·网络·spring boot·后端·物联网·spring
写代码的小阿帆7 小时前
英语四六级证书审核(SpringBoot+Dify+RPA)
java·spring boot
苏三说技术8 小时前
MarkItDown 再次登顶GitHub榜
后端
IT_陈寒8 小时前
SpringBoot这个坑差点让我加班到天亮
前端·人工智能·后端
小小龙学IT8 小时前
Go 后端开发中的并发模式:从 Goroutine 到 Pipeline 实战
开发语言·后端·golang
geovindu8 小时前
go: Coroutines Pattern
开发语言·后端·设计模式·golang·协程模式
霸道流氓气质8 小时前
RabbitMQ 从零到实战:概念、配置与 Spring Boot 集成指南
spring boot·rabbitmq·java-rabbitmq
夜郎king8 小时前
SpringBoot 整合 Neo4j 实战:从零搭建经典小说知识图谱完整方案
spring boot·知识图谱·neo4j
阿正的梦工坊9 小时前
【Rust】01-认识 Rust:语言定位、工具链与第一个程序
开发语言·后端·rust
一条泥憨鱼9 小时前
苍穹外卖【day5|Redis与店铺营业状态设置】
java·后端·mybatis·苍穹外卖