数据库准备

我们先准备一个数据库和表,比如:
mybatisdb数据库
create table user(id int primary key auto_increment,name char(10),age int);
2025-08-26T01:32:29.png

SpringBoot项目创建创建,需要依赖Spring Web,MyBatis Framework,MySQL Driver

2025-08-26T01:48:08.png
2025-08-26T01:49:03.png
2025-08-26T01:50:15.png
如下pom.xml
2025-08-26T02:23:17.png

配置环境和使用方法

先在application.yml文件配置好mysql连接配置和mybatis的配置

spring:
  application:
    name: mybatis

  profiles:
    active: dev

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.database}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.obj.mybatis.entity
  configuration:
    map-underscore-to-camel-case: true #开启下划线转驼峰命名
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印 SQL 日志(开发环境用)

这里的
classpath:mapper/*.xml 就是xml文件目录
2025-08-26T07:37:18.png
这里的type-aliases-package: com.obj.mybatis.entity 就是让mybatis的xml文件里面,
接收参数的parameterType不写全称的情况下,能识别到entity 下面的实体类
2025-08-26T07:29:02.png
如果不写这个的话,那么就得写全称
2025-08-26T07:29:25.png

不然的话,会找不到这个类型
2025-08-26T07:24:46.png

application-dev.yml自己去配置

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    host: localhost
    port: 3306
    database: mybatisdb
    username: root
    password: 123456

配置好以后

自己写个包存放接口,方法都是关于数据库操作的

2025-08-26T07:46:04.png
以前的话,使用接口操作数据库可以使用注解来操作,比如查询
2025-08-26T07:50:02.png
使用mybatis就可以动态的去对应的映射文件查询
2025-08-26T07:51:29.png

xml文件的编写和关联方法

在resource目录创建一个mapper文件夹,里面存放以后的xml
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.obj.mybatis.mapper.userMapper">
 
</mapper>

<mapper namespace=的namespace就是指定这个接口的位置,用来映射此文件
2025-08-26T07:43:17.png

如果Mapper里面的xml的sql语句爆红,找不到表,那么IDEA连接一下数据库,不连接也不影响,只是会爆红和看不到一些提示
2025-08-26T06:42:11.png
连接如下:
2025-08-26T06:43:51.png
2025-08-26T06:45:11.png
填好消息后测试能连接就直接应用,确定
2025-08-26T06:47:07.png
这样就不暴红了
2025-08-26T06:47:38.png

一些mybatis的使用语法

简单查询所有数据语句

其实这种简单的可以直接使用ibatis的注解上方写语句就行了,下面演示mybatis的
首先数据库表如下
2025-08-26T08:05:03.png
创建一个接口
2025-08-26T08:04:32.png
再到对应的xml文件编写语句

<select id="userList" resultType="com.obj.mybatis.entity.user">
 select *from user
</select>

这里的id (userList)就是接口的方法名称, resultType="com.obj.mybatis.entity.user"就是返回的结构类型
2025-08-26T08:11:49.png

写一个测试类型测试

package com.obj.mybatis;
import com.obj.mybatis.entity.user;
import com.obj.mybatis.mapper.userMapper;
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
public class test {

    @Autowired
    private userMapper userMapper;

@Test
public void test(){
    List<user> list=userMapper.userList();
    System.out.println("======list======");
    for (user user : list) {
        System.out.println(user);
        System.out.println("======id======"+user.getId());
        System.out.println("======name======"+user.getName());
    }
}


}

测试类型使用@Autowired,所以需要先启动springboot项目来联系上下文,才能再测试
2025-08-26T08:15:15.png
这个就是结果,上面的sql日志是因为之前在application.yml设置了
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl才有的

动态查询

假设你有一个 “用户列表查询接口”,支持按 userId(用户 ID)、name(用户名)、age(年龄)筛选,且这三个参数都是非必填(用户可填可不填)。
如果不用 ,SQL 会写成:

<!-- 错误写法:即使参数为 null,也会拼接条件,导致查询结果为空 -->
<select id="findUsers" resultType="User">
    SELECT * FROM user
    WHERE user_id = #{userId}  <!-- 若 userId 为 null,会变成 user_id = null,SQL 语法无效 -->
      AND name = #{name}      <!-- 若 name 为 null,同样无效 -->
      AND age = #{age}
</select>

标签优化后(只拼接参数有效的条件):

<select id="findUsers" resultType="User">
    SELECT * FROM user
    <where>  <!-- <where> 标签会自动处理多余的 AND/OR -->
        <!-- 只有当 userId 不为 null 时,才拼接 "and user_id=#{userId}" -->
        <if test="userId != null">
            and user_id = #{userId}
        </if>
        <!-- 只有当 name 不为 null 且不为空字符串时,才拼接姓名条件 -->
        <if test="name != null and name != ''">
            and name like concat('%', #{name}, '%')  <!-- 模糊查询 -->
        </if>
        <!-- 只有当 age 不为 null 时,才拼接年龄条件 -->
        <if test="age != null">
            and age = #{age}
        </if>
    </where>
</select>

效果:

如果用户只传 userId=1 → SQL 为 SELECT * FROM user WHERE user_id = 1。
如果用户传 name="张三" → SQL 为 SELECT * FROM user WHERE name like '%张三%'。
如果用户传 age=20 且 name="李四" → SQL 为 SELECT * FROM user WHERE name like '%李四%' and age = 20。
如果用户什么都不传 → SQL 为 SELECT * FROM user(查询所有数据)。

好,再回到我们的数据库

 <select id="selects" resultType="com.obj.mybatis.entity.user">
select *from user
<where>
 <if test="name!=null">
and name=#{name}
 </if>
 <if test="age!=null">
  and age=#{age}
 </if>
</where>
 </select>

比如我们要查询,大王这个昵称的数据,另一个是查询大王,age为10的数据
2025-08-26T09:35:19.png
如果不使用动态条件查询
2025-08-26T09:37:59.png

单条数据插入

<insert id="insertUser" parameterType="com.obj.mybatis.entity.user">
insert into user(name,age) values(#{name},#{age})
</insert>

2025-08-26T08:20:22.png
参数实体类型
下方使用#{参数名称}来接收实体类里面的参数
运行测试结果
2025-08-26T08:32:06.png
2025-08-26T08:32:19.png
如果不使用实体类来接收参数,那么可以在接口那边使用@Param来指定参数,然后在#{name}接收
2025-08-26T08:37:03.png
2025-08-26T08:37:24.png

批量操作(如插入)

 <insert id="insertBatch" parameterType="java.util.List">
 insert into user(name,age) values
<foreach collection="list" item="else_name" separator=",">
(#{else_name.name},#{else_name.age})
</foreach>
</insert>

这里的以List数据为例
parameterType="java.util.List"是接收的数据类型,也可以写成别名 parameterType="list">
使用foreach来遍历容器,这个容器就是list同上,然后遍历的每一个对象使用item="else_name" 命名,操作完一条数据以后,使用separator=","来在sql语句后方加一个,间隔.如insert into user(name,age) values (?,?) , (?,?)
下方(#{else_name.name},#{else_name.age})就是取出每一个遍历子对象的对应元素
2025-08-26T09:03:40.png
2025-08-26T09:04:07.png

一些xml标签

resultMap

为什么需要 resultMap 标签?

 resultMap 的核心作用是定义数据库字段与 Java 实体类属性之间的映射关系,主要解决两类问题:

字段名与属性名不一致数据库表字段通常使用下划线命名(如 create_time),而 Java 实体类常用驼峰命名(如 createTime)。虽然可以通过配置 map-underscore-to-camel-case: true 自动转换简单场景,但复杂场景(如字段名与属性名完全不同,如 db_name 对应 userName)仍需 resultMap 手动映射。

 复杂关联查询当查询涉及多表关联(如一对一、一对多)时,需要通过 resultMap 定义关联关系(如 association 映射单个对象、collection 映射集合),MyBatis 才能正确将查询结果封装为嵌套对象。
<?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.xy.mybatisapdemo.mapper.UserMapper">

    <resultMap id="UserResultMap" type="com.xy.mybatisapdemo.entity.User">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="age" property="age"/>
        <result column="email" property="email"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>
    <select id="findAll" resultMap="UserResultMap">
        select * from user
    </select>

</mapper>
注意引用的时候是使用resultMap="UserResultMap",而resultType是指向实体类