当前位置: 首页 > news >正文

MyBatis Mapper XML 核心详解

以下内容是关于 MyBatis 框架中 Mapper XML 文件 的官方文档或技术说明,内容非常全面。您问“怎么理解”,我将为您系统地、通俗地解析这份文档的核心要点,帮助您掌握 MyBatis 的核心思想和关键组件。


一、核心思想:MyBatis 的设计哲学

“The true power of MyBatis is in the Mapped Statements.”
(MyBatis 的真正力量在于“映射语句”)

MyBatis 是一个 半自动化的 ORM(对象关系映射)框架,它不像 Hibernate 那样完全隐藏 SQL,而是:

  • 让你写 SQL
  • 帮你处理参数设置和结果映射
  • 极大减少 JDBC 冗余代码(文档说节省 95%)

它不试图“取代 SQL”,而是“增强 SQL 的能力”。


二、Mapper XML 的核心元素(按推荐顺序)

元素说明
<cache>配置当前命名空间的二级缓存
<cache-ref>引用其他命名空间的缓存配置
<resultMap>最强大、最复杂的元素,定义数据库结果集如何映射到 Java 对象
<sql>可重用的 SQL 片段
<insert>插入语句
<update>更新语句
<delete>删除语句
<select>查询语句

⚠️ 注意:<parameterMap>废弃,不再使用。


三、核心元素详解

1. <select> 查询语句

<select id="selectPerson" parameterType="int" resultType="hashmap">SELECT * FROM PERSON WHERE ID = #{id}
</select>
  • id:在当前命名空间内唯一标识这个 SQL。
  • parameterType:传入参数的类型(可选,MyBatis 能自动推断)。
  • resultType:返回结果的类型(如 UserHashMap 等)。
  • #{id}预编译参数,防止 SQL 注入,等价于 JDBC 的 ?
📌 重要属性
属性说明
resultMap引用外部 <resultMap>,用于复杂映射(和 resultType 二选一)
useCache是否使用二级缓存(默认 true
flushCache是否清空缓存(默认 false
timeout查询超时时间(秒)
fetchSize提示数据库每次返回多少行数据(优化大数据量查询)

2. <insert><update><delete>

<insert id="insertAuthor">INSERT INTO Author (username, password, email) VALUES (#{username}, #{password}, #{email})
</insert>
🔑 特殊属性(仅 insert/update)
属性说明
useGeneratedKeys="true"使用数据库自增主键(如 MySQL)
keyProperty="id"将生成的主键值赋给 Java 对象的 id 属性
keyColumn="ID"指定数据库中生成主键的列名(PostgreSQL 等需要)
🌟 <selectKey>:手动生成主键(适用于不支持自增的数据库)
<insert id="insertAuthor"><selectKey keyProperty="id" resultType="int" order="BEFORE">SELECT CAST(RANDOM()*1000000 AS INTEGER) FROM SYSIBM.SYSDUMMY1</selectKey>INSERT INTO Author (id, username) VALUES (#{id}, #{username})
</insert>
  • order="BEFORE":先生成主键再插入。
  • order="AFTER":先插入再查主键(如 Oracle 的 RETURNINGCURRVAL)。

3. <sql>:可重用 SQL 片段

<sql id="userColumns">${alias}.id, ${alias}.username, ${alias}.password
</sql><select id="selectUsers" resultType="map">SELECT <include refid="userColumns"><property name="alias" value="t1"/></include>,<include refid="userColumns"><property name="alias" value="t2"/></include>FROM users t1 CROSS JOIN users t2
</select>
  • <include> 引用 SQL 片段。
  • ${alias}字符串替换(注意 SQL 注入风险)。

4. 参数处理:#{} vs ${}

语法说明安全性用途
#{param}预编译参数,使用 ? 占位符✅ 安全一般参数(如 WHERE id = #{id}
${param}字符串替换,直接拼接 SQL❌ 有 SQL 注入风险动态表名、列名(如 ORDER BY ${column}

✅ 最佳实践:

  • 用户输入的列名/表名,必须做白名单校验。
  • 能用 #{} 就不用 ${}

5. <resultMap>:最强大的映射工具

场景:当数据库字段名 ≠ Java 属性名
<resultMap id="userResultMap" type="User"><id property="id" column="user_id"/><result property="username" column="user_name"/><result property="password" column="hashed_password"/>
</resultMap><select id="selectUsers" resultMap="userResultMap">SELECT user_id, user_name, hashed_password FROM users WHERE id = #{id}
</select>
  • <id>:映射主键,有助于性能优化。
  • <result>:普通字段映射。
高级用法:关联映射(一对一、一对多)
<resultMap id="detailedBlogResultMap" type="Blog"><id property="id" column="blog_id"/><result property="title" column="blog_title"/><!-- 一对一:博客属于一个作者 --><association property="author" javaType="Author"><id property="id" column="author_id"/><result property="username" column="author_username"/></association><!-- 一对多:博客有多个文章 --><collection property="posts" ofType="Post"><id property="id" column="post_id"/><result property="subject" column="post_subject"/></collection>
</resultMap>
  • association:一对一关联(如 Blog → Author)
  • collection:一对多关联(如 Blog → List)
  • ofType:集合中元素的类型(相当于泛型)
🌟 <discriminator>:鉴别器(多态映射)
<discriminator javaType="int" column="draft"><case value="1" resultType="DraftPost"/><case value="0" resultType="PublishedPost"/>
</discriminator>

根据 draft 字段的值,决定使用哪个 resultType,实现“一个查询返回不同子类”。


四、总结:如何理解这份文档?

维度理解
定位MyBatis 不是“全自动 ORM”,而是“SQL 增强器”
核心<select> + <resultMap> 解决了 JDBC 最繁琐的部分
优势写 SQL 自由,映射灵活,性能可控
风险使用 ${} 时需警惕 SQL 注入
最佳实践从小 resultMap 开始,逐步构建复杂映射,配合单元测试

五、学习建议

  1. 先掌握简单映射resultType + 别名 + #{} 参数
  2. 再学 <resultMap>:处理字段名不一致
  3. 再学关联映射associationcollection
  4. 最后学高级特性<discriminator>、缓存、动态 SQL

如果您有具体的使用场景(比如“如何实现一对多查询”或“如何防止 SQL 注入”),欢迎继续提问,我可以给出更具体的代码示例。

http://www.dtcms.com/a/461002.html

相关文章:

  • 加强局网站建设网站建设域名多少钱
  • 记录最新 Neo4j 安装过程(截图实操)、使用、踩坑 Neo4j 5.26.13、JDK 17安装
  • JavaWeb项目部署到Tomcat的三种方法
  • MyBatis配置全解析:核心要点详解
  • apache-tomcat 安装部署
  • 如何为卫生中心构建安全高效的网络系统?
  • 抖音代运营业务介绍seo文案范例
  • 珠海网站排名提升昆明网站建设frf
  • 使用 Loki + Promtail + Grafana 实现 Docker 容器日志采集与可视化
  • Dockerfile实战案例详解
  • Paimon系列:主键表流读之changelog producer
  • 本地 Docker 镜像送上云:腾讯云无服务器与容器化全栈迁移实战
  • win10安装spark3.1详细流程(小白用)
  • Spark on k8s部署
  • Kotlin 内联函数、高阶函数、扩展函数
  • 用化学方法nmp溶剂从佳能cmos传感器上剥离拜耳矩阵和微透镜
  • Apache Tomcat 详解
  • 矩阵奇异值分解(SVD)中Golub–Kahan 双对角化 + 对双对角矩阵的隐式QR详解
  • QT MVC中Model的特点及使用注意事项
  • wordpress最快仿站宁波网络营销服务
  • 徕卡RTC360助力铝单板设计效率提升
  • EasyExcel 读取 Excel 文件指南
  • LabVIEW光栅旋转式光谱仪
  • 上海营销网站设计去设计公司还是去企业
  • 怎么查询自己注册的商标东营网站建设课程定位优化
  • 【rabbitmq 高级特性】RabbitMQ 延迟队列全面解析
  • linux学习笔记(22)线程同步——线程信号量
  • 如何用营销自动化提升开信率与转化率
  • 人形机器人安全研究
  • 比斯特自动化|为什么焊接18650电池离不开点焊机?