MyBatis注解方式:从CRUD到数据映射的全面解析

devtools/2025/3/29 3:24:24/

目录

  • 1. MyBatis是什么?
  • 2.准备工作
    • 2.1创建工程
    • 2.2 数据准备
    • 2.3 持久层代码
    • 2.4 单元测试
  • 3.Mybatis的增删改查操作(使用注解方式)
    • 3.1 增(insert)
    • 3.2 删(delete)
    • 3.3 改(update)
    • 3.4 查(select)
  • 4.总结

1. MyBatis是什么?

MyBatis 是一个功能强大的持久层框架,专注于简化数据库操作。它通过配置文件或注解来管理 SQL 语句,支持动态 SQL,使开发更加灵活和高效。与 Hibernate 等 ORM(对象关系映射)框架不同,MyBatis 更加注重 SQL 的控制,允许开发者直接编写和优化 SQL 语句。
在这里插入图片描述


简单来说 MyBatis 是更简单完成程序和数据库交互的框架,也就是更简单的操作和读取数据库工具
接下来,我们就通过⼀个入门程序,让大家感受⼀下通过Mybatis如何来操作数据库。

2.准备工作

Mybatis操作数据库的步骤:

  1. 准备工作(创建springboot工程、数据库表准备、实体类)
  2. 引⼊Mybatis的相关依赖,配置Mybatis(数据库连接信息)
  3. 编写SQL语句(注解/XML)
  4. 测试

2.1创建工程

创建springboot工程,并导入 mybatis的起步依赖、mysql的驱动包。
在这里插入图片描述


项目工程创建完成后,自动在pom.xml文件中,导入Mybatis依赖和MySQL驱动依赖。

java"><!--	Mybatis 依赖包	--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.4</version></dependency>
<!--数据库驱动--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency>

2.2 数据准备

创建用户表(这里使用的是Navicat)

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;-- 使用数据数据
USE mybatis_test;-- 创建表[用户表]
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' );

在这里插入图片描述
成功创建。

创建对应的实体类UserInfo

java">import lombok.Data;
import java.util.Date;
@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驱动类
• 登录名
• 密码
• 数据库连接字符串

application.yml文件, 配置内容如下:

java"># 数据库连接配置datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver

也可以用.porperties配置文件进行配置,前面文章有介绍,本篇文章统一使用yml配置文件。


注意事项:
如果使用 MySQL 是 5.x 之前的使用的是"com.mysql.jdbc.Driver",如果是大于 5.x 使用的
是“com.mysql.cj.jdbc.Driver

2.3 持久层代码

创建一个Mapper接口(比如UserInfoMapper)

在这里插入图片描述

java">import com.sliqvers.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
// @Mapper 交给spring 进行管理@Mapper
public interface UserInfoMapper {@Select("SELECT * FROM user_info")List<UserInfo> selectAll();
}

Mybatis的持久层接口规范⼀般都叫 XxxMapper。
@Mapper注解:表⽰是MyBatis中的Mapper接口,交给Spring进行管理。
• 程序运行时, 框架会自动生成接口的实现类对象(代理对象),并给交Spring的IOC容器管理。
• @Select注解:代表的就是select查询,也就是注解对应方法的具体实现内容。


2.4 单元测试

在创建出来的SpringBoot工程中,在src下的test目录下,已经自动帮我们创建好了测试类 ,我们可以
直接使用这个测试类来进行测试。

java">import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UserInfoMapperTest {@Autowired
private UserInfoMapper userInfoMapper;@Testvoid selectAll() {System.out.println(userInfoMapper.selectAll());}
}

解释:
1.@Spring boot Test 加载Spring运行环境
2.@Autowired注解:为UserInfo进行赋值,否则userInfo为空,则程序报错。
3.@Test注解:这是一个测试方法,可以在测试类进行测试。
启动测试观察结果:
在这里插入图片描述
可以看到成功了。

idea 自动生成测试类的方法:
在这里插入图片描述


3.Mybatis的增删改查操作(使用注解方式)

在学习这些操作之前, 我们先来学习MyBatis日志打印
在前面的运行结果可以看到
在这里插入图片描述
这样子的日志并不直观,那怎么办呢?我们进行一下Mybatis的日志打印配置(在.yml文件当中添加):

java">mybatis:configuration: # 配置打印 MyBatis日志log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

运行结果:
在这里插入图片描述
可以看到打印出来的结果比之前的打印结果更加直观了


3.1 增(insert)

增加之前:
在这里插入图片描述
SQL语句:

insert into user_info (username, `password`, age, gender, phone) values
("张三","张三",19,1,"1646566787");

java代码:

java">@Mapper
public interface UserInfoMapper {//插入@Insert("insert into user_info (username, password, age,phone) values (#{username},#{password},#{age},#{phone})")Integer insertUser(UserInfo userinfo);
}

测试代码:

java">   @Testvoid insertUser() {UserInfo userInfo=new UserInfo();userInfo.setUsername("张三");userInfo.setPassword("张三");userInfo.setAge(19);userInfo.setPhone("1646566787");Integer result=userInfoMapper.insertUser(userInfo);System.out.println("影响行数" + result + " ,id" + userInfo.getId());}

运行结果:
在这里插入图片描述
刷新数据库,看是否插入成功了
在这里插入图片描述
可以看到插入成功了。


提出问题
我们同时看到那个数据库的id是主动自增了的,但是在控制台输出的id是null,那这个是怎么回事呢?

如果想要拿到⾃增id, 需要在Mapper接口的方法上添加一个Options的注解。

java">@Mapper
public interface UserInfoMapper {//插入@Options(useGeneratedKeys = true,keyProperty = "id")@Insert("insert into user_info (username, password, age,phone) values (#{username},#{password},#{age},#{phone})")Integer insertUser(UserInfo userinfo);
}

useGeneratedKeys:这会令 MyBatis使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内
部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字
段),默认值:false.
• keyProperty:指定能够唯⼀识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或
insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset)

我们在新增加一个数据,看是否可以在控制台获取到id的自增值。
增加之前的数据:
在这里插入图片描述

代码(insert):

java">    @Testvoid insertUser() {UserInfo userInfo=new UserInfo();userInfo.setUsername("张si");userInfo.setPassword("张si");userInfo.setAge(19);userInfo.setPhone("1646566787");Integer result=userInfoMapper.insertUser(userInfo);System.out.println("影响行数" + result + " ,id:" + userInfo.getId());}

运行结果:
在这里插入图片描述
刷新数据库:
在这里插入图片描述

可以看到获取到了自增的值,至于为什么这个id是7,原因是因为我之前插入了一条数据,然把她删掉了,然后再插入的时候就是从6开始自增了,这是一个自增的知识点的断点问题。

3.2 删(delete)

SQL语句:

delete from user_info where id=7;

java代码:

java">@Mapper
public interface UserInfoMapper {//删除@Delete("delete from user_info where id=#{id}")void delete(Integer id);
}

测试代码:

java">@Testvoid delete() {userInfoMapper.delete(7);System.out.println("删除成功");}

运行结果:
在这里插入图片描述
打开数据库并且刷新看是否删除成功:
在这里插入图片描述
可以看到成功了。

3.3 改(update)

SQL语句:

update user_info set username="lisi" where id=5;

java代码:

java">@Mapper
public interface UserInfoMapper {//更新@Update("update user_info set username=#{username} where id=#{id}")void update(Integer id);
}

测试:

java">   @Testvoid update() {UserInfo userInfo=new UserInfo();userInfo.setId(5);userInfo.setUsername("lisi");userInfoMapper.update(userInfo);System.out.println("更新成功");}

数据更新前:
在这里插入图片描述
启动项目:
运行结果:
在这里插入图片描述
打开数据库并且刷新查询是否更新数据成功:
在这里插入图片描述
可以看到更新成功了。

3.4 查(select)

SQL语句:

select * from user_info;

java代码:

java">@Mapper
public interface UserInfoMapper {//查询@Select("SELECT * FROM user_info")List<UserInfo> selectAll();}

测试:

java">    @Autowired
private UserInfoMapper userInfoMapper;@Testvoid selectAll() {System.out.println(userInfoMapper.selectAll());}

运行结果:
在这里插入图片描述
可以看到查询成功了。

但是这里会有一个问题:我们先把Mybatis的日志配置取消掉为了便于观察:

启动项目:
在这里插入图片描述
我们可以看到这个这里这个没有获取到数据库表的数据。
这个原因是什么呢?
这是数据库表里的字段名字
在这里插入图片描述
再看java代码当中的字段名字:
在这里插入图片描述
可以看到他们是有区别的。当自动映射查询结果时,MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性(忽略大小写)。 这意味着如果发现了 ID 列和 id 属性,MyBatis 会将列 ID 的值赋给 id 属性那么怎么解决这个问题呢?

三种方法

1.起别名:

java">   @Select("select id, username,`password`, age, gender,  phone, " +"delete_flag as deleteFlag, create_time as createTime, update_time as updateTime" +" from user_info")

2.结果映射:

java">     @Results(id = "BaseMap", value = {@Result(column = "delete_flag", property = "deleteFlag"),@Result(column = "create_time", property = "createTime"),@Result(column = "update_time", property = "updateTime")})

3.驼峰命名(推荐):

java">mybatis:configuration: # 配置打印 MyBatis日志map-underscore-to-camel-case: true #配置驼峰⾃动转换log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

4.总结

这篇博客详细介绍了使用MyBatis注解方式实现增删改查操作的全过程,并针对select查询时数据库数据获取不到的问题,提供了三种有效的解决方案:通过取别名、结果映射和设置驼峰大小转换。这些方法能够帮助开发者快速解决数据映射的问题,提高开发效率。下一篇博客中,我们将继续探讨MyBatis的另一配置方式——XML方式,并揭示它在增删改查操作中的独特优势。希望这篇博客能帮助大家更加全面地掌握MyBatis的核心功能,从而在实际项目中游刃有余。


http://www.ppmy.cn/devtools/169130.html

相关文章

Pycharm接入DeepSeek,提升自动化脚本的写作效率

一.效果展示&#xff1a; 二.实施步骤&#xff1a; 1.DeepSeek官网创建API key&#xff1a; 创建成功后&#xff0c;会生成一个API key&#xff1a; 2. PyCharm工具&#xff0c;打开文件->设置->插件&#xff0c;搜索“Continue”&#xff0c;点击安装 3.安装完成后&…

Excel(函数进阶篇):FILTER函数全解读、XLOOKUP函数全解读、UNIQUE函数、数组与数组公式

目录 数组与数组函数office365中VLOOKUP函数的加强数组中的多条件判断FILTER函数详解用法概述函数语法 基础筛选多条件筛选进阶技巧结合动态数组 高级函数整合错误处理注意事项FILTER经典问题&#xff1a;一对多查询 XLOOKUP函数XLOOKUP基础用法XLOOKUP函数多条件匹配和双向查询…

Milvus WeightedRanker 对比 RRF 重排机制

省流:优先选择WeightedRanker 以rag为例,优先选择bm25全文检索,其次选择向量检索 Milvus混合搜索中的重排机制 Milvus通过hybrid_search() API启用混合搜索功能&#xff0c;结合复杂的重排策略来优化多个AnnSearchRequest实例的搜索结果。本主题涵盖了重排过程&#xff0c;…

C++之模板二番战

本节我们将要介绍模板的深入知识。 文章目录 前言 一、非类型模板参数 1.1 非类型模板参数的特点 1.2 非类型模板参数的使用场景 1.3 非类型模板参数的使用实例 二、模板特例化 2.1 模板特例化的概念 2.2 函数模板特例化 2.3 函数模板特例化规则 2.4 完全特例化和偏特…

对RIP协议工作原理的分析【复习篇】

路由的分类 **静态路由&#xff1a;**通过网络管理员手工添加的路由条目 **动态路由&#xff1a;**所有路由器都运行相同的路由协议&#xff0c;之后通过路由器之间相互沟通、交流&#xff0c;最终计算出前往未知网段的路由条目 根据范围分类 AS自治系统 类型描述例子IGP&…

鸿蒙保姆级教学

鸿蒙&#xff08;HarmonyOS&#xff09;是华为推出的一款面向全场景的分布式操作系统&#xff0c;支持手机、平板、智能穿戴、智能家居、车载设备等多种设备。鸿蒙系统的核心特点是分布式架构、一次开发多端部署和高性能。以下是从入门到大神级别的鸿蒙开发深度分析&#xff0c…

水一个人的时候

import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation # 设置画布 fig, ax plt.subplots() ax.set_xlim(-2, 2) ax.set_ylim(-2, 2) ax.set_aspect(equal) ax.axis(off) # 隐藏坐标轴 # 初始化爱心图案 heart_line, ax.pl…

nRF54L10—超低功耗无线 SoC

nRF54L10与nRF54L15和nRF54L05共同组成了nRF54L系列。nRF54L系列中的所有无线SoC都集成了超低功耗多协议2.4 GHz无线电和MCU&#xff08;微控制器单元&#xff09;功能&#xff0c;配备128MHz的Arm Cortex-M33处理器以及全面的外设集合。该系列提供多种封装和内存大小选择&…