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', '[email protected]', '北京市海淀区', 1, 0, '2023-10-01 10:00:00', '192.168.1.1', '测试用户1'),
    ('1', '李四', 'lisi', '李四', '123456', 0, 'images/avatar/0002.jpg', '市场部', '13800000002', '[email protected]', '上海市浦东新区', 1, 0, '2023-10-01 10:05:00', '192.168.1.2', '测试用户2'),
    ('2', '王五', 'wangwu', '王五', '123456', 2, 'images/avatar/0003.jpg', '销售部', '13800000003', '[email protected]', '广州市天河区', 1, 0, '2023-10-01 10:10:00', '192.168.1.3', '测试用户3'),
    ('0', '赵六', 'zhaoliu', '赵六', '123456', 1, 'images/avatar/0004.jpg', '财务部', '13800000004', '[email protected]', '深圳市南山区', 1, 0, '2023-10-01 10:15:00', '192.168.1.4', '测试用户4'),
    ('1', '孙七', 'sunqi', '孙七', '123456', 0, 'images/avatar/0005.jpg', '人力资源部', '13800000005', '[email protected]', '成都市武侯区', 1, 0, '2023-10-01 10:20:00', '192.168.1.5', '测试用户5'),
    ('2', '周八', 'zhouba', '周八', '123456', 2, 'images/avatar/0006.jpg', '技术部', '13800000006', '[email protected]', '杭州市西湖区', 1, 0, '2023-10-01 10:25:00', '192.168.1.6', '测试用户6'),
    ('0', '吴九', 'wujiu', '吴九', '123456', 1, 'images/avatar/0007.jpg', '市场部', '13800000007', '[email protected]', '南京市鼓楼区', 1, 0, '2023-10-01 10:30:00', '192.168.1.7', '测试用户7'),
    ('1', '郑十', 'zhengshi', '郑十', '123456', 0, 'images/avatar/0008.jpg', '销售部', '13800000008', '[email protected]', '武汉市江汉区', 1, 0, '2023-10-01 10:35:00', '192.168.1.8', '测试用户8'),
    ('2', '钱十一', 'qianshiyi', '钱十一', '123456', 2, 'images/avatar/0009.jpg', '财务部', '13800000009', '[email protected]', '重庆市渝中区', 1, 0, '2023-10-01 10:40:00', '192.168.1.9', '测试用户9'),
    ('0', '孙十二', 'sunshier', '孙十二', '123456', 1, 'images/avatar/0010.jpg', '人力资源部', '13800000010', '[email protected]', '西安市雁塔区', 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": "[email protected]",
  "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中完成定义,参考上述操作步骤稍加改动即可完成。

相关推荐
烛阴1 小时前
bignumber.js深度解析:驾驭任意精度计算的终极武器
前端·javascript·后端
服务端技术栈1 小时前
电商营销系统中的幂等性设计:从抽奖积分发放谈起
后端
你的人类朋友2 小时前
✍️Node.js CMS框架概述:Directus与Strapi详解
javascript·后端·node.js
面朝大海,春不暖,花不开2 小时前
自定义Spring Boot Starter的全面指南
java·spring boot·后端
HelloWord~2 小时前
SpringSecurity+vue通用权限系统
vue.js·spring boot
钡铼技术ARM工业边缘计算机2 小时前
【成本降40%·性能翻倍】RK3588边缘控制器在安防联动系统的升级路径
后端
wangjinjin1803 小时前
使用 IntelliJ IDEA 安装通义灵码(TONGYI Lingma)插件,进行后端 Java Spring Boot 项目的用户用例生成及常见问题处理
java·spring boot·intellij-idea
CryptoPP3 小时前
使用WebSocket实时获取印度股票数据源(无调用次数限制)实战
后端·python·websocket·网络协议·区块链
白宇横流学长3 小时前
基于SpringBoot实现的大创管理系统设计与实现【源码+文档】
java·spring boot·后端
草捏子4 小时前
状态机设计:比if-else优雅100倍的设计
后端