1. 为什么要搞个 XML?(核心逻辑)
之前用 @Select 注解写 SQL,就像是在便签纸上写备忘录——简单、随手一贴就行。
但是,当遇到下面这种情况时,“便签纸”就不够用了:
- SQL 超级长:几十行的报表查询,写在 Java 代码里会把代码撑得很难看。
- SQL 是动态的:比如“如果你给了名字就按名字查,没给名字就按年龄查”,这种
if/else逻辑,注解很难写,但 XML 极其擅长。
所以:
- 注解 = 轻武器(手枪),解决简单增删改查。
- XML = 重武器(加特林),解决复杂业务逻辑。
2. XML 映射的“三位一体”
要想让 XML 跑起来,你必须把三个地方打通。结合你刚才的图片,这三个地方分别是:
第一步:指路(配置文件)
你刚才发的截图里,application.properties 有这么一行:
Properties
mybatis.mapper-locations=classpath:mapper/*.xml
这是什么意思?
SpringBoot 启动时是个瞎子,它不知道你把“重武器”(XML文件)藏哪了。这句话就是告诉它:
“嘿,兄弟,所有的 SQL 秘籍都放在
resources/mapper/这个文件夹下,名字是.xml结尾的,你去那里找。”
第二步:接口(Java 这一端)
在 UserMapper.java 里,你只需要定义“我要做什么”,不需要写 SQL。
Java
public interface UserMapper {
// 只写方法名,没有 @Select 注解了!
// 意思:我要查个列表,具体怎么查,去 XML 里看。
List<User> list();
}
第三步:实现(XML 那一端)
在 resources/mapper/UserMapper.xml 里,你写真正的 SQL。
3. 最核心的“三大绑定规则” (重要)
MyBatis 怎么知道 Java 里的这个方法 对应 XML 里的这段 SQL?全靠这三个属性“连线”:
请对照你刚才的代码看:
-
Namespace(命名空间) = 身份证号
- XML 里的
<mapper namespace="..."> - 必须等于:Mapper 接口的全类名(例如
com.itmob.mapper.UserMapper)。 - 如果错一个字母,MyBatis 就找不到家了。
- XML 里的
-
ID = 名字
- XML 里的
<select id="..."> - 必须等于:接口里的方法名(例如
list)。 - 如果不一致,就会报错 "Invalid bound statement"(无效绑定)。
- XML 里的
-
ResultType = 返回啥
- XML 里的
resultType="..." - 必须等于:你要封装成的实体类全名(例如
com.itmob.pojo.User)。 - 注意:就算返回的是
List<User>,这里也只要写User,MyBatis 够聪明,知道自己装进 List 里。
- XML 里的