2026-04-16-MyBatis
注解
Results
它需要配合 Result 这个注解来使用,是用来解决 Java 命名和 MySQL 命名不一致而导致属性的值无法映射上的问题
Result
它是针对某一个字段经行映射,column 是表示 MySQL 中字段的名称,property 是表示 Java 中对象的名称。
如果 MySQL 中字段的名称和 Java 中对象属性的名称都满足各自的命名规范,那么只需要开启命名自动转换即可,而不需要配置这些属性
Options
它是用来获取新增的对象的 Id 值。useGeneratedKeys = true 开启获取主键值,keyProperty 表示 Java 中主键的名称
XML
resultMap
这个功能和上面的 Results 注解类似,都是给 Java 和 MySQL 各自的字段对应的映射关系
<resultMap id="BaseMap" type="com.wunamor.mybatisdemo.model.UserInfo">
<id column="id" property="id"/>
<result column="delete_flag" property="deleteFlag" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
</resultMap>动态SQL
if
里面有 test 属性,test 属性值为 true 就把里面代码块插入进入
trim
通过属性设置,去除开头或结尾指定的值
where
去除 where 标签后面第一个 and/or 等语句,但是在使用的时候一定要考虑到没有 where 会不会影响到全表,比如更新的时候如果没有传入相关属性,那么可能会导致全表更新。
set
在更新的时候使用,会去除末尾的逗号
foreach
在批量删除或插入的使用常用
include
配合 sql 这个标签使用,在一部分代码块大量重复使用的时候,就可以使用这个标签。这个代码块不要求是否正确
其他
${} 和 #{}
${} 是直接字符串拼接,不需要任何的处理,因此会有 SQL 注入的问题,所以一般情况下都是使用 #{} 来代替 ${}
SQL 注入是一种攻击行为,比如有一个这样的语句:
select * from user_info where username = '${username}'如果username没有任何限制,就会有一定的问题,比如使用1' or 1 = 1 #就可以查询所有的内容
虽然有 SQL 注入的问题,但是它在某一些特殊的场景下是无法使用 #{} 替代的,比如根据某个字段经行升序/降序查询:
select * from user_info order by age ${type}而排序的类型是可以枚举出来的,因此可以使用${}
SQL 优化
SQL 优化可以从以下几个方面考虑:
- 是否使用多表查询
- 是否使用索引
- 索引是否生效
后两个是可以在 MySQL的索引 这个章节里面讲到过,就不讲述了。这里着重讲述多表查询
多表查询
不使用多表查询主要的原因是多表查询容易导致慢查询。
在处理请求期间,MySQL 数据库是无法处理其他的请求的,所以这就会导致其他业务“卡”了一下,这个显然是不太合理。 就拿现实中的办理业务来类比,假设要办理一个业务是要 4 天(数据量多,处理时间大),这个业务是可以分为若干模块,那就可以很自然的分多期处理
因此,虽然使用两次单表查询的时间之和可能会比一次多表查询的时间长,但是为了防止影响到其他业务,依然会使用单表查询。
而且如果单表查询之间是没有关联关系,下次的查询不依赖上次查询的结果,那么就可以通过 MySQL 集群,可以比较高效地查询结果
面试题目
${} 和 #{} 有什么区别?
${}是有SQL注入的问题,#{}是没有这个问题- 由于
#{}是有预编译的过程(类似缓存),它的速度是要比${}快的 - 虽然
${}有SQL注入的问题,但是在 根据表名查询(多库多表),根据某个字段升序/降序查询等特殊场景都需要这个,而#{}是无法替代的