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

对Mapper.xml文件进行深入的学习

1.  前言

既上次在Mapper.xml文件出现bug之后,痛改前非,决定吃透Mapper.xml映射文件。

让我们通过具体的代码段来进一步理解 MyBatis 的 Mapper XML 文件中的每个组成部分。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.goblin.BIbackend.mapper.BillsMapper"><resultMap id="BaseResultMap" type="com.goblin.BIbackend.model.entity.Bills"><id property="id" column="id" jdbcType="BIGINT"/><result property="userId" column="user_id" jdbcType="BIGINT"/><result property="amount" column="Amount" jdbcType="FLOAT"/><result property="billDate" column="bill_date" jdbcType="DATE"/><result property="dueDate" column="due_date" jdbcType="DATE"/><result property="isPaid" column="is_paid" jdbcType="BIGINT"/></resultMap><sql id="Base_Column_List">id,user_id,Amount,bill_date,due_date,is_paid</sql><select id="list" resultType="com.goblin.BIbackend.model.entity.Bills">select * from bills<where><if test="userId != null">user_id = #{userId}</if><if test="amount != null">and Amount = #{amount}</if><if test="billDate != null">and bill_date = #{billDate}</if><if test="dueDate != null">and due_date = #{dueDate}</if><if test="isPaid != null">and is_paid = #{isPaid}</if></where></select><select id="mySelectById" resultType="com.goblin.BIbackend.model.entity.Bills">select * from bills where id = #{id}</select><insert id="myInsert" parameterType="com.goblin.BIbackend.model.entity.Bills">insert into bills (user_id,Amount,bill_date,due_date,is_paid)values (#{userId},#{amount},#{billDate},#{dueDate},#{isPaid})</insert><delete id="myDeleteById" >delete from bills where id = #{id}</delete><select id="mySelectAll" resultMap="BaseResultMap">select * from bills</select><update id="myUpdate" parameterType="com.goblin.BIbackend.model.entity.Bills">update bills where id = #{id}</update></mapper>

2.  各部分

2.1  <mapper>根元素

<mapper namespace="com.goblin.BIbackend.mapper.BillsMapper"><!-- 其他配置 -->
</mapper>

这个根元素定义了 XML 文件的命名空间,通常对应 Java 中的 Mapper 接口的完全限定名。这有助于区分不同的 Mapper 文件,防止 SQL 语句冲突。

2.2  <resultMap> 和字段映射

<resultMap id="BaseResultMap" type="com.goblin.BIbackend.model.entity.Bills"><id property="id" column="id" jdbcType="BIGINT"/><result property="userId" column="user_id" jdbcType="BIGINT"/><result property="amount" column="Amount" jdbcType="FLOAT"/><result property="billDate" column="bill_date" jdbcType="DATE"/><result property="dueDate" column="due_date" jdbcType="DATE"/><result property="isPaid" column="is_paid" jdbcType="BIGINT"/>
</resultMap>

这里定义了一个名为 BaseResultMap 的结果映射它将数据库查询结果映射到 com.goblin.BIbackend.model.entity.Bills 类的实例。

具体映射关系如下:

1. id属性对应数据库表的id列,数据类型为BIGINT。
2. userId属性对应数据库表的user_id列,数据类型为BIGINT。
3. amount属性对应数据库表的Amount列,数据类型为FLOAT。
4. billDate属性对应数据库表的bill_date列,数据类型为DATE。
5. dueDate属性对应数据库表的due_date列,数据类型为DATE。
6. isPaid属性对应数据库表的is_paid列,数据类型为BIGINT。

前面是实体类里面定义的名称,后面是数据库里面对应的字段名。 

2.3  <sql> 片段

<sql id="Base_Column_List">id, user_id, Amount, bill_date, due_date, is_paid
</sql>
  • id: 为 SQL 片段定义一个标识符,可以在 <select> 或其他元素中通过 <include> 引用。
  • 内容: 列出了查询操作中需要的列名。这是为了避免在多个 <select> 元素中重复相同的列名列表。

2.4  增删改查SQL语句

<select id="list" resultType="com.goblin.BIbackend.model.entity.Bills">select * from bills<where><if test="userId != null">user_id = #{userId}</if><if test="amount != null">and Amount = #{amount}</if><if test="billDate != null">and bill_date = #{billDate}</if><if test="dueDate != null">and due_date = #{dueDate}</if><if test="isPaid != null">and is_paid = #{isPaid}</if></where></select><select id="mySelectById" resultType="com.goblin.BIbackend.model.entity.Bills">select * from bills where id = #{id}</select><insert id="myInsert" parameterType="com.goblin.BIbackend.model.entity.Bills">insert into bills (user_id,Amount,bill_date,due_date,is_paid)values (#{userId},#{amount},#{billDate},#{dueDate},#{isPaid})</insert><delete id="myDeleteById" >delete from bills where id = #{id}</delete><update id="myUpdate" parameterType="com.goblin.BIbackend.model.entity.Bills">update bills where id = #{id}</update>

parameterTyperesultType 在 SQL 映射文件中用于指定参数和结果的 Java 类型,但它们的作用和使用场景不同。 一定不能写错,否则测试接口的时候就错乱了。

2.4.1  resultType

  • 作用resultType 用于指定 MyBatis 查询操作返回的结果类型。这个属性告诉 MyBatis 应该如何将查询结果集的每一行映射到 Java 对象。
  • 使用场景:通常用在 <select> 元素中,用于定义查询结果应该如何映射到 Java 类的实例。
  • 示例:
<select id="selectBlog" resultType="Blog">select * from Blog
</select>

在这个例子中,resultType 指定了查询结果应该映射到 Blog 类的实例。

2.4.2  parameterType

  • 作用parameterType 用于指定 MyBatis 操作(如 <insert><update><delete> 或带有参数的 <select>)中传入的参数类型。这个属性告诉 MyBatis 期待的参数对象的类型,MyBatis 会根据这个类型来自动映射方法参数和 SQL 语句中的占位符。
  • 使用场景:通常用在需要传入参数执行数据库操作的元素中,例如插入、更新或删除操作。
  • 示例
<select id="selectById" parameterType="java.util.Map" resultType="com.example.Blog">select * from blog where id = #{id}
</select>

在这个例子中,parameterType 指定了方法的参数类型为 java.util.Map,这意味着你可以传递一个 Map 对象作为查询参数。

2.4.3  两者区别总结 

  • 方向parameterType 定义了进入操作的参数类型,而 resultType 定义了从数据库查询返回的结果类型。
  • 使用位置parameterType 通常用在需要参数的 SQL 操作中,resultType 则用在查询操作中。
  • 映射方式parameterType 映射的是方法的参数到 SQL 语句的占位符,resultType 映射的是查询结果集到 Java 对象的属性。

 2.4.5  占位符#{id}

在 SQL 映射文件中编写 SQL 语句时,可以使用 #{} 来引用 Java 方法的参数。

<select id="selectBlog" resultType="Blog">SELECT * FROM blog WHERE id = #{id}
</select>

在这个例子中,#{id} 就是一个占位符,它将被 MyBatis 替换为方法参数 id 的值。

参数替换

MyBatis 会根据方法的参数列表自动替换 #{} 中的内容。如果方法的参数是一个简单类型或 POJO(Plain Old Java Object),MyBatis 会根据参数的名称来替换占位符。

预处理语句

使用 #{} 占位符的 SQL 语句会被 MyBatis 转换为预处理语句(PreparedStatement),这样可以提高性能并防止 SQL 注入攻击。

类型处理

MyBatis 会根据参数的实际类型来设置 SQL 语句中的参数。例如,如果参数是 java.sql.Date 类型,MyBatis 会使用适当的 JDBC 方法来设置日期参数。

占位符总结

#{} 占位符是 MyBatis 中实现参数化查询的关键机制,它允许开发者将 Java 方法的参数值安全、灵活地传递给 SQL 语句。通过使用 #{},MyBatis 可以自动处理参数的类型转换和预处理语句的生成,从而提高数据库操作的效率和安全性。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • @SpringBootApplication 注解
  • linux:命令执行过程【图表】
  • linux 安装redis 遇到问题解决方案
  • 面试真题 | ARM体系架构基础知识
  • (四)stm32之通信协议
  • 补码是什么意思_补码的性质_补码反码原码的转换
  • c++【入门】计算(a+b)*c的值
  • LLM大模型应用中的安全对齐的简单理解
  • 什么是数据同步服务RSYNC?
  • 快速排序算法Python实现
  • 【人工智能】-- 迁移学习
  • 包管理器-npm、yarn、cnpm、pnpm的比较
  • JDK安装详细教程(以JDK17为例)
  • c++将utf8转gb2312
  • Tomcat组件概念和请求流程
  • 345-反转字符串中的元音字母
  • java第三方包学习之lombok
  • Puppeteer:浏览器控制器
  • Python socket服务器端、客户端传送信息
  • React的组件模式
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 官方解决所有 npm 全局安装权限问题
  • 缓存与缓冲
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 前端面试题总结
  • 思考 CSS 架构
  • 算法之不定期更新(一)(2018-04-12)
  • 学习使用ExpressJS 4.0中的新Router
  • 一道面试题引发的“血案”
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 阿里云ACE认证之理解CDN技术
  • 阿里云服务器如何修改远程端口?
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (6)添加vue-cookie
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (四)库存超卖案例实战——优化redis分布式锁
  • (一) springboot详细介绍
  • (一)插入排序
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • .Mobi域名介绍
  • .NET 通过系统影子账户实现权限维持
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET处理HTTP请求
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • /使用匿名内部类来复写Handler当中的handlerMessage()方法
  • :“Failed to access IIS metabase”解决方法