MyBatis系列三: XxxMapper.xml-SQL映射文件

XxxMapper.xml-SQL映射文件

  • 官方文档
  • 基本介绍
  • 详细说明
    • 基本使用
    • parameterType(输入参数类型)
    • 传入HashMap
    • resultMap(结果集映射)

在这里插入图片描述

官方文档

文档地址: https://mybatis.org/mybatis-3/zh_CN/sqlmap-xml.html

基本介绍

1.MyBatis的真正强大在于它的语句映射(在XxxMapper.xml配置), 由于它的异常强大, 如果拿它跟具有相同功能的JDBC代码进行对比, 你会立即发现省掉了将近95%的代码. MyBatis致力于减少使用成本, 让用户能更专注于SQL代码.

2.SQL映射文件常用的几个顶级元素 (按照应被定义的顺序列出) :

cache - 该命名空间的缓存配置
cache-ref - 引用其它命名空间的缓存配置
resultMap - 描述如何从数据集结果集中加载对象, 是最复杂也是最强大的元素
parameterType - 将会传入这条语句的参数的类全限定名或别名

sql - 可被其它语句引用的可重复的语句块.
insert - 映射插入语句
update - 映射更新语句
delete - 映射删除语句
select - 映射查询语句

详细说明

1.在原来的mybatis项目中, 新建xml-mapper子项目 [参考], 演示xml映射器的使用

2.新建Module后, 先创建需要的包, 再将需要的文件 / 资源拷贝过来(这里我们拷贝Monster.java, resources/jdbc.propertiesmybatis-config.xml)

3.拷贝MonsterMapper.java, MonsterMapper.xmlMonsterMapperTest.java, 做一个比较 干净的讲解环境

基本使用

1.insert, delete, update, select这个我们在前面学习过, 分别对应增删改查的方法和SQL语句的映射
2.如何获取到刚刚添加的Monster对象的id主键 [前面讲解过了]

<insert id="addMonster" parameterType="Monster" useGeneratedKeys="true" keyProperty="id">INSERT INTO `monster` (`age`, `birthday`, `email`, `gender`, `name`, `salary`)VALUES (#{age}, #{birthday}, #{email}, #{gender}, #{name}, #{salary})
</insert>

parameterType(输入参数类型)

●parameterType(输入参数类型)
1.传入简单类型, 比如按照idMonster(前面学过)
2.传入POJO类型, 查询时需要有多个筛选条件
3.当有多个条件时, 传入的参数就是Pojo类型的Java对象, 比如这里的Monster对象
4.当传入的参数类是String时, 也可以使用 ${} 来接收参数

●parameterType-应用案例
案例1: 请查询 id = 1 或者 name = 大象精 的妖怪
案例2: 请查询 name 中包含 “牛魔王” 的妖怪

●代码实现
1.修改MonsterMapper.java, 增加方法接口

public interface MonsterMapper {//通过id 或者 名字查询public List<Monster> findMonsterByNameOrId(Monster monster);//查询名字中含有牛魔王的妖怪public List<Monster> findMonsterByName(String name);
}

2.修改MonsterMapper.xml

<mapper namespace="com.zzw.mapper.MonsterMapper"><!--1. 配置/实现public List<Monster> findMonsterByNameOrId(Monster monster);2. 通过id 或者 名字查询3. `id` = #{id} `id`表示表的字段名 #{id}中的id表示你传入的Monster对象的属性名--><select id="findMonsterByNameOrId" parameterType="Monster" resultType="Monster">SELECT * FROM `monster` WHERE `id` = #{id} OR `name` = #{name}</select><!--1. 配置/实现public List<Monster> findMonsterByName(Monster monster);2. 查询名字中 含有 "牛魔王" 的妖怪 - 模糊查询`3. 模糊查询的使用 取值需要 ${value} 取值--><select id="findMonsterByName" parameterType="String" resultType="Monster">SELECT * FROM `monster` WHERE `name` LIKE '%${name}%'</select>
</mapper>

3.修改MonsterMapperTest.java, 进行测试

public class MonsterMapperTest {//属性private SqlSession sqlSession;private MonsterMapper monsterMapper;//编写方法完成初始化@Beforepublic void init() {//获取到sqlSessionsqlSession = MyBatisUtils.getSqlSession();//获取到MonsterMapper对象 monsterMapper=class com.sun.proxy.$Proxy7 代理对象//, 底层是使用了动态代理机制, 后面我们自己实现mybatis底层机制时, 会讲到monsterMapper = sqlSession.getMapper(MonsterMapper.class);System.out.println("monsterMapper=" + monsterMapper.getClass());}@Testpublic void findMonsterByNameOrId(){Monster monster = new Monster();monster.setId(1);monster.setName("大象精");List<Monster> monsters =monsterMapper.findMonsterByNameOrId(monster);for (Monster m : monsters) {System.out.println("m--" + m);}if (sqlSession != null) {sqlSession.close();}System.out.println("查询成功");}@Testpublic void findMonsterByName() {List<Monster> monsters = monsterMapper.findMonsterByName("牛魔王");for (Monster monster : monsters) {System.out.println("monster--" + monster);}if (sqlSession != null) {sqlSession.close();}System.out.println("查询成功");}
}

传入HashMap

●传入HashMap(重点)
1.HashMap传入参数更加灵活, 比如可以灵活地增加查询的属性, 而不受限于Monster这个Pojo属性本身
2.演示如何遍历一个List<Map<String, Object>>的数据类型

●传入HashMap - 应用实例1
要求: 声明一个方法, 按传入参数是HashMap的方式, 查询 id > 10 并且 salary > 40的所有妖怪

1.修改MonsterMapper.java, 增加方法接口

//查询 id > 10 并且 salary > 40的所有妖怪
public List<Monster> findMonsterByIdAndSalary_ParameterHashMap(Map<String, Object> map);

2.修改MonsterMapper.xml

<!--
1. 配置/实现public List<Monster> findMonsterByIdAndSalary_ParameterHashMap(Map<String, Objects> map);
2. 查询 id > 10 并且 salary > 40的所有妖怪
3. 如果是以map形式传入参数, 当你这样写条件 `id` > #{id} 表示你的map 中有一个k-v 中 key为id
-->
<select id="findMonsterByIdAndSalary_ParameterHashMap" parameterType="map" resultType="Monster">SELECT * FROM `monster` WHERE `id` > #{id} AND `salary` > #{salary}
</select>

3.修改MonsterMapperTest.java, 进行测试

@Test
public void findMonsterByIdAndSalary_ParameterHashMap() {Map<String, Object> map = new HashMap<>();map.put("id", 10);map.put("salary", 40);List<Monster> monsters =monsterMapper.findMonsterByIdAndSalary_ParameterHashMap(map);for (Monster monster : monsters) {System.out.println("monster--" + monster);}if (sqlSession != null) {sqlSession.close();}System.out.println("查询成功");
}

●传入和返回HashMap - 应用实例2
要求: 将上面的方法改成返回参数也是HashMap的类型

1.修改MonsterMapper.java, 增加方法接口

//查询 id > 10 并且 salary > 40, 要求传入的参数是HashMap
public List<Map<String, Object>>findMonsterByIdAndSalary_ParameterHashMap_ReturnHashMap(Map<String, Object> map);

2.修改MonsterMapper.xml

<!--
1. 配置/实现public List<Map<String, Object>>findMonsterByIdAndSalary_ParameterHashMap_ReturnHashMap
2. 查询 id > 10 并且 salary > 40, 要求传入的参数是HashMap
-->
<select id="findMonsterByIdAndSalary_ParameterHashMap_ReturnHashMap" parameterType="map"resultType="map">SELECT * FROM `monster` WHERE `id` > #{id} AND `salary` > #{salary}
</select>

3.修改MonsterMapperTest.java, 进行测试

@Test
public void findMonsterByIdAndSalary_ParameterHashMap_ReturnHashMap() {Map<String, Object> map = new HashMap<>();map.put("id", 10);map.put("salary", 40);List<Map<String, Object>> maps =monsterMapper.findMonsterByIdAndSalary_ParameterHashMap_ReturnHashMap(map);//取出返回的结果-以map的形式取出//回顾java基础, map遍历for (Map<String, Object> monsterMap : maps) {//System.out.println("monsterMap--" + monsterMap);//遍历monsterMap(方式1), 取出属性和对应值//Set<String> keySet = monsterMap.keySet();//for (String key : keySet) {//    Object value = monsterMap.get(key);//    System.out.println(key + "=>" + value);//}//遍历monsterMap(方式2), 取出属性和对应值Set<Map.Entry<String, Object>> entries = monsterMap.entrySet();for(Map.Entry<String, Object> entry : entries) {System.out.println(entry.getKey() + "=>" + entry.getValue());}System.out.println("==================================");}if (sqlSession != null) {sqlSession.close();}System.out.println("查询成功");
}

resultMap(结果集映射)

●基本介绍
当实体类的属性和表的字段不一致时, 我们可以通过resultMap进行映射, 从而屏蔽实体类属性名和表的字段名的不同.

●案例演示
1.创建表user

-- 创建表 user
CREATE TABLE `user` (`user_id` INT NOT NULL AUTO_INCREMENT,`user_email` VARCHAR(255) DEFAULT '',`user_name` VARCHAR(255) DEFAULT '',PRIMARY KEY (`user_id`)
)CHARSET=utf8

2.创建实体类com.zzw.entity.User

public class User {private Integer user_id;private String username;private String useremail;//setter, getter, toString方法
}

3.创建com.zzw.mapper.UserMapper.java

public interface UserMapper {//添加方法public void addUser(User user);//查询所有Userpublic List<User> findAllUser();
}

4.创建com.zzw.mapper.UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--解读1. 这是一个mapper xml 文件2. 该文件可以去实现对应的接口的方法3. namespace 指定该xml文件和哪个接口对应!!!
-->
<mapper namespace="com.zzw.mapper.UserMapper"><!--1. 配置/实现public void addUser(User user);2. 完成添加用户的任务,注意这里--><select id="addUser" parameterType="User">INSERT INTO `user` (`user_email`, `user_name`)VALUES (#{useremail}, #{username})</select><!--1.配置/实现public List<User> findAllUser();2.返回所有User信息3.按照传统的方式完成, 会出现什么问题?=> 如果对象属性和表字段相同时, 就会设置值; 如果不同, 就会是默认值4.我们可以使用resultMap来解决5.resultMap: 表示我们要定义一个resultMap6.id="findAllUserMap" type="User" => id 就是程序员指定的resultMap id, 后面通过id可以使用它7.type="User", 就是你需要返回的对象类型8.result column="user_name" property="username": column="user_name" 表的字段名, property="username" 对象属性名9.resultMap="findAllUserMap" 表示使用我们定义的 resultMap, 通过id关联--><resultMap id="findAllUserMap" type="com.zzw.entity.User"><result column="user_name" property="username"/><result column="user_email" property="useremail"/></resultMap><select id="findAllUser" resultMap="findAllUserMap">SELECT * FROM `user`</select>
</mapper>

5.测试com.zzw.mapper.UserMapperTest

public class UserMapperTest {//属性private SqlSession sqlSession;private UserMapper userMapper;//初始化@Beforepublic void init() {sqlSession = MyBatisUtils.getSqlSession();userMapper = sqlSession.getMapper(UserMapper.class);}@Testpublic void addUser() {User user = new User();user.setUsername("jack");user.setUseremail("jack@163.com");userMapper.addUser(user);//如果是增删改, 需要提交事务if (sqlSession != null) {sqlSession.commit();sqlSession.close();}System.out.println("增加成功");}@Testpublic void findAllUser() {List<User> users = userMapper.findAllUser();for (User user : users) {System.out.println("user--" + user);}if (sqlSession != null) {sqlSession.close();}System.out.println("查询成功");}
}

●注意事项和细节
1.解析表字段和对象属性名不一致, 也支持使用字段别名

<!--使用表字段别名, 来解决表的字段名和对象属性名, 不一致问题, 可以用, 但是我们仍然推荐使用resultMap-->
<select id="findAllUser" resultType="User">SELECT user_id, user_name as username, user_email as useremail FROM `user`
</select>

2.说明: 如果是MyBatis-Plus处理就比较简单, 可以使用 注解TableField 来解决实体字段名和表字段名不一致的问题, 还可以使用@TableName来解决 实体类名和表名不一致的问题

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

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

相关文章

网络配线架的隐藏功能

网络布线是确保现代信息社会高效运转的关键技术之一。在这一领域&#xff0c;网络配线架扮演着至关重要 的角色。它不仅仅是一个简单的物理连接点&#xff0c;更拥有许多隐藏功能&#xff0c;这些功能极大地提升了网络的 效率、稳定性和可管理性。 1、集中管理 网络配线架提…

【BES2500x系列 -- RTX5操作系统】深入探索CMSIS-RTOS RTX -- 同步与通信篇 -- 消息队列和邮箱处理 --(四)

&#x1f48c; 所属专栏&#xff1a;【BES2500x系列】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f49…

经典FC游戏web模拟器--EmulatorJS

简介 EmulatorJS是一个基于JavaScript和Webassembly技术的虚拟环境的实现&#xff0c;可以在网页中运行各种经典FC游戏系统&#xff0c;支持任天堂、世嘉、雅达利等经典红白机。EmulatorJS的诞生使得诸如超级玛丽、坦克大战、魂斗罗等经典FC游戏能够以一种全新的方式回归。本文…

SAP MM模块的ATP检查

前面几篇文章都演示和说明ATP的一些设置和操作&#xff0c;通常情况下ATP的检查PP模块&#xff0c;SD模块用的相对来说是比较多的&#xff0c;但是实际上MM模块也会遵循ATP的可用性的检查规则。 当我们在做311、301等移动类型时&#xff0c;系统会根据相应的可用性检查规则&am…

Django 多对多关系

多对多关系作用 Django 中&#xff0c;多对多关系模型的作用主要是为了表示两个模型之间的多对多关系。具体来说&#xff0c;多对多关系允许一个模型的实例与另一个模型的多个实例相关联&#xff0c;反之亦然。这在很多实际应用场景中非常有用&#xff0c;比如&#xff1a; 博…

BMA530 运动传感器

型号简介 BMA530是博世&#xff08;bosch-sensortec&#xff09;的一款运动传感器。时尚简约的可穿戴设备为功能强大的组件提供了很小的空间。具有先进功能集的下一代加速度计是世界上最小的加速度传感器&#xff08;1.2 x 0.8 x 0.55 mm&#xff09;。它专为紧凑型设备而设计&…

24/07/02数据结构(1.1201)算法效率顺序表

数据结构基本内容:1.时间复杂度 空间复杂度2.顺序表链表3.栈 队列4.二叉树5.排序 数据结构是存储,组织数据的方式.指相互之间存在一种或多种特定关系的数据元素的集合 算法是定义良好的计算过程.取一个或一组值为输入并产生一个或一组值为输出. 需要知道虽然选择题有20-30个…

python自动化运维--DNS处理模块dnspython

1.dnspython介绍 dnspython是Pyhton实现的一个DNS工具包&#xff0c;他几乎支持所有的记录类型&#xff0c;可以用于查询、传输并动态更新ZONE信息&#xff0c;同事支持TSIG&#xff08;事物签名&#xff09;验证消息和EDNS0&#xff08;扩展DNS&#xff09;。在系统管理方面&a…

Linux高并发服务器开发(九)Tcp状态转移和IO多路复用

文章目录 0 包裹函数1 多进程服务器流程代码 2 多线程服务器3 TCP状态转移半关闭心跳包 4 端口复用5 IO多路复用技术高并发服务器 6 select代码总结 7 POLLAPI代码poll相对select的优缺点 8 epoll&#xff08;重点&#xff09;API监听管道代码EPOLL 高并发服务器 9 Epoll的两种…

Iot解决方案开发的体系结构模式和技术

前言 Foreword 计算机技术起源于20世纪40年代&#xff0c;最初专注于数学问题的基本原理&#xff1b;到了60年代和70年代&#xff0c;它以符号系统为中心&#xff0c;该领域首先开始面临复杂性问题&#xff1b;到80年代&#xff0c;随着个人计算的兴起和人机交互的问题&#x…

【进阶篇】Java 项目中对使用递归的理解分享

前言 笔者在最近的项目开发中&#xff0c;遇到了两个父子关系紧密相关的场景&#xff1a;评论树结构、部门树结构。具体的需求如&#xff1a;找出某条评论下的所有子评论id集合&#xff0c;找出某个部门下所有的子部门id集合。 在之前的项目开发经验中&#xff0c;递归使用得是…

【LeetCode】十、二分查找法:寻找峰值 + 二维矩阵的搜索

文章目录 1、二分查找法 Binary Search2、leetcode704&#xff1a;二分查找3、leetcode35&#xff1a;搜索插入位置4、leetcode162&#xff1a;寻找峰值5、leetcode74&#xff1a;搜索二维矩阵 1、二分查找法 Binary Search 找一个数&#xff0c;有序的情况下&#xff0c;直接…

【动态规划 前缀和】2478. 完美分割的方案数

本文涉及知识点 划分型dp 动态规划汇总 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode 2478. 完美分割的方案数 给你一个字符串 s &#xff0c;每个字符是数字 ‘1’ 到 ‘9’ &#xff0c;再给你两个整数 k 和 minLength 。 如…

Wireshark - tshark支持iptables提供数据包

tshark现在的数据包获取方式有两种&#xff0c;分别是读文件、网口监听&#xff08;af-packet原始套接字&#xff09;。两种方式在包获取上&#xff0c;都是通过读文件的形式&#xff1b;存在文件io操作&#xff0c;在专门处理大流量的情境下&#xff0c; 我们复用wireshark去做…

Windows编程上

Windows编程[上] 一、Windows API1.控制台大小设置1.1 GetStdHandle1.2 SetConsoleWindowInfo1.3 SetConsoleScreenBufferSize1.4 SetConsoleTitle1.5 封装为Innks 2.控制台字体设置以及光标调整2.1 GetConsoleCursorInfo2.2 SetConsoleCursorPosition2.3 GetCurrentConsoleFon…

python如何输出list

直接输出list_a中的元素三种方法&#xff1a; list_a [1,2,3,313,1] 第一种 for i in range(len(list_a)):print(list_a[i]) 1 2 3 313 1 第二种 for i in list_a:print(i) 1 2 3 313 1 第三种&#xff0c;使用enumerate输出list_a方法&#xff1a; for i&#xff0c;j in enum…

Redis的使用(二)redis的命令总结

1.概述 这一小节&#xff0c;我们主要来研究一下redis的五大类型的基本使用&#xff0c;数据类型如下&#xff1a; redis我们接下来看一看这八种类型的基本使用。我们可以在redis的官网查询这些命令:Commands | Docs,同时我们也可以用help 数据类型查看命令的帮助文档。 2. 常…

opencascade AIS_InteractiveContext源码学习7 debug visualization

AIS_InteractiveContext 前言 交互上下文&#xff08;Interactive Context&#xff09;允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是&#xff0c;对于已经被交互上下文识别的交互对象&#xff0c;必须使用上下文方法进行…

【问题已解决】Vue管理后台,点击登录按钮,会发起两次网络请求(竟然是vscode Compile Hero编译插件导致的)

问题 VueElement UI 做的管理后台&#xff0c;点击登录按钮&#xff0c;发现 接口会连续掉两次&#xff0c;发起两次网络请求&#xff0c;但其他接口都是正常调用的&#xff0c;没有这个问题&#xff0c;并且登录按钮也加了loading&#xff0c;防止重复点击&#xff0c;于是开…

JavaMySQL 学习(基础)

目录 Java CMD Java发展 计算机存储规则 Java学习 switch新用法&#xff08;可以当做if来使用&#xff09; 数组定义 随机数 Java内存分配 MySQL MySQL概述 启动和停止 客户端连接 数据模型 关系型数据库 SQL SQL通用语法 SQL分类 DDL--数据定义语言 数据库…