MyBatis 入门与实战:从配置到CRUD一站式指南

目录

1.什么是MyBatis

2.入门操作

(1)创建项目

(2)数据准备

(3)配置数据库连接字符串

(4)写持久层代码

(5)单元测试

3.基础操作

(1)打印日志

(2)参数传递

(3)增

(4)删

(5)改

(6)查

[4.MyBatis XML配置文件](#4.MyBatis XML配置文件)

(1)配置连接字符串和MyBatis

(2)写持久层代码

(3)增删改查

[5.#{}和{}区别](#{}和{}区别)

6.数据库连接池

7.动态SQL

[(1). 标签 - 条件判断](#(1). 标签 - 条件判断)

[(2). 标签 - 智能修剪](#(2). 标签 - 智能修剪)

[(3). 标签 - 智能WHERE子句](#(3). 标签 - 智能WHERE子句)

[(4).
标签 - 智能SET子句](#(4). 标签 - 智能SET子句)

[(5). 标签 - 循环遍历](#(5). 标签 - 循环遍历)

[(6). 标签 - SQL片段复用](#(6). 标签 - SQL片段复用)

8.核心总结复盘

[(1). MyBatis 是什么](#(1). MyBatis 是什么)

[(2). 两种 SQL 配置方式](#(2). 两种 SQL 配置方式)

[(3). 基础增删改查(CRUD)](#(3). 基础增删改查(CRUD))

[(4). 字段映射配置](#(4). 字段映射配置)

[(5). 参数传递与占位符](#(5). 参数传递与占位符)

[(6). 数据库连接池](#(6). 数据库连接池)

9.注意事项

[(1). 项目配置](#(1). 项目配置)

[(2). 代码规范](#(2). 代码规范)

[(3). 单元测试](#(3). 单元测试)

[(4). SQL 编写](#(4). SQL 编写)

[(5). 日志与调试](#(5). 日志与调试)


1.什么是MyBatis

MyBatis 是一款基于 Java 的持久层框架,用于简化数据库操作。它通过 XML 或注解配置 SQL 语句,并将 Java 对象与数据库记录映射,避免了手动处理 JDBC 的繁琐流程。

2.入门操作

(1)创建项目

在创建项目时需要添加以下的四个依赖项

(2)数据准备

我在这里使用Navicat编写SQL代码生成表也就是准备好数据,

字段命名规范: 字段名全部小写(windows不区分但是linux系统区分大小写),单词之间用下划线分割

如图所示

(3)配置数据库连接字符串

Mybatis要连接数据库需要在配置文件application.yml中添加4个配置项,分别是:

  • 数据库连接字符串
  • 登录名
  • 登陆密码
  • MySql驱动类
复制代码
application.yml文件内容
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mybatis_test?characterEncoding=utf-
         jdbc:mysql://数据库地址和端口号/连接数据库名?编码参数&useSSl为false是开发环
8&useSSL=false&allowPublicKeyRetrieval=true//连接字符串
境为true是生产环境&allowPublicKeyRetrieval=true(开发环境固定加)
    username: root//登录名
    password: root//登陆密码,如果纯数字,需要加上双引号,如"2222"
    driver-class-name: com.mysql.cj.jdbc.Driver//MySql驱动类一般固定

(4)写持久层代码

到这一步需要清楚SQL代码,不清楚的可以看看本人的另一篇讲解SQL代码的文章

(●'◡'●) MySQL总结

创建表中数据的对象,属性与数据库中表一致

表中必须要有三个字段:自增id ,create_time创建时间 ,update_time更新时间

复制代码
UserInfo类内容
@Data
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}
复制代码
接口UserInfoMapper内容
@Mapper
//类似于@Controller,能在运行时自动生成该接口的实现类,并将其纳入 Spring 容器管理。
public interface UserInfoMapper {
    @Select("select *from user_info")//代表数据库会执行()中的查询操作
    List<UserInfo> selectAll();
}

(5)单元测试

单元测试是针对软件中最小可测试单元(如函数、方法、类)的验证过程,目的是确保代码逻辑在隔离环境下按预期运行。

如何进行单元测试:

在接口处右键 出现下方情况,点击生成, 出现小弹窗之后点击测试

之后会在test文件夹中生成测试用例,在测试用例中可以直接进行测试

复制代码
UserInfoMapperTest内容
@SpringBootTest//提供Spring环境
class UserInfoMapperTest {
    @Autowired//di,从Spring容器中取出对象,赋值给userInfoMapper
    private UserInfoMapper userInfoMapper;
    @Test
    void selectAll() {
       //测试内容,即打印查询到的内容
        List<UserInfo> userInfos = userInfoMapper.selectAll();
        userInfos.forEach(System.out::println);
    }
}

测试结果展示,从数据库中获取到了这四条数据并打印了出来

3.基础操作

(1)打印日志

application.yml中添加配置即可

mybatis:

configuration:

log-impl:org.apache.ibatis.logging.stdout.StdOutImpl

==>右箭头是传递参数信息,<==左箭头是数据库返回的信息

(2)参数传递

UserInfoMapper接口内容

复制代码
@Select("select *from user_info where id=#{id}")//#{id}是 MyBatis 的参数占位符语法,表示此处需要传入一个名为 id的参数。UserInfo selectById(int id);

生成测试用例 用于验证 UserInfoMapper 接口中定义的 selectById(int id) 方法功能。通过传入参数 1,查询 user_info 表中 id1 的记录。

复制代码
@Test
void selectById() {
    UserInfo userInfo = userInfoMapper.selectById(1);
    System.out.println(userInfo);
}

(3)增

向表中插入一条数据,姓名李四,密码hhh,年龄19,性别1

UserInfoMapper接口增加方法

复制代码
@Insert("insert into user_info(username,`password`,age,gender) values(#{username},#{password},#{age},#{gender})")
Integer insert(UserInfo userInfo);//传入userInfo对象为参数

注意事项

  • 确保 UserInfo 类的属性名与 SQL 中的 #{} 占位符名称一致
  • 密码字段使用反引号是因为在数据库中 password 是保留字
  • 方法返回的整数通常用于判断操作是否成功(大于 0 表示成功
复制代码
生成测试类
@Test
void insert() {
    UserInfo userInfo = new UserInfo();
//创建对象,并设置对象信息,传入insert方法中,返回信息是影响的行数
    userInfo.setUsername("李四");
    userInfo.setPassword("hhh");
    userInfo.setAge(19);
    userInfo.setGender(1);
    Integer insert = userInfoMapper.insert(userInfo);
    log.info("影响行数"+insert);
}

结果展示:

(4)删

删除表中id为5的记录

UserInfoMapper接口增加方法

复制代码
@Delete("delete from user_info where id=#{id}")
//()中输入有关删除操作的SQL语句
Integer deleteById(Integer id);

生成测试用例

复制代码
@Test
void deleteById() {
    Integer i = userInfoMapper.deleteById(5);
    log.info("影响行数"+i);
}

结果展示

(5)改

表初始为

现在我要将id为4的username从"wangwu"改成"张三"

UserInfoMapper接口添加方法

复制代码
@Update("update user_info SET username=#{username} where id=#{id}")
Integer updateByUsername(String username,Integer id);

生成测试用例,传入参数

复制代码
@Test
void updateByUsername() {
    Integer result = userInfoMapper.updateByUsername("张三", 4);
    log.info("修改行数"+result);
}

运行结果

(6)查

数据库表中的字段名可能与UserInfo类的属性名不完全一致,比如下面三个字段,可能导致无法自动识别并赋值。这种不一致可能由命名规则或其他因素引起。

但可以通过添加注解明确指定字段与属性之间的映射关系,可以解决自动赋值失败的问题。注解能够直接标明数据库字段对应到哪个类属性。

复制代码
@Results(id="BaseMap",value={
        @Result(column = "update_time",property = "updateTime"),
        @Result(column = "create_time",property = "createTime"),
        @Result(column = "delete_flag",property = "deleteFlag")

})
//该注解 能指明映射关系
//如果其他方法想要复用该注解,只需要在方法上添加@ResultMap("BaseMap")即可
@Select("select *from user_info")
List<UserInfo> selectAll();

结果展示

如果不处理字段名和属性名映射问题,即不添加**@Results**注解,那么为对应上的属性为null

数据库字段命名规则是蛇形即a_b_c,而代码中明明属性规则是小驼峰即aBC,都是固定默认的

因此除了该注解之外,还可以添加下方配置代替@Results注解,并且对所有方法都有效

复制代码
mybatis:
  configuration:
    map-underscore-to-camel-case: true

4.MyBatis XML配置文件

MyBatis支持两种方式编写SQL:XML映射文件和注解(如@Select@Update)。

MyBatis允许两者共存,但同一方法不能同时用XML和注解。优先级规则:注解优先于XML(若两者定义相同方法,注解生效)。

(1)配置连接字符串和MyBatis

复制代码
application.yml内容
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mybatis_test?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 55555
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  mapper-locations: classpath:mybatis/**.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true//配置驼峰自动转换,不需要在乎字段与属性映射

注意:

xml文件必须和yml文件中的mapper-location项相映射

(2)写持久层代码

(2).1添加mapper接口

复制代码
@Mapper
public interface UserInfoXmlMapper {
    List<UserInfo> selectAll();
}

(2).2添加UserInfoMapper.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.bite.mybatis.mapper.UserInfoXmlMapper">
                  //此处是要实现功能的文件的位置,即上面创建的mapper接口位置
<select id="sellectAll(函数名)" resultType="com.example.mybatisdemo.entity.UserInfo(返回类型即对象的位置)">

select*from user_info //中间写对应实现的SQL语句

复制代码
</select>
</mapper>

注意:

1.接口名必须和xml配置中的namespace相映射

2.接口方法名必须和xml配置中<select >中的id名相同

3.安装mybatisx插件之后可以手动操作自动生成<select>中的内容,只用在<select></select>中写SQL语句即可

(2).3单元测试

生成测试用例

复制代码
@SpringBootTest
class UserInfoXmlMapperTest {
    @Autowired
    private UserInfoXmlMapper userInfoXmlMapper;
    @Test
    void selectAll() {
        userInfoXmlMapper.selectAll().forEach(System.out::println);
    }
}

结果展示:

(3)增删改查

操作方法:在接口中声明方法,在xml文件映射并且编写SQL代码,此处SQL代码与之前注解()中的SQL代码编写方式完全相同

接口UserInfoXmlMapper声明方法

复制代码
@Mapper
public interface UserInfoXmlMapper {
    List<UserInfo> selectAll();
    UserInfo selectById(int id);//查
    Integer insert(UserInfo userInfo);//增
    Integer deleteById(Integer id);//删
    Integer updateByUsername(String username,Integer id);//改
}

xml文件映射,并编写SQL代码

复制代码
<?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.mybatisdemo.mapper.UserInfoXmlMapper">
 <select id="selectAll" resultType="com.example.mybatisdemo.entity.UserInfo">
  select *from user_info;
</select>//查

 <select id="selectById" resultType="com.example.mybatisdemo.entity.UserInfo">
  select *from user_info where id=#{id}
 </select>//查

 <insert id="insert">
  insert into user_info(username,`password`,age,gender) values(#{username},#{password},#{age},#{gender})
 </insert>//增

 <delete id="deleteById">
  delete from user_info where id=#{id}
 </delete>//删

 <update id="updateByUsername">
  update user_info SET username=#{username} where id=#{id}
 </update>//改

</mapper>

生成测试用例

复制代码
package com.example.mybatisdemo.mapper;

import com.example.mybatisdemo.entity.UserInfo;
import lombok.extern.slf4j.Slf4j;
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
@Slf4j
class UserInfoXmlMapperTest {
    @Autowired
    private UserInfoXmlMapper userInfoXmlMapper;
    
   @Test
    void selectAll() {
        userInfoXmlMapper.selectAll().forEach(System.out::println);
    }

    @Test
    void selectById() {
        UserInfo userInfo = userInfoXmlMapper.selectById(1);
        System.out.println(userInfo);
    }

    @Test
    void insert() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("小丽");
        userInfo.setPassword("xiaoli");
        userInfo.setGender(1);
        userInfo.setAge(20);
        userInfoXmlMapper.insert(userInfo);
    }

    @Test
    void deleteById() {
        Integer i = userInfoXmlMapper.deleteById(4);
        log.info("修改行数"+i);
    }

    @Test
    void updateByUsername() {
        Integer i = userInfoXmlMapper.updateByUsername("hhh", 1);
        log.info("修改行数"+i);
    }
}

5.#{}和${}区别

在编程中,#{}${} 是两种常见的占位符或插值语法,通常用于字符串模板或动态内容生成。

  • #{}在传String类型参数时会加上引号,而${}不会加引号,需要手动添加
  • #{} 在 SQL 预处理语句(如 MyBatis)中能防止 SQL 注入,因为它会生成参数化查询。
  • ${} 直接拼接字符串,可能存在注入风险,需谨慎使用。
  • #{}是预编译SQL ,${}是即时SQL

能使用尽量使用#{},实在不行使用${},并且需要注意SQL注入的问题

比如传参数为排序/表名,字段名 时不需要添加**"",**因此使用${}

6.数据库连接池

能够管理数据库连接,通过预先创建并维护一定数量的数据库连接,供应用程序按需复用,避免频繁创建和销毁,消耗资源,接下来介绍如何使用

数据库连接池主流有Hikali和Druid,Hikari 现在是 Spring Boot 的默认连接池,Druid 则是阿里巴巴开源的重要项目之一。两者都在持续更新和维护中。

如果想要切换为Druid,添加下方依赖即可

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid-spring-boot-3-starter</artifactId>

<version>1.2.21</version> <!-- 版本号可替换为最新稳定版 -->

</dependency>

如果SpringBoot版本为2.x则添加下方依赖

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid-spring-boot-starter</artifactId>

<version>1.1.17</version>

</dependency>

适用场景

Hikari 适合需要极致性能的轻量级应用或微服务架构。Druid 适合需要全面监控和管理能力的企业级应用,尤其是对数据库操作有严格审计需求的场景。

7.动态SQL

动态SQL是指在程序运行时根据条件或参数 动态生成的SQL语句,而非在代码中直接写死的静态SQL。这种灵活性使得SQL能够适应不同的查询需求,尤其在参数不确定查询条件多变的情况下非常有用。除此之外建议使用xml去写。

比如在数据库中有user_info表,表中有个字段为gender,在插入记录时,如果没有传递参数则默认为0,如图所示

复制代码
关键代码展示(注意红色部分)
测试用例:
@Test
void insert() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("小丽");
    userInfo.setPassword("xiaoli");
    userInfo.setAge(20);
//此处并没有设置gender属性
    userInfoXmlMapper.insert(userInfo);
}

xml配置:

复制代码
<insert id="insert">
 insert into user_info(username,`password`,age,gender) values(#{username},#{password},#{age},#{gender})
</insert>

mapper接口声明方法:

复制代码
Integer insert(UserInfo userInfo);

UserInfo对象:

复制代码
@Data
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

测试用例中未设置gender 属性,但XML配置的insert语句固定包含gender字段,导致数据库接收到NULL而非使用默认值0 。这是由于静态SQL 无法根据参数存在性动态调整字段 , 得到记录如下图所示

此时便需要动态SQL来解决这个问题,能根据传递参数的情况决定SQL代码

只对xml文件中SQL语句的gender参数添加**<if></if>**即可

insert into user_info(username,`password`,age <if test="gender!=null"> ,gender </if> )

values(#{username},#{password},#{age} <if test="gender!=null">,#{gender}</if>)

等效的SQL示例

当gender不为null时:

复制代码
INSERT INTO user_info(username, password, age, gender) 
VALUES(?, ?, ?, ?)

当gender为null时:

复制代码
INSERT INTO user_info(username, password, age) 
VALUES(?, ?, ?)

结果展示:

动态SQL中还有许多除了<if>之外的标签

(1). <if>标签 - 条件判断

功能:根据条件判断是否包含某段SQL片段

语法

复制代码
<if test="条件表达式">
    SQL片段
</if>

示例

复制代码
<select id="findUsers" resultType="User">
    SELECT * FROM users
    WHERE 1=1
    <if test="username != null and username != ''">
        AND username = #{username}
    </if>//如果username不为空,则传递
    <if test="age != null">
        AND age = #{age}
    </if>
</select>

应用场景:可选查询条件、动态字段插入/更新


(2). <trim>标签 - 智能修剪

功能 :仅仅使用<if>可能会导致","多余

该标签可以智能去除SQL语句中多余的关键字(如AND、OR、逗号等)

属性

  • prefix:添加前缀

  • suffix:添加后缀

  • prefixOverrides:去除开头多余的关键字

  • suffixOverrides:去除结尾多余的关键字

示例

复制代码
<insert id="insertUser">
    INSERT INTO users
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="username != null">username,</if>
        <if test="password != null">password,</if>
        <if test="email != null">email,</if>
    </trim>//去除后置逗号,前缀和后缀分别添加(和)
    VALUES
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="username != null">#{username},</if>
        <if test="password != null">#{password},</if>
        <if test="email != null">#{email},</if>
    </trim>
</insert>

(3). <where>标签 - 智能WHERE子句

功能:自动处理WHERE关键字,去除开头多余的AND/OR

示例

复制代码
<select id="findUsers" resultType="User">
    SELECT * FROM users
    <where>
        <if test="username != null">
            AND username = #{username}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
        <if test="email != null">
            AND email LIKE CONCAT('%', #{email}, '%')
        </if>
    </where>
</select>

等价于

复制代码
<trim prefix="WHERE" prefixOverrides="AND |OR ">
    ...
</trim>

(4). <set>标签 - 智能SET子句

功能:用于UPDATE语句,自动处理SET关键字,去除结尾多余的逗号

示例

复制代码
<update id="updateUser">
    UPDATE users
    <set>
        <if test="username != null">username = #{username},</if>
        <if test="password != null">password = #{password},</if>
        <if test="email != null">email = #{email},</if>
        <if test="age != null">age = #{age},</if>
    </set>
    WHERE id = #{id}
</update>

等价于

复制代码
<trim prefix="SET" suffixOverrides=",">
    ...
</trim>

(5). <foreach>标签 - 循环遍历

功能:遍历集合,生成IN查询或批量操作

属性

  • collection:要遍历的集合

  • item:当前元素变量名

  • index:当前索引

  • open:开始符号

  • close:结束符号

  • separator:分隔符

示例

复制代码
<!-- IN查询 -->
<select id="findUsersByIds" resultType="User">
    SELECT * FROM users
    WHERE id IN
    <foreach collection="ids" item="id" open="(" close=")" separator=",">
        #{id}
    </foreach>
</select>

<!-- 批量插入 -->
<insert id="batchInsert">
    INSERT INTO users (username, password) VALUES
    <foreach collection="users" item="user" separator=",">
        (#{user.username}, #{user.password})
    </foreach>
</insert>

(6). <include>标签 - SQL片段复用

功能:引用公共的SQL片段,避免代码重复

定义片段

复制代码
<sql id="userColumns">
    id, username, email, create_time
</sql>

<sql id="userWhere">
    <where>
        <if test="username != null">
          AND username = #{username}
        </if>
        <if test="status != null">
           AND status = #{status}
        </if>
    </where>
</sql>

使用片段

复制代码
<select id="findUsers" resultType="User">
    SELECT 
    <include refid="userColumns"/>
    FROM users
    <include refid="userWhere"/>
</select>

8.核心总结复盘

(1). MyBatis 是什么

  • 基于 Java 的持久层框架,通过 XML 或注解配置 SQL,实现 Java 对象与数据库记录的映射。

  • 简化 JDBC 操作,提升开发效率。

(2). 两种 SQL 配置方式

  • 注解方式 :直接在接口方法上使用 @Select@Insert等注解编写 SQL。

  • XML 方式:通过独立的 XML 文件配置 SQL 语句,支持更复杂的动态 SQL。

  • 优先级 :同一方法若同时存在注解和 XML 配置,注解优先生效

(3). 基础增删改查(CRUD)

  • 增(@Insert/<insert>)、删(@Delete/<delete>)、改(@Update/<update>)、查(@Select/<select>)。

  • 操作返回值通常为影响行数(Integer),查询需指定返回类型(resultType)。

(4). 字段映射配置

  • 数据库字段(如 update_time)与 Java 属性(如 updateTime)的命名差异可通过以下方式解决:

    • 注解 @Results+ @Result显式映射。

    • 全局配置 map-underscore-to-camel-case: true(推荐),自动启用蛇形转驼峰。

(5). 参数传递与占位符

  • #{} :预编译占位符,防止 SQL 注入,自动添加引号(适用于值传递,如 WHERE id=#{id})。

  • ${}:字符串拼接占位符,直接替换文本,需手动处理引号(适用于动态字段名、表名等非值场景)。

(6). 数据库连接池

  • 默认使用 HikariCP(轻量高效)。

  • 可切换为 Druid(功能丰富,支持监控),需添加依赖并配置。

9.注意事项

(1). 项目配置

  • 数据库连接字符串需包含编码参数(characterEncoding=utf-8)和开发环境参数(useSSL=false)。

  • 密码为纯数字时需加双引号(如 password: "123")。

  • XML 文件路径需与 application.ymlmapper-locations配置一致。

(2). 代码规范

  • 实体类需包含基础字段:自增 idcreate_timeupdate_time

  • 数据库字段名推荐全小写+下划线(蛇形),Java 属性使用小驼峰。

  • 敏感字段(如 password)在 SQL 中需用反引号转义。

(3). 单元测试

  • 测试类需加 @SpringBootTest注解以启动 Spring 环境。

  • 通过 @Autowired注入 Mapper 接口,直接调用方法验证逻辑。

(4). SQL 编写

  • 使用 #{}避免 SQL 注入,仅动态表名/字段名等场景用 ${}(需严格校验参数)。

  • XML 中 namespace必须对应 Mapper 接口全路径,id必须与方法名一致。

(5). 日志与调试

  • 开启 MyBatis 日志(log-impl: StdOutImpl)可查看 SQL 执行详情(参数、返回结果)。

  • 注意日志中 ==>(传入参数)和 <==(返回数据)的解读。

相关推荐
Jul1en_2 小时前
【MyBatis/plus】核心配置、插件与 MyBatis-Plus 构造器 Wrapper
mybatis
LiZhen7985 小时前
SpringBoot 实现动态切换数据源
java·spring boot·mybatis
我是Superman丶6 小时前
在 PostgreSQL 中使用 JSONB 类型并结合 MyBatis-Plus 实现自动注入,主要有以下几种方案
数据库·postgresql·mybatis
Pluto_CSND6 小时前
基于mybatis-generator插件生成指定数据表的实体类、xml文件和dao层接口
mybatis
indexsunny8 小时前
互联网大厂Java面试实战:微服务与Spring生态技术解析
java·spring boot·redis·kafka·mybatis·hibernate·microservices
手握风云-9 小时前
JavaEE 进阶第十六期:MyBatis,查询请求的生命周期全景图(一)
java·java-ee·mybatis
独断万古他化10 小时前
【SSM开发实战:博客系统】(二)JWT 登录流程、拦截器实现和用户信息接口落地
spring boot·spring·mybatis·博客系统·项目
Pluto_CSND11 小时前
MyBatis 的 XML 文件中特殊字符的处理
mybatis
独断万古他化12 小时前
【SSM开发实战:博客系统】(一)项目初始化与基础功能实现
spring boot·spring·mybatis·博客系统·项目