文章目录
-
- [一、Mybatis 初识](#一、Mybatis 初识)
-
- [1.1 Mybatis 定义](#1.1 Mybatis 定义)
- [1.2 入门案例](#1.2 入门案例)
- [二、Mybatis 基础操作](#二、Mybatis 基础操作)
-
- [2.1 打印日志](#2.1 打印日志)
- [2.2 参数传递](#2.2 参数传递)
- [2.3 增(Insert)](#2.3 增(Insert))
- [2.4 删(Delete)](#2.4 删(Delete))
- [2.5 改(Update)](#2.5 改(Update))
- [2.6 查(Select)](#2.6 查(Select))
-
- [2.6.1 起别名](#2.6.1 起别名)
- [2.6.2 结果映射](#2.6.2 结果映射)
- [2.6.3 开启驼峰命名](#2.6.3 开启驼峰命名)
- [三、Mybatis XML 配置文件](#三、Mybatis XML 配置文件)
-
- [3.1 配置](#3.1 配置)
- [3.2 入门案例](#3.2 入门案例)
- [3.1 增(Insert)](#3.1 增(Insert))
- [3.2 删(Delete)](#3.2 删(Delete))
- [3.3 改(Update)](#3.3 改(Update))
- [3.4 查(Select)](#3.4 查(Select))
一、Mybatis 初识
1.1 Mybatis 定义
- MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
web应用程序⼀般分为三层,即:Controller、Service、Dao。持久层(Dao)是数据访问层,用来操作数据库。
而 MyBatis 是更简单完成程序和数据库交互的框架,也就是更简单的操作和读取数据库工具。
1.2 入门案例
- 数据准备:
sql
-- 创建表[用户表]
DROP TABLE IF EXISTS user_info;
CREATE TABLE `user_info` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
`username` VARCHAR ( 127 ) NOT NULL,
`password` VARCHAR ( 127 ) NOT NULL,
`age` TINYINT ( 4 ) NOT NULL,
`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-女 0-默认',
`phone` VARCHAR ( 15 ) DEFAULT NULL,
`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now() ON UPDATE now(),
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
-- 添加用户信息
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );
- 创建对应实体类:
java
@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;
}
- 配置数据库连接字符串
Mybatis 中配置连接数据库,需要数据库相关参数配置
Mysql 驱动类
登录名
密码
数据库连接字符串
yaml
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
- 持久层代码
java
@Mapper
public interface UserInfoMapper {
@Select("select * from user_info")
List<UserInfo> selectAll();
}
- 持久层接口的命名规范一般为
XxxMapper @Mapper注解:用于标识这是 MyBatis 中的 Mapper 接口- 程序运行时,框架会自动为该接口生成实现类对象(代理对象),并将其交给 Spring 的 IOC 容器管理
@Select注解:代表一个 select 查询,注解内的内容就是对应方法的具体 SQL 实现
- 单元测试
在创建出来的SpringBoot工程中,在src下的test目录下,已经自动创建好了测试类,可以直接使用这个测试类来进行测试。
java
@SpringBootTest
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void selectAll() {
List<UserInfo> userInfos = userInfoMapper.selectAll();
userInfos.forEach(System.out::println);
}
}
运行结果如下:

二、Mybatis 基础操作
下面详细讲述MyBatis的增,删,改,查操作。
2.1 打印日志
- 在 MyBatis 中,我们可以借助日志查看 SQL 语句的执行、执行时传递的参数,以及最终的执行结果
- 日志功能只需在配置文件中进行配置即可启用
yaml
# 配置打印MyBatis⽇志
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
重新运行可以得到如下内容,传递参数和执行结果:

2.2 参数传递
需求:根据id 查询用户,sql select * from user_info where id = ?。
- 问题:如果 SQL 语句中的
id写为固定数值(如id=4),则只能查询固定对应的数据,无法满足动态查询的需求。 - 解决方案:在
selectById方法中添加参数(id),将方法的参数传递给 SQL 语句。 - 具体用法:使用
#{}的方式获取方法中的参数,从而让 SQL 支持动态数值。
java
@Select("select id,username,`password`,age,gender,phone,delete_flag," +
"create_time,update_time from user_info where id= #{id}")
UserInfo selectById(Integer id);
如果mapper接口方法形参只有⼀个普通类型的参数,#{...}里面的属性名可以随便写,如:#{id}、#{value}。建议和参数名保持⼀致。但是参数有多个时,必须和参数名保持一致。
测试用例:
java
@Test
void selectById() {
UserInfo userInfo = userInfoMapper.selectById(1);
System.out.println(userInfo);
}
结果:

也可以通过 @Param 设置参数的别名,如果使用 @Param 设置别名,#{...} 里面的属性名必须和 @Param 设置的一样,例:
java
@Select("select id,username,`password`,age,gender,phone,delete_flag," +
"create_time,update_time from user_info where id= #{id}")
UserInfo selectById(@Param("id") Integer id);
2.3 增(Insert)
java
@Insert("insertinto user_info (username, `password`, age, gender)" +
"values (#{username},#{password},#{age},#{gender})")
Integer insertUser(UserInfo userInfo);
可以直接使用UserInfo 对象的属性名来获取参数。也可以写出所有属性来获取参数。
此时返回的是执行的行数。
测试:
java
@Test
void insertUser() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("java1");
userInfo.setPassword("java1");
userInfo.setAge(20);
userInfo.setGender(1);
Integer result = userInfoMapper.insertUser(userInfo);
log.info("影响行数:{}",result);
}
新增之后可以刷新数据库查看执行结果。
如果设置了 @Param 属性,#{...}需要使用 参数.属性来获取
@Insert("insert INTO user_info (username, password, age, gender) values (#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender})") Integer insertUser2(@Param("userInfo") UserInfo userInfo);
- 返回主键 @Options
Insert 语句默认返回的是受影响的行数
但有些情况下,数据插入之后,还需要有后续的关联操作,需要获取到新插入数据的 id。如果想要拿到 id ,需要在Mapper 接口的方法上添加一个注解 @Options。
java
@Options(useGeneratedKeys = true,keyProperty = "id") // 获得自增ID,通过注解
@Insert("insertinto user_info (username, `password`, age, gender)" +
"values (#{username},#{password},#{age},#{gender})")
Integer insertUser(UserInfo userInfo);
useGeneratedKeys:这会令 MyBatis 使用 JDBC 的getGeneratedKeys方法来取出由数据库内部生成的主键(比如像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false。keyProperty:指定能够唯一识别对象的属性,MyBatis 会使用getGeneratedKeys的返回值或 insert 语句的selectKey子元素设置它的值,默认值:未设置(unset)
- 注意:设置 useGeneratedKeys=true 之后,方法返回值依然是受影响的行数,自增 id 会设置在上述 keyProperty 指定的属性中。
2.4 删(Delete)
Mapper 接口:
java
@Delete("delete from user_info where id = #{id}")
Integer deleteUserById(Integer id);
测试:
java
@Test
void deleteUserById() {
Integer result = userInfoMapper.deleteUserById(11);
}
2.5 改(Update)
Mapper 接口:
java
@Update("update user_info set gender = #{gender} where id = #{id}")
void updateUserById(Integer gender,Integer id);
测试:
java
@Test
void updateUserById() {
userInfoMapper.updateUserById(0,11);
}
2.6 查(Select)
在上面查询时发现,有几个字段是没有赋值的,只有 Java 对象属性和数据库字段一模一样时,才会进行赋值。查询结果:

从运行结果上可以看到,我们SQL语句中,查询了delete_flag, create_time, update_time,但是这几个属性却没有赋值。
原因分析:
当自动映射查询结果时,MyBatis会获取结果中返回的列名并在Java类中查找相同名字的属性(忽略大小写)。这意味着如果发现了ID列和id属性,MyBatis会将列ID的值赋给id属性

解决办法:
- 起别名
- 结果映射
- 开启驼峰命名
2.6.1 起别名
在SQL 语句中,给列名起别名,保持别名和实体类属性名一样。
java
@Select("SELECT id,username,`password`,age,gender,phone,delete_flag as deleteFlag, " +
"create_time as createTime, update_time as updateTime " +
"from user_info") //起别名
List<UserInfo> selectAll();
2.6.2 结果映射
使用Spring 提供的注解 @Results :
java
@Results(id = "BaseMap",value = {
@Result(column = "delete_flag",property = "deleteFlag"),
@Result(column = "create_time",property = "createTime"),
@Result(column = "update_time",property = "updateTime"),
}) //通过注解映射
@Select("select id,username,`password`,age,gender,phone,delete_flag," +
"create_time,update_time from user_info")
List<UserInfo> selectAll();
如果其他SQL 需要复用这个映射关系,可以给这个Results 定义一个名称,如上id = "BaseMap" ,使用 @ResultMap 注解来复用即可,例:
java
@ResultMap("BaseMap")
@Select("select id,username,`password`,age,gender,phone,delete_flag," +
"create_time,update_time from user_info where id= #{id}")
UserInfo selectById(@Param("id") Integer id);
2.6.3 开启驼峰命名
通常数据库列使用蛇形命名法进行命名(下划线分割各个单词),而 Java 属性一般遵循驼峰命名法约定。为了在这两种命名方式之间启用自动映射,需要将 mapUnderscoreToCamelCase 设置为 true。
yaml
mybatis:
configuration:
map-underscore-to-camel-case: true #配置驼峰自动转换
驼峰命名规则:abc_xyz => abcXyz
- 表中字段名:
abc_xyz - 类中属性名:
abcXyz
Java 代码不做任何处理
通过上面三个方法后,执行查询发现所有字段都可以查询到数据,全部进行正确赋值:

三、Mybatis XML 配置文件
Mybatis 的开发有两种方式:
- 注解
- XML配置文件
3.1 配置
需要进行数据库连接字符串配置和Mybatis 的 XML 文件配置。
yaml
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
username: root
password: whx041223
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/**Mapper.xml # 配置 mybatis xml 文件路径;classpath 对应resources
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 配置打印MyBatis⽇志
map-underscore-to-camel-case: true #配置驼峰⾃动转换
3.2 入门案例
进行持久层代码编写
- 方法定义 Interface,添加Mapper 接口
java
@Mapper
public interface UserInfoXmlMapper {
List<UserInfo> selectAll();
}
- 方法实现,添加UserInfoXMLMapper.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.whx.mybatis.mapper.UserInfoXmlMapper">
<select id="selectAll" resultType="com.whx.mybatis.entity.UserInfo">
select id,username,`password`,age,gender,phone,delete_flag,
create_time,update_time from user_info
</select>
</mapper>
标签的说明:
<mapper>标签:需要指定namespace属性,表示命名空间,值为 mapper 接口的全限定名,包括全包名.类名。<select>查询标签:是用来执行数据库的查询操作的:id:是和 Interface(接口)中定义的方法名称一样的,表示对接口的具体实现方法。resultType:是返回的数据类型,也就是开头定义的实体类。
3.1 增(Insert)
接口:
java
Integer insertUser(UserInfo userInfo);
方法实现:
xml
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into user_info (username, `password`, age, gender)
values (#{username},#{password},#{age},#{gender})
</insert>
返回自增id,接口定义不变,在Mapper.xml 中设置useGeneratedKeys和keyProperty属性。
如果使用 @Param 设置参数名,使用方法和注解类似:
接口:
java
Integer insertUser(@Param("userInfo") UserInfo userInfo);
方法实现:
xml
<insert id="insertUser">
insert INTO user_info (username, `password`, age, gender)
values (#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender})
</insert>
3.2 删(Delete)
接口:
java
Integer deleteUserById(Integer id);
方法实现:
xml
<delete id="deleteUserById">
delete from user_info where id = #{id}
</delete>
3.3 改(Update)
接口:
java
void updateUserById(Integer gender,Integer id);
方法实现:
xml
<update id="updateUserById">
update user_info set gender = #{gender} where id = #{id}
</update>
3.4 查(Select)
和注解方式一样,使用XML方式查询也存在数据封装的问题。

结果显示:deleteFlag,createTime,updateTime也没有进行赋值。
解决办法和注解一样:
- 起别名
- 结果映射
- 开启驼峰命名
其中1,3的解决办法和注解一样,结果映射在XML中的方法:
xml
<resultMap id="BaseMapXml" type="com.whx.mybatis.entity.UserInfo">
<id property="id" column="id"></id>
<result property="deleteFlag" column="delete_flag"></result>
<result property="createTime" column="create_time"></result>
<result property="updateTime" column="update_time"></result>
</resultMap>
<select id="selectAll" resultMap="BaseMapXml">
select id,username,`password`,age,gender,phone,delete_flag,
create_time,update_time from user_info
</select>
解析:

总结:
本文围绕 MyBatis 轻量级持久层框架展开,总结其核心使用要点。MyBatis 通过注解或 XML 配置简化 JDBC 冗余代码,支持自定义 SQL 与对象映射,兼顾开发效率与灵活性。入门环节涵盖数据库准备、实体类定义、配置编写、Mapper 接口开发及单元测试,可快速搭建运行环境。基础操作中,日志配置能查看 SQL 执行细节,#{}实现单参数、多参数等场景的动态绑定,增删改查操作可通过注解或 XML 配置获取自增主键,查询结果映射提供起别名、resultMap、驼峰命名转换三种方案,解决数据库与 Java 命名适配问题。XML 配置适配复杂 SQL 场景,掌握这些核心点即可应对日常持久层开发。