什么是MyBatis
MyBatis是⼀款优秀的 持久层 框架,⽤于简化JDBC的开发。
MyBatis本是 Apache的⼀个开源项⽬iBatis,2010年这个项⽬由apache迁移到了google code,并
且改名为MyBatis 。2013年11⽉迁移到Github
创建项目时添加依赖
上面有提到⼀个词:持久层
持久层:指的就是持久化操作的层, 通常指数据访问层(dao), 是⽤来操作数据库的.
MyBatis⼊⻔
Mybatis操作数据库的步骤:
准备⼯作
创建⼯程

Mybatis 是⼀个持久层框架, 具体的数据存储和数据操作还是在MySQL中操作的, 所以需要添加
MySQL驱动
项⽬⼯程创建完成后,⾃动在pom.xml⽂件中,导⼊Mybatis依赖和MySQL驱动依赖
版本会随着SpringBoot 版本发⽣变化
SpringBoot 3.X对⽤MyBatis版本为3.X
数据准备


配置数据库连接字符串


注意事项:
如果使⽤ MySQL 是 5.x 之前的使⽤的是"com.mysql.jdbc.Driver",如果是⼤于 5.x 使⽤的 是“com.mysql.cj.jdbc.Driver”.
写持久层代码
单元测试
@SpringBootTest就是一个将运行环境交给这个测试类的注解,没有这个注解,就没法注入依赖这些操作,因为被管理的依赖都是在运行环境里的。
MyBatis的基础操作
上⾯使用了Mybatis的查询操作, 接下来学习MyBatis的增, 删, 改操作
在学习这些操作之前, 我们先来学习MyBatis⽇志打印
打印⽇志

重新运⾏程序, 可以看到SQL执⾏内容, 以及传递参数和执⾏结果

参数传递

但是这样的话, 只能查找id=4 的数据, 所以SQL语句中的id值不能写成固定数值,需要变为动态的数值
解决⽅案:在queryById⽅法中添加⼀个参数(id),将⽅法中的参数,传给SQL语句
使⽤ #{} 的⽅式获取⽅法中的参数
如果mapper接⼝⽅法形参只有⼀个普通类型的参数,#{…} ⾥⾯的属性名可以随便写,如:#{id}、# {value}。需要和参数名保持一样,不然没法成功传参,或者使用注解标识参数名。顺序不重要,参数名对的上就行。但是如果只传递一个参数,参数名就不需要对上,因为只有一个参数也没得选,但是最好还是参数名和#{}里的名称对上。
不建议使用方法:
使用paramN在#{}里,这个代值第n个参数。



如果只查询0-1个表当中的数据来赋值给实体类,那么返回值为实体类就行了,没查询到会返回null。如果返回多个数据却用实体类接收会报异常。
如果是查询0-n个数据,就需要将返回值设置为List<T>T是实体类,没查询到会返回null。
如果返回值为基础类型,不是包装类没有查询到数据,返回值可能会有逻辑错误,所以只查询一个基础类型的话推荐使用包装类,包装了的话没有查询到返回null。
list来接受数据库给的返回值是因为,这样就不需要关心数据库具体返回的类型是什么arraylist 还是linklist,只需要知道是一个list类型,来通过多态就可以调用list通用的方法了。
增(Insert)
也可以将传递的参数直接改成传递对象,对象里的属性名和类型也是要一一对应的。
返回主键
Insert 语句默认返回的是受影响的⾏数,这些mysql语句的返回值和在数据库直接调用的返回值是一样的。
但有些情况下, 数据插⼊之后, 还需要有后续的关联操作, 需要获取到新插⼊数据的id
⽐如订单系统
当我们下完订单之后, 需要通知物流系统, 库存系统, 结算系统等, 这时候就需要拿到订单ID
如果想要拿到⾃增id, 需要在Mapper接⼝的⽅法上添加⼀个Options的注解
这个自增id会被赋值到传递的对象里面,通过getid来获得。
删(Delete)
改(Update)
查(Select)
可以看到,mysql的属性写法是下划线写法,而java类当中的写法是小驼峰写法。
起别名
结果映射
开启驼峰命名
mybatis:configuration:map-underscore-to-camel-case: true # 配置驼峰⾃动转换
MyBatis XML配置文件
Mybatis的开发有两种⽅式:
注解
XML
上⾯学习了注解的⽅式, 接下来我们学习XML的⽅式
使⽤Mybatis的注解⽅式,主要是来完成⼀些简单的增删改查功能. 如果需要实现复杂的SQL功能,建议使⽤XML来配置映射语句,也就是将SQL语句写在XML配置⽂件中.
MyBatis XML的⽅式需要以下两步:
配置数据库连接字符串和MyBatis
写持久层代码
配置连接字符串和MyBatis和写持久层代码的⽅法定义 Interface和使用注解来完成数据库交互的步骤是一样的,除了还要设置MyBatis的XML的文件设置,配置xml文件的扫描路径。
配置连接字符串和MyBatis
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件10 mybatis.mapper-locations = classpath:mapper/**Mapper.xml
mybatis:10 mapper-locations: classpath:mapper/**Mapper.xml
写持久层代码
添加 mapper 接口

添加 UserInfoXMLMapper.xml
数据持久成的实现,MyBatis 的固定 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.demo.mapper.UserInfoMapper">//这个定义的是要实//现的类的路径
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
- 作用:这是 XML 文件的声明部分,用于定义 XML 的版本和字符编码。
- 解释:
- version="1.0" :指定 XML 文档遵循的 XML 1.0 规范,是目前最基础、通用的 XML 版本。
- encoding="UTF-8" :设置 XML 文件的字符编码为 UTF-8,确保文件能正确解析中文字符等特殊字符,避免乱码问题。
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- 作用:定义 XML 的文档类型(DTD,Document Type Definition),用于约束 Mapper XML 的结构和语法。
- 解释:
- <!DOCTYPE mapper ... > :声明这是一个 MyBatis 的 mapper 类型文档。
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" :表示这是 MyBatis 官方定义的公共 DTD, 3.0 是 DTD 的版本, EN 表示语言为英文。
- http://mybatis.org/dtd/mybatis-3-mapper.dtd :指定 DTD 文件的位置,MyBatis 解析器会通过该 URL 验证 XML 内容是否符合 Mapper 文件的语法规则(如标签、属性是否合法)。
<mapper namespace="com.example.demo.mapper.UserInfoMapper">
- 作用:定义 Mapper 的命名空间(namespace),是 MyBatis 中非常关键的配置。
- 解释:
- namespace 的值通常与对应的 Mapper 接口全类名一致(如这里的 com.example.demo.mapper.UserInfoMapper ,假设存在同名 Java 接口)。
- 作用:
- 绑定接口:MyBatis 会通过命名空间关联对应的 Mapper 接口,接口中的方法与 XML 中 <select> 、 <insert> 等标签的 id 一一映射,实现接口方法到 SQL 的关联。
- 避免 SQL 冲突:不同 Mapper XML 中即使有相同 id 的 SQL 标签,只要命名空间不同,就不会冲突,保证 SQL 定义的唯一性。
返回的数据类型是实体类的类型,而不是List<T>这样的,要的是返回所包含的类型。
增(Insert)
UserInfoMapper接⼝:


xml格式,可以随意的换行,还是视为同一条指令的。
删(Delete)
改(Update)
查(Select)
resultType换成了resultMap
这个映射可以多次使用
其他查询操作
多表查询

多表查询实际上和单表查询没有区别,需要的是创建另外的实体类,能够接收查询到的数据,虽然可以直接包含其他的实体类,但建议还是另外加上基础类型。
多表查询的问题
实际开发中最好不要用多表查询,因为这会导致一种慢查询的现象,在mysql查询中,每一个查询都需要mysql线程池中的一个线程,多表查询的时间必然比单表查询要慢,那么就会导致占有线程的时间过长,导致其他业务不能及时的得到处理,这是非常致命的。所以建议还是将多表查询细分为单表查询,再通过程序员自身将单表查询到的数据串联起来,能够有效的提升查询效率,并且还能通过索引优化。
就像这里一样,多表查询是同时查询两张表并且将两张表的数据段进行比较,而两个单表查询就可以先查询出其中一张表的id,再通过这张表的id作为另外一张表的关联字段 user_id这种作为where的查询条件,就可以加快查询速度。
#{} 和 ${}



#{} 和 ${}区别

排序功能
${}可以在那些参数较少,受限制,能够校验的场景下使用。
此之外, 还有表名作为参数时, 也只能使⽤ ${}。
因为有时会有数据量过大,从而导致需要分表分库的情况。
like 查询
数据库连接池




