跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Spring 配置文件与 MyBatis 基础用法

Spring Boot 配置文件支持 properties 和 yml 格式,各有优劣。MyBatis 作为持久层框架,支持注解和 XML 配置方式。通过 @Value 注入配置,使用 @Mapper 注解及 XML 映射文件进行 CRUD 操作,掌握动态 SQL 标签(if, trim, where, set, foreach)的使用,以及主键返回和预编译 SQL 防止注入的原理。

利刃发布于 2026/2/7更新于 2026/6/227 浏览
Spring 配置文件与 MyBatis 基础用法

1. 配置文件

1.1 概述

计算机配置文件:用于存储系统、应用程序的设置信息,通常以文本或结构化数据格式 (如 JSON、XML、INI 等) 保存。其核心功能包括但不限于:参数定制:允许用户或管理员调整软件或硬件的运行参数;环境适配:根据不同设备或场景加载特定配置 (如开发/生产环境);持久化存储:确保重启后设置仍生效。

SpringBoot 配置文件:SpringBoot 支持多种类型的配置文件,常见的格式包括 properties、yaml 和 yml,主要用于集中管理应用程序的各种配置参数,简化部署和开发过程中的环境切换。YAML 和 YML 本质上是相同的文件格式,只是文件扩展名的不同,两者在功能和使用上没有区别。

1.2 properties

properties 配置文件是最早期的配置文件格式,也是创建 SpringBoot 项目默认的配置采用常见的键值对格式 (key=value),支持 # 开头的注释。

#应用程序名称
spring.application.name=configuration
#应用程序端口号
server.port=8080
#数据库连接信息
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/database_name?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root

1.3 yml

采用键值对格式 (key: value),冒号后必须有空格;数据序列化格式,通过缩进表示层级关系;支持 # 开头的注释。

spring:
  application:
    #应用程序名称
    name: configuration
  #数据库连接信息
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/database_name?characterEncoding=utf8&useSSL=false
    username: root
    password: root
  #应用程序端口号
  server:
    port: 8080
mybatis:
  configuration:
    map-underscore-to-camel-case: true

1.4 优缺点对比

properties 优点:语法简单直观,采用 key=value 形式,适合初学者快速上手;与 Java 生态兼容性极强。 缺点:缺乏层次结构,复杂配置时容易冗余(如 spring.datasource 前缀重复);不支持数据类型定义,所有值均为字符串,需手动转换。

yml 优点:层次化结构清晰,通过缩进表示层级,适合复杂配置场景;支持数据类型 (如布尔值、数字),减少手动类型转换。 缺点:格式错误易导致解析失败 (容易忽略冒号后空格);部分旧版工具链兼容性较差,需额外依赖解析库。

注:SpringBoot 同时支持两种格式,混合使用时若 key 重复,properties 优先级高于 yml。

1.5 @Value 注解

作用:是 Spring 框架提供了一个@Value 注解 (org.springframework.beans.factory.annotation.Value),用于将外部配置文件中的值注入到 Spring 管理的 Bean 中。

示例:(properties 和 yml 的读取方式相同)

package org.example.configuration.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {
    @Value("${spring.application.name}")
    private String applicationName;

    @Value("${server.port}")
    private Integer port;

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    public void print() {
        System.out.println("applicationName=" + applicationName);
        System.out.println("port=" + port);
        System.out.println("url=" + url);
        System.out.println("username=" + username);
        System.out.println("password=" + password);
    }
}
package org.example.configuration;

import org.example.configuration.config.Config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class ConfigurationApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(ConfigurationApplication.class, args);
        Config config = context.getBean(Config.class);
        config.print();
    }
}

运行结果: applicationName=configuration port=8080 url=jdbc:mysql://127.0.0.1:3306/database_name?characterEncoding=utf8&useSSL=false username=root password=root

2. MyBatis

2.1 概述

MyBatis是一款优秀的持久层框架,支持自定义 SQL、存储过程、高级映射以及多种配置方式。它消除了几乎所有的 JDBC 代码和参数的手动设置以及结果集的检索。

支持存储过程:指的是数据库管理系统 (DBMS) 允许用户创建、存储和执行存储过程的能力。存储过程是一组预编译的 SQL 语句,存储在数据库中,可以被应用程序调用执行。 支持高级映射:指通过配置或注解实现复杂 SQL 查询结果与 Java 对象之间的灵活转换。其核心目标是简化数据库关联操作,提升开发效率。 支持多种配置方式:MyBatis 支持注解和 XML 两种配置方式。

在这里插入图片描述

2.2 前置操作

引入依赖:Spring Web,Mybatis Framework,MySQL Driver,Lombok

在这里插入图片描述

在 application.properties/yml 中添加数据库连接信息:

#应用程序名称
spring.application.name=configuration
#应用程序端口号
server.port=8080
#数据库连接信息
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/database_name?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
#自动驼峰转换
mybatis.configuration.map-underscore-to-camel-case=true
spring:
  application:
    name: configuration
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/database_name?characterEncoding=utf8&useSSL=false
    username: root
    password: root
  server:
    port: 8080
mybatis:
  configuration:
    map-underscore-to-camel-case: true

SQL 命名规范:采用下划线分隔单词 (如 order_detail) Java 命名规范:大驼峰/小驼峰

2.3 注解

2.3.1 配置
  1. 创建一个接口,并使用 @Mapper 注解修饰
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BlogMapper {
    //其他代码
}

@Mapper 注解:允许开发者直接在接口方法上通过注解配置 SQL 语句,无需编写 XML 映射文件。适用于简单 SQL 场景,能显著减少配置量。

  1. 初始化数据
create table blog (
    id int primary key auto_increment,
    name varchar(128),
    age int
);
insert into blog values (null,'刘备',30),(null,'关羽',28),(null,'张飞',25);
  1. 创建对应实体类
import lombok.Data;

@Data
public class PersonInfo {
    private Integer id;
    private String name;
    private Integer age;

    public PersonInfo(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public PersonInfo() {
    }
}
2.3.2 CRUD
import com.example.spring_mybatis.model.PersonInfo;
import org.apache.ibatis.annotations.*;

@Mapper
public interface BlogMapper {
    @Select("select * from blog")
    List<PersonInfo> getPersonInfoAll();

    @Insert("insert into blog values (#{id},#{name},#{age})")
    Integer addPerson(PersonInfo person);

    @Update("update blog set name = #{name},age = #{age} where id = #{id}")
    Integer updatePerson(PersonInfo personInfo);

    @Delete("delete from blog where id = #{id}")
    Integer deletePerson(Integer id);
}

按住 alt+insert,可在 test 目录下生成以上方法的测试方法

import com.example.spring_mybatis.model.PersonInfo;
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 java.util.List;

@SpringBootTest
@Slf4j
class BlogMapperTest {
    private final BlogMapper blogMapper;

    @Autowired
    public BlogMapperTest(BlogMapper blogMapper) {
        this.blogMapper = blogMapper;
    }

    @Test
    void getPersonInfoAll() {
        List<PersonInfo> personInfoAll = blogMapper.getPersonInfoAll();
        log.info("查询成功,personInfoAll:{}",personInfoAll.toString());
    }

    @Test
    void addPerson() {
        Integer ret = blogMapper.addPerson(new PersonInfo(null,"赵云",25));
        log.info("添加成功,影响行数:{}",ret.toString());
    }

    @Test
    void updatePerson() {
        Integer ret = blogMapper.updatePerson(new PersonInfo(1,"刘备",35));
        log.info("更新成功,影响行数:{}",ret.toString());
    }

    @Test
    void deletePerson() {
        Integer ret = blogMapper.deletePerson(4);
        log.info("删除成功,影响行数:{}",ret.toString());
    }
}
2.3.3 @Param

作用:用于在 Mapper 接口方法中为形式参数指定名称。当方法有多个参数时,通过该注解明确 SQL 中引用的参数名,避免依赖参数顺序。

@Mapper
public interface BlogMapper {
    @Update("update blog set name = #{name},age = #{age} where id = #{id}")
    Integer updatePersonInfo(@Param("id")Integer userId,@Param("name")String userName,@Param("age")Integer userAge);
}
@SpringBootTest
@Slf4j
class BlogMapperTest {
    private final BlogMapper blogMapper;

    @Autowired
    public BlogMapperTest(BlogMapper blogMapper) {
        this.blogMapper = blogMapper;
    }

    @Test
    void updatePersonInfo() {
        Integer ret = blogMapper.updatePersonInfo(1,"刘玄德",30);
        log.info("更新成功,影响行数:{}",ret.toString());
    }
}

在这里插入图片描述

2.4 xml

2.4.1 配置
  1. 创建一个接口,并使用 @Mapper 注解修饰
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BlogXMLMapper {
    //其他代码
}
  1. 配置 mybatis 的 xml 文件路径
mybatis:
  mapper-locations: classpath:mybatis/**Mapper.xml

配置 mybatis 的 xml 文件路径,标识位于 resources/mybatis 路径下任何以 Mapper 结尾的 xml 文件为 mybatis 的配置文件。

在这里插入图片描述

  1. 在 resources/mybatis 路径下创建以 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.example.spring_mybatis.mapper_blog.BlogXMLMapper"></mapper>
2.4.2 示例

在接口中声明方法

import com.example.spring_mybatis.model_blog.PersonInfo;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;

@Mapper
public interface BlogXMLMapper {
    List<PersonInfo> getPersonInfoAll();
}

在对应 xml 文件中实现接口方法

  • id:是 MyBatis 映射文件中 SQL 语句的唯一标识符。需与 Mapper 接口中的方法名一致,保证映射正确。
  • resultType:指定 SQL 查询结果映射的 Java 对象类型,需为全限定类名。
<mapper namespace="com.example.spring_mybatis.mapper_blog.BlogXMLMapper">
    <select id="getPersonInfoAll" resultType="com.example.spring_mybatis.model_blog.PersonInfo">
        select * from blog
    </select>
</mapper>

按住 alt+insert,可在 test 目录下生成以上方法的测试方法

import com.example.spring_mybatis.model_blog.PersonInfo;
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 java.util.List;

@SpringBootTest
@Slf4j
class BlogXMLMapperTest {
    private final BlogXMLMapper blogXMLMapper;

    @Autowired
    public BlogXMLMapperTest(BlogXMLMapper blogXMLMapper) {
        this.blogXMLMapper = blogXMLMapper;
    }

    @Test
    void getPersonInfoAll() {
        List<PersonInfo> personInfoAll = blogXMLMapper.getPersonInfoAll();
        log.info("查询成功,personInfoAll:{}",personInfoAll.toString());
    }
}

运行结果:

在这里插入图片描述

2.5 动态 SQL

动态 SQL:指在程序运行时根据条件或参数动态生成的 SQL 语句。与静态 SQL 相比,动态 SQL 更具灵活性,适用于需要根据不同条件构建查询的场景。例如,在某些 web/app 进行账号注册时会出现非必填选项。MyBatis 的注解和 XML 两种方式都能实现动态 SQL,但 XML 较为方便,所以下文使用 XML 来实现动态 SQL。

2.5.1 trim 标签

作用:用于自定义字符串截取规则。包含四个属性:prefix:最终结果添加前缀;suffix:最终结果添加后缀;prefixOverrides:去除首部指定内容;suffixOverrides:去除尾部指定内容。

2.5.2 if 标签

作用:用于条件判断,通常在 where 或 set 语句中使用。当 test 表达式的值为 true 时,包含标签内的 SQL 片段。

<insert id="addPersonInfo">
    insert into blog 
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null"> id, </if>
        <if test="name != null"> name, </if>
        <if test="age != null"> age, </if>
    </trim> 
    values 
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null"> #{id}, </if>
        <if test="name != null"> #{name}, </if>
        <if test="age != null"> #{age}, </if>
    </trim>
</insert>
2.5.3 where 标签

作用:替代 SQL 中的 where 关键字。当 if 条件成立时才会加入 SQL 片段,并自动去除第一个子句的 and/or。

<select id="getPersonInfoByNameAndAge">
    select * from blog 
    <where>
        <if test="name != null"> and name = #{name} </if>
        <if test="age != null"> and age = #{age} </if>
    </where>
</select>
2.5.4 set 标签

作用:用于 update 语句。当 if 条件成立时才会加入 SQL 片段,并自动去除最后一个子句的逗号。

<update id="updatePersonInfo">
    update blog 
    <set>
        <if test="name != null"> name = #{name}, </if>
        <if test="age != null"> age = #{age}, </if>
    </set>
    <where> and id = #{id} </where>
</update>
2.5.5 foreach 标签

作用:用于集合遍历。主要属性:collection:集合参数名;item:当前元素变量名;open/close:包围符号;separator:分隔符。

@Test
void getPersonInfoById(){
    ArrayList<Integer> ids = new ArrayList<>();
    ids.add(1); ids.add(2); ids.add(3);
    List<PersonInfo> personInfoById = blogXMLMapper.getPersonInfoById(ids);
    System.out.println(personInfoById);
}
<select id="getPersonInfoById" resultType="com.example.spring_mybatis.model_blog.PersonInfo">
    select * from blog where id in 
    <foreach collection="ids" item="id" open="(" close=")" separator=",">
        #{id} 
    </foreach>
</select>
2.5.6 include 标签

作用:用于引用 SQL 片段,通过 refid 指定要引用的片段 id。需配合 sql 标签使用,实现代码复用。

<sql id="collection"> id,name,age </sql>
<select id="getPersonInfoAll" resultType="com.example.spring_mybatis.model_blog.PersonInfo">
    select <include refid="collection"></include> from blog 
</select>

2.6 主键返回

主键返回:指在数据库插入操作后,自动获取刚插入记录的主键值。在 MyBatis 中使用注解和 XML 都能获取到返回的主键。

1.注解实现

@Mapper
public interface BlogMapper {
    @Options(useGeneratedKeys =true,keyProperty ="id")
    @Insert("insert into blog values (#{id},#{name},#{age})")
    Integer addPerson(PersonInfo person);
}
@SpringBootTest
@Slf4j
class BlogMapperTest {
    private final BlogMapper blogMapper;

    @Autowired
    public BlogMapperTest(BlogMapper blogMapper) {
        this.blogMapper = blogMapper;
    }

    @Test
    void addPerson(){
        PersonInfo personInfo = new PersonInfo(null,"黄忠",60);
        Integer ret = blogMapper.addPerson(personInfo);
        log.info("添加成功,影响行数:{},返回的主键值:{}",ret.toString(),personInfo.getId());
    }
}

在这里插入图片描述

2.通过 xml 实现

@SpringBootTest
@Slf4j
class BlogXMLMapperTest {
    private final BlogXMLMapper blogXMLMapper;

    @Autowired
    public BlogXMLMapperTest(BlogXMLMapper blogXMLMapper) {
        this.blogXMLMapper = blogXMLMapper;
    }

    @Test
    void addPersonInfo(){
        PersonInfo personInfo = new PersonInfo();
        personInfo.setAge(40);
        personInfo.setName("曹操");
        Integer ret = blogXMLMapper.addPersonInfo(personInfo);
        log.info("添加成功,影响行数:{},返回的主键值:{}",ret.toString(),personInfo.getId());
    }
}
<insert id="addPersonInfo" useGeneratedKeys="true" keyProperty="id">
    insert into blog 
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null"> id, </if>
        <if test="name != null"> name, </if>
        <if test="age != null"> age, </if>
    </trim> 
    values 
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null"> #{id}, </if>
        <if test="name != null"> #{name}, </if>
        <if test="age != null"> #{age}, </if>
    </trim>
</insert>

在这里插入图片描述

2.7 预编译/即时 SQL

预编译 SQL(Prepared Statements):SQL 语句在程序运行前被预先编译并存储在数据库中。执行时只需传递参数,无需重新编译 SQL 语句。安全性高:通过参数化查询避免 SQL 注入攻击。性能优化:编译一次,多次执行,减少数据库开销。

即时 SQL(Dynamic SQL):在程序运行时动态生成并立即编译执行,每次执行都可能涉及完整的 SQL 解析和编译过程。灵活性高:可根据运行时条件动态拼接 SQL 语句。潜在风险:直接拼接用户输入可能导致 SQL 注入。性能开销:每次执行需重新编译。

#占位符会使用预编译机制,将参数值安全地绑定到 SQL 语句中,防止 SQL 注入攻击。MyBatis 会将#替换为?,然后通过 JDBC 的预编译功能设置参数值。 $占位符直接进行字符串替换,将参数值拼接到 SQL 语句中,不会进行预编译或转义处理。

SQL 注入攻击:当恶意输入" 'or 1 = '1 "时

1.预编译 SQL

@Select("select * from blog where name= #{name}")
List<UserInfo> queryByName(String name)

预编译 SQL 会根据参数的类型判断是否需要加引号,上述 name 参数是 String 类型,需要加引号,这就是参数化查询的作用。最终 SQL:

select * from blog where name = " 'or 1='1 ";

2.即时 SQL

@Select("select * from blog where name= '${name}'")
List<UserInfo> queryByName(String name)

即时 SQL 不会判断参数类型从而是否添加引号,所以需要手动加上单引号。最终 SQL:

select * from blog where name =''or1='1';

因为 1=1 是恒等式,所以该表的数据会被全部查询出来,这就是 SQL 注入。

目录

  1. 1. 配置文件
  2. 1.1 概述
  3. 1.2 properties
  4. 1.3 yml
  5. 1.4 优缺点对比
  6. 1.5 @Value 注解
  7. 2. MyBatis
  8. 2.1 概述
  9. 2.2 前置操作
  10. 2.3 注解
  11. 2.3.1 配置
  12. 2.3.2 CRUD
  13. 2.3.3 @Param
  14. 2.4 xml
  15. 2.4.1 配置
  16. 2.4.2 示例
  17. 2.5 动态 SQL
  18. 2.5.1 trim 标签
  19. 2.5.2 if 标签
  20. 2.5.3 where 标签
  21. 2.5.4 set 标签
  22. 2.5.5 foreach 标签
  23. 2.5.6 include 标签
  24. 2.6 主键返回
  25. 2.7 预编译/即时 SQL
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • OpenClaw 多 Agent 多 Discord 频道配置实战指南
  • Stable Diffusion 3.5 云端部署方案:老旧 Windows 电脑运行指南
  • LangChain 消息处理详解:缓存、过滤、合并与流式输出
  • NewBie-image-Exp0.1 动漫 AI 绘画镜像快速入门
  • 车辆监控管理系统:后端 API、Web 后台与移动端应用
  • Clawdbot 结合 Qwen3-32B 在 HR 与 IT 运维场景的落地实践
  • LangChain 大模型应用开发:自定义 LLM 封装指南
  • ComfyUI Manager 使用指南:插件与模型管理优化
  • 未来人工智能领域七大新兴职业岗位解析
  • LLaMA 大模型微调实践与调优经验
  • Windows WSL 下 AMD 显卡部署 Stable Diffusion WebUI 与 ComfyUI
  • AMD 显卡在 Windows WSL 下部署 Stable Diffusion(WebUI 与 ComfyUI)
  • Rust 微服务架构实战:gRPC 通信、服务发现与容器编排
  • Python 微服务开发实战:架构拆分、服务交互与安全部署
  • C++ 函数重载、隐藏与覆盖详解
  • ROS2 从零认识 URDF:机器人模型描述的说明书
  • Ultralytics Utils 核心子模块代码解析:autobatch、autodevice 等
  • 复刻 Moji 2.0 小智 AI 桌面机器人,基于乐鑫 ESP32 开发板
  • 无人机路径规划算法详解
  • Java 量化实战:股票详细信息实时获取与多数据源架构

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online