MyBatis 学习(四)之 SQL 映射文件

news2024/9/27 12:10:06

目录

1 SQL 映射文件介绍

2 select 元素

3 insert 元素

4 update 和 delete 元素

5 sql 元素       

6 parameterType 元素

7 resultType 元素

8 resultMap 元素(重要)

9 参考文档


1 SQL 映射文件介绍

        映射器是 MyBatis 中最复杂并且是最重要的组件。它由一个接口和 SQL 映射文件(或者注解)组成。在映射器中我们可以配置各类 SQL、动态 SQL、缓存、存储过程、级联等复杂的内容。

以下是 SQL 映射文件的部分元素介绍

元素描述
cache该命名空间的缓存配置
cache-ref引用其它命名空间的缓存配置
resultMap描述如何从数据库结果集中加载对象,它是最复杂也是最强大的元素
sql可被其它语句引用的可重用语句块
select映射查询语句
insert映射插入语句
update映射更新语句
delete映射删除语句

2 select 元素

select 元素表示 SQL 的 select 语句,用于查询,以下是 select 元素的部分属性

属性

描述
id在命名空间中唯一的标识符,可以被用来引用这条语句
parameterType将会传入这条语句的参数类的全类名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler) 推断出具体传入语句的参数,默认值为未设置(unset)
resultType从这条语句中返回的期望类型的类的全类名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。可以使用 resultType 或 resultMap,但不能同时使用
resultMap外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂映射的情形都能迎刃而解。可以使用 resultMap 或 resultType,但不能同时使用
flushCache将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false
useCache将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true
timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖驱动)
fetchSize这是一个给驱动的提示,尝试让驱动程序每次批量返回的结果行数和这个设置值相等。 默认值为未设置(unset)(依赖驱动)
statementTypeSTATEMENT,PREPARED 或 CALLABLE 中的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED
resultSetTypeFORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖驱动)
databaseId如果配置了数据库厂商标识 (databaseIdProvider) 并且存在两个相同的语句,一个带 databaseId 而另一个不带,MyBatis 会优先加载带有 databaseId 的语句。如果 databaseId 与当前数据库匹配,则不带 databaseId 的相同语句将被忽略。未设置 databaseId 使用通用 SQL 规则
resultOrderedresultOrdered:这个设置仅对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。 这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false
resultSets这个设置仅对多结果集的情况适用。它将列出语句执行后返回的结果集并给每个结果集一个名称,名称是逗号分隔的

3 insert 元素

属性

描述
id在命名空间中唯一的标识符,可以被用来引用这条语句
parameterType将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)
flushCache将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:(对 insert、update 和 delete 语句)true
timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)
statementType可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED
useGeneratedKeys(仅适用于 insert 和 update)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false
keyProperty(仅适用于 insert 和 update)指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset)。如果生成列不止一个,可以用逗号分隔多个属性名称。不能和keyColumn连用
keyColumn(仅适用于 insert 和 update)设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第一列的时候,是必须设置的。如果生成列不止一个,可以用逗号分隔多个属性名称。不能和keyProperty连用
databaseId同 select 元素

主键回填

        在 MyBatis 中,若表中的主键设置为自增,插入数据时没有插入主键,但是又想获得数据库中该条数据的主键,那么可以通过设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置到目标属性(如 User 类中的 id 属性)上来获得该值。

<insert id="insertUser" parameterType="com.entity.User" useGeneratedKeys="true" keyProperty="id">
        insert into person(name, age, sex)
        values (#{name}, #{age}, #{sex});
</insert>
//添加一个用户数据
@Test
public void testInsertUser() {
    String statement = "com.mapper.UserMapper.insertUser";
    User user = new User();
    user.setName("孙尚香");
    user.setAge(24);
    user.setSex("女");
    int i = sqlSession.insert(statement, user);
    System.out.println( (i>0)? "添加成功!":"添加失败!");
    //提交插入的数据
    sqlSession.commit();
    sqlSession.close();
    // 输出返回的主键值
    System.out.println("返回的主键值=" + user.getId());
}

自定义主键并且可以在 Java 中通过属性获得该值

在 MyBatis 中可以通过 selectKey 元素自定义主键,以下是其属性介绍

  • keyProperty:selectKey 需要设置的目标属性
  • resultType:结果类型
  • order:可以设置为 BEFORE 或 AFTER ,表示先设置主键,后执行插入语句或先执行插入语句,后设置主键
<insert id="insertUser" parameterType="com.entity.User" >
    <selectKey keyProperty="id" resultType="int" order="BEFORE">
        select ROUND(RAND()*1000)
    </selectKey>
    insert into person(id, name, age, sex)
    values (#{id}, #{name}, #{age}, #{sex});
</insert>
@Test
public void testInsertUser() {
    String statement = "com.mapper.UserMapper.insertUser";
    User user = new User();
    user.setName("郑旦");
    user.setAge(24);
    user.setSex("女");
    int i = sqlSession.insert(statement, user);
    System.out.println( (i>0)? "添加成功!":"添加失败!");
    //提交插入的数据
    sqlSession.commit();
    sqlSession.close();
    // 输出返回的主键值
    System.out.println("返回的主键值=" + user.getId());
}

  

4 update 和 delete 元素

        update 和 delete 元素在使用上比较简单,所以这里把它们放在一起论述。它们和 insert 元素的属性差不多,执行完后也会返回一个整数,用来表示该 SQL 语句影响了多少条数据库记录。

<!-- 根据 id 更新用户 -->
<update id="updateUser">
    update person set name = #{name},
                      age = #{age},sex = #{sex} where id = #{id}
</update>
<!-- 根据 id 删除用户 -->
<delete id="deleteUser" parameterType="int">
    delete from person where id = #{id}
</delete>

5 sql 元素       

        sql 元素是用来定义可重用的 sql 代码片段,这样在字段比较多的时候,以便在其它语句中使用。需要结合 include 元素一起使用,以下是代码示例。

<!--定义sql代码片段-->
<sql id="userCols">
    id,username,age,sex
</sql>
<!-- 查询所有用户 -->
<select id="selectAllUser" resultType="com.entity.User">
    select <include refid="userCols"/> from person
</select>

6 parameterType 元素

parameterType 元素可以输入以下类型:

  • Java 基本数据类型
  • POJO 类型
  • Map 类型
<!-- 通过 普通数据类型 int 查询一个用户 -->
<select id="selectUserById" parameterType="int" resultType="com.entity.User">
    select * from person where id = #{id};
</select>

<!-- 通过 POJO 类型 User 添加用户-->
<insert id="insertUser" parameterType="com.entity.User">
    insert into person(id,username,age,sex) values (#{id},#{username},#{age},#{sex});
</insert>
 
<!-- 通过 嵌套 POJO 类型 查询一个用户,QueryVo 类中定义了 User user 属性 -->
<select id="selectUserByUserNameAndAge" parameterType="com.entity.QueryVo" resultType="com.entity.User">
    select * from person where name = #{user.name} and age = #{user.age};
</select>

<!-- 通过 Map 类型 查询一个用户, HashMap<String, Object> map = new HashMap<>(); 
map.put("name","赵飞燕"); map.put("age",24); 通过 key 获得 map 中的 value-->
<select id="selectUserByMap" parameterType="hashmap" resultType="com.entity.User">
    select * from person where name = #{name} and age = #{age};
</select>

7 resultType 元素

resultType 元素和 parameterType 元素用法差不多,一个是输出,一个是输入。resultType 元素可以输出以下类型:

  • Java 基本数据类型
  • POJO 对象
  • POJO 对象列表
  • Map 对象列表
<!-- 统计用户总数量,输出为一个整数 int -->
<select id="countUsers" resultType="int">
    select count(1) from person
</select>

<!-- 通过 id 查询一个用户,输出为一个 User -->
<select id="selectUserById" parameterType="int" resultType="com.entity.User">
    select * from personwhere id = #{id};
</select>

<!-- 查询所有用户,输出为一个 List<User> 列表 -->
<select id="selectAllUser" resultType="com.entity.User">
    select * from person
</select>

<!-- 查询所有用户, 输出为一个 List<HashMap<String, Object>> Map 列表-->
<select id="selectAllUser" resultType="hashmap">
    select * from person
</select>

8 resultMap 元素(重要)

        我们在使用 resultType 的时候,需要保证数据库表中的字段名和表对应实体类的属性名称一致才行(包括驼峰命名规则)。那不一致怎么办,查询的时候可以给列名起个别名,但是一般不建议这样做,而是通过 resultMap 元素进行一个转换。

<!-- id:唯一标识,type:需要映射的 Java 类型-->
<resultMap id="userMap" type="com.entity.User">
    <!-- 与主键字段的对应,property对应实体属性,column对应表字段 -->
    <id property="userId" column="id"/>
    <!-- 与非主键字段的对应,property对应实体属性,column对应表字段 -->
    <result property="userName" column="username"/>
    <result property="userAge" column="age"/>
    <result property="userSex" column="sex"/>
</resultMap>

<!-- 查询所有用户,返回集为resultMap类型,resultMap的value上面配置的 id=userMap 要一致-->
<select id="selectAllUser" resultMap="userMap">
    select * from person
</select>

上述代码是不是很眼熟,在 MyBatis 案例中使用了 @ResultMap 注解来实现上述代码

resultMap 元素的组成

<!-- autoMapping:指定是否自动映射查询结果的列到 Java 对象的属性。
默认为开启(true),如果设置为 false,则需要手动配置每个属性的映射关系 -->
<resultMap id="标识" type="输出类型" extends="继承其他 <resultMap>" autoMapping="自动映射">
    <constructor><!--构造器注入属性值-->
        <!-- 构造器标识,一般为主键 -->
        <!-- column对应表字段,name对应实体属性 -->
        <idArg column="id" name="userId" javaType="int"/>
        <!-- 构造器参数 -->
        <arg column="username" name="userName" javaType="string"/> 
    </constructor>
        <!-- id 与主键字段的对应,property对应实体属性,column对应表字段 -->
        <id property="userId" column="id"/>
        <!-- result 与非主键字段的对应,property对应实体属性,column对应表字段 -->
        <result property="userName" column="username"/>
    <association/><!--高级映射,一对一映射-->
    <collection /><!--高级映射,一对多映射-->
    <discriminator>
        <case/>
    </discriminator><!--根据返回的字段的值封装不同的类型-->
</resultMap>

9 参考文档

Mybatis3详解(四)----SQL映射文件详解(XxxMapper.xml) - 唐浩荣 - 博客园 (cnblogs.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1482836.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue开发实例(二)Vue代码运行及分析配置

Vue项目代码运行及分析 一、项目运行二、目录结构说明1、项目本身结构2、其他可能用到的文件夹 三、建议配置1、启动服务浏览器自动打开页面地址2、关闭eslint校验工具3、 src文件夹的别名的设置 一、项目运行 上篇文件末尾介绍到&#xff0c;进入项目&#xff0c;运行启动命令…

Unity(第二十二部)官方的反向动力学一般使用商城的IK插件,这个用的不多

反向动力学&#xff08;Inverse Kinematic&#xff0c;简称IK&#xff09;是一种通过子节点带动父节点运动的方法。 正向动力学 在骨骼动画中&#xff0c;大多数动画是通过将骨架中的关节角度旋转到预定值来生成的&#xff0c;子关节的位置根据父关节的旋转而改变&#xff0c;这…

【LeetCode】【滑动窗口长度不固定】978 最长湍流子数组

1794.【软件认证】最长的指定瑕疵度的元音子串 这个例题&#xff0c;是滑动窗口中长度不定求最大的题目&#xff0c;在看题之前可以先看一下【leetcode每日一题】【滑动窗口长度不固定】案例。 题目描述 定义&#xff1a;开头和结尾都是元音字母&#xff08;aeiouAEIOU&…

java基础-mysql

文章目录 mysql基础面试题什么是mysql什么是事务并发事务带来的影响事物的隔离级别索引大表优化什么是池化思想&#xff0c;什么是数据库连接池&#xff0c;为什么要用数据库连接池⾏锁&#xff0c;表锁&#xff1b;乐观锁&#xff0c;悲观锁MySQL主备同步的基本原理SQL什么情况…

2024年腾讯云优惠代金券领取入口汇总(新老用户免费领)

腾讯云代金券领取渠道有哪些&#xff1f;腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券&#xff0c;大家也可以在腾讯云百科蹲守代金券&#xff0c;因为腾讯云代金券领取渠道比较分散&#xff0c;腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

基于 STM32U5 片内温度传感器正确测算温度

目录预览 1、引言 2、问题 3、小结 01 引言 STM32 在内部都集成了一个温度传感器&#xff0c;STM32U5 也不例外。这个位于晶圆上的温度传感器虽然不太适合用来测量外部环境的温度&#xff0c;但是用于监控晶圆上的温度还是挺好的&#xff0c;以防止芯片过温运行。 02 问题…

springcloud和基础服务的搭建以及封装

page分页也进行了封装&#xff0c;只需要添加到pom中&#xff0c;将会自动进行分页&#xff0c;并且后端不需要写任何的分页数据。只需要前端自己传分页参数即可&#xff0c;并且里面封装了很多类型的参数类型。自定义的很多注解&#xff0c;并且也支持多个版本的同一个接口名称…

推荐一个屏幕上鼠标高亮显示的小工具

在视频录制等特定场景下&#xff0c;很多人希望在点击鼠标时能够在屏幕上及时进行显示&#xff0c;便于别人发现&#xff0c;提高别人的注意力。 因此&#xff0c;很多录屏软件中都内含显示鼠标点击功能。那如果不支持该怎么办呢&#xff1f;其实&#xff0c;也是可以通过其他工…

MongoDB聚合运算符:$count

文章目录 语法使用举例在$group阶段中使用在$setWindowFields阶段使用 $count聚合运算符返回分组中文档的数量。从5.0开始支持。 语法 { $count: { } }$count不需要参数 使用 $count可以用于下列聚合阶段&#xff1a; $bucket$bucket$group$setWindowFields 在$group阶段中…

vue3创建h5 项目使用rem做响应式的配置

第一步 安装依赖&#xff1a; npm install amfe-flexible -S npm install postcss-px2rem -S第二步 main.ts文件中导入 import "amfe-flexible/index.js";第三步 进行配置&#xff1a; vue3 项目中创建 postcss.cinfig.js文件&#xff0c;这里是基于设计稿是750px…

【k8s管理--两种方式安装prometheus】

1、k8s的监控方案 1.1 Heapster Heapster是容器集群监控和性能分忻工具&#xff0c;天然的支持Kubernetes和CoreOS。 Kubernetes有个出名的监控agent–cAdvisor。在每个kubernetes Node上都会运行cAdvisor&#xff0c;它会收集本机以及容器的监控数(cpu,memory,filesystem,ne…

java学习笔记-初级

完整笔记下载链接&#xff1a;https://download.csdn.net/download/qq_48257021/88800766?spm1001.2014.3001.5503 一、变量 1.双标签 <!-- 外部js script 双标签 --><script srcmy.js></script> 在新文件my.js里面写&#xff1a; 2.字符串定义&#xff…

【模型复现】自制数据集上复现目标检测域自适应 SSDA-YOLO

【模型复现】自制数据集上复现目标检测域自适应 SSDA-YOLO 1. 环境安装2. 数据集制作2.1 数据准备2.2 数据结构 3. 模型训练3.1 数据文件配置3.2 训练超参数配置3.3 模型训练 4. 模型验证4.1 验证超参数配置4.2 模型验证 5. 模型推理5.1 推理超参数配置5.2 模型推理 6. 踩坑记录…

智能驾驶规划控制理论学习03-基于采样的规划方法

目录 一、基于采样的规划方法概述 二、概率路图&#xff08;PRM&#xff09; 1、核心思想 2、实现流程 3、算法描述 4、节点连接处理 5、总结 三、快速搜索随机树&#xff08;RRT&#xff09; 1、核心思想 2、实现流程 3、总结 4、改进RRT算法 ①快速搜索随机图&a…

机器学习---主动学习

1. 概念区分 使用传统的监督学习方法做分类&#xff0c;往往训练样本规模越大&#xff0c;分类的效果越好。但是在现实生活中的 很多场景下&#xff0c;标记样本的获取较困难&#xff0c;需要领域内的专家进行人工标注&#xff0c;需要较大的时间成本和经 济成本。另外&…

R语言安装和简单入门HelloWorld用法

R语言安装和简单入门HelloWorld用法 #R语言安装地址 https://www.r-project.org/ click->CRAN mirror->选择China下列表&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/CRAN/ 选择Download R for Windows 选择base Download R-4.3.2 for Windows 下载文件R-4.3.2-…

Java SPI:Service Provider Interface

SPI机制简介 SPI&#xff08;Service Provider Interface&#xff09;&#xff0c;是从JDK6开始引入的&#xff0c;一种基于ClassLoader来发现并加载服务的机制。 一个标准的SPI&#xff0c;由3个组件构成&#xff0c;分别是&#xff1a; Service&#xff1a;是一个公开的接口…

K线实战分析系列之十四:三只乌鸦,行情趋弱,留意风险

K线实战分析系列之十四&#xff1a;三只乌鸦&#xff0c;行情趋弱&#xff0c;留意风险 一、三只乌鸦二、三只乌鸦形态总结 一、三只乌鸦 理想的三只乌鸦形态 向下的跳空更显示出盘面的弱势 二、三只乌鸦形态总结 三只乌鸦形态由三根K线组成&#xff0c;都是阴线&#xff…

激光雷达原理

全球汽车行业正在进行自动化变革&#xff0c;这将彻底改变交通运输的安全和效率水平。 戴姆勒在S级豪华车型中引入L3级自动驾驶&#xff08;L3&#xff0c;在特定条件下自动驾驶&#xff0c;人类驾驶员一旦被请求就会随时接管&#xff09;是自动驾驶革命的一个重大突破。其他多…

Redis 存储原理和数据模型

redis 是不是单线程 redis 单线程指的是命令处理在一个单线程中。主线程 redis-server&#xff1a;命令处理、网络事件的监听。 辅助线程 bio_close_file&#xff1a;异步关闭大文件。bio_aof_fsync&#xff1a;异步 aof 刷盘。bio_lazy_free&#xff1a;异步清理大块内存。io_…