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中完成定义,参考上述操作步骤稍加改动即可完成。

相关推荐
颜淡慕潇4 分钟前
【数据库系列】 Spring Boot 集成 Neo4j 的详细介绍
java·数据库·spring boot·后端·neo4j
Neoest13 分钟前
场景解决之mybatis当中resultType= map时,因某个字段为null导致返回的map的key不存在怎么处理
mybatis
许野平19 分钟前
Rust:GUI 开源框架
开发语言·后端·rust·gui
刘翔在线犯法26 分钟前
Scala的迭代器
开发语言·后端·scala
无敌小肥00728 分钟前
Springboot 整合 itext 实现PDF文件合并,识别图片则转成PDF拼接
spring boot·后端·pdf
迷茫的李二1 小时前
Spring Boot 自动加载 Jackson 的原理及替换为 FastJSON
java·spring boot
bingbingyihao1 小时前
Spring boot + Vue2小项目基本模板
vue.js·spring boot
IT大玩客1 小时前
SpringBoot如何集成WebSocket
spring boot·后端·websocket
ModelBulider1 小时前
九、HttpMessageConverter
java·开发语言·后端·spring·springmvc
就叫飞六吧2 小时前
电商系统表的1-n如何设计?情景分析
java·后端·spring