MyBatis学习笔记(五) —— MyBatis获取参数值的两种方式
5、MyBatis获取参数值的两种方式
MyBatis获取参数值的两种方式:${} 和 #{}
${} 的本质就是字符串拼接, #{} 的本质就是占位符赋值
${} 使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;>但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加>单引号
5.1、单个字面量类型的参数
若mapper接口中的方法参数为单个的字面量类型,
此时可以使用 ${} 和
#{} 以任意的名称获取参数的值,注意${} 需要手动加单引号
UserMapper.java
package com.fan.mybatis.mapper;import com.fan.mybatis.pojo.User;
/*** MyBatis获取参数值的两种方式:#{} 和 ${}* #{}的本质是占位符,${}的本质是字符串拼接* 1、若mapper接口方法的参数为单个的字面量类型* 此时可以通过#{} 和 ${}以任意的内容获取参数值,一定要注意${}的单引号问题
*/public interface UserMapper {/*** 根据用户名查询用户信息* @param username* @return*/User getUserByUsername(String username);
}
UserMapper.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.fan.mybatis.mapper.UserMapper"><select id="getUserByUsername" resultType="User">select * from t_user where username = #{username}</select>
</mapper>
ParameterTest.java
package com.fan.mybatis;import com.fan.mybatis.mapper.UserMapper;
import com.fan.mybatis.pojo.User;
import com.fan.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;public class ParameterTest {@Testpublic void testGetUserByUsername(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);User user = mapper.getUserByUsername("admin");System.out.println(user);}
}
运行,控制台打印输出如下
DEBUG 02-24 17:35:24,407==> Preparing: select * from t_user where username = ? (BaseJdbcLogger.java:137)
DEBUG 02-24 17:35:24,426==> Parameters: admin(String) (BaseJdbcLogger.java:137)
DEBUG 02-24 17:35:24,442<== Total: 1 (BaseJdbcLogger.java:137)
User{id=1, username=‘admin’, password=‘123456’, age=23, gender=‘男’, email=‘12345@qq.com’}
可以看到映射文件中的 #{} 变为? ,#{} 被当做占位符。传过来的参数是admin,查询出来1条数据。
<?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.fan.mybatis.mapper.UserMapper"><select id="getUserByUsername" resultType="User">select * from t_user where username = #{name}</select>
</mapper>
将#{usenrame}变为#{name} , 运行可以看到查询出来的结果。
在mybatis传递参数的过程,不知道传递的参数叫什么名字,只知道传递的值是 admin,所以传递参数值跟#{}里的参数名字没有关系。
建议#{}里的参数名字和传递的参数名一样。
${}测试
错误写法:${username}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper"><select id="getUserByUsername" resultType="User"><!--select * from t_user where username = #{username}-->select * from t_user where username = ${username}</select>
</mapper>

可以看到 admin是一个字符串,传入sql中没有加引号。不加单引号会被当做字段来解析,
Unknown column ‘admin’ in ‘where clause’
where字句中有一个不认识的列/字段 admin
#{}执行sql的时候,占用的是?; ${} 执行sql的时候,是直接拼接在sql中的。
正确写法:‘${usenrame}’
<?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.fan.mybatis.mapper.UserMapper"><select id="getUserByUsername" resultType="User"><!--select * from t_user where username = #{username}-->select * from t_user where username = '${username}'</select>
</mapper>

${}里不能写数值,纯数字是可以运算的。
5.2、多个字面量类型的参数
若mapper接口中的方法参数为多个时,
此时MyBatis会自动将这些参数放在一个map集合中,以arg0, arg1…为键,以参数为值;以param1, param2 … 为键,以参数为值;因此只需要通过${} 和
#{} 访问map集合的键就可以获取相应的值,注意${} 需要手动加单引号
UserMapper.java
package com.fan.mybatis.mapper;import com.fan.mybatis.pojo.User;/*** @Date: 2023/02/24* @Author: fan* @Description:* MyBatis获取参数值的两种方式:#{} 和 ${}* #{}的本质是占位符,${}的本质是字符串拼接* 1、若mapper接口方法的参数为单个的字面量类型* 此时可以通过#{} 和 ${}以任意的内容获取参数值,一定要注意${}的单引号问题* 2、若mapper接口的方法的参数为多个的字面量类型* 此时MyBatis会将参数放在map集合中,以两种方式存储数据* a> 以arg0,arg1,...为键,以参数为值* b> 以param1,param2,...为键,以参数为值* 因此,只需要通过#{}和${}访问map集合的键,就可以获取相对应的值,一定要注意${}的单引号问题*/
public interface UserMapper {/*** 验证登录* @param username* @param password* @return*/User checkLogin(String username,String password);
}
UserMapper.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.fan.mybatis.mapper.UserMapper"><select id="checkLogin" resultType="User">select * from t_user where username = #{username} and password = #{password}</select>
</mapper>
ParameterTest.java
@Testpublic void testCheckLogin(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);User user = mapper.checkLogin("admin","123456");System.out.println(user);
}
运行,控制台报错:
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.apache.ibatis.binding.BindingException: Parameter ‘username’ not found. Available parameters are [arg1, arg0, param1, param2]
### Cause: org.apache.ibatis.binding.BindingException: Parameter ‘username’ not found. Available parameters are [arg1, arg0, param1, param2]

可以看到sql语句没有输出,PersistenceException是配置文件解析错误,BindingException是绑定参数时出现的异常。
Parameter ‘username’ not found. 参数username没有找到。
Available parameters are [arg1, arg0, param1, param2] 可用的参数时arg1, arg0, param1, param2。可参照此方案进行修改。
正确的写法:
方式一
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper"><select id="checkLogin" resultType="User">select * from t_user where username = #{arg0} and password = #{arg1}</select>
</mapper>
运行可以正常输出信息,查询到用户信息。

方式二:
UserMapper.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.fan.mybatis.mapper.UserMapper"><select id="checkLogin" resultType="User"><!--select * from t_user where username = #{arg0} and password = #{arg1}-->select * from t_user where username = #{param1} and password = #{param2}</select>
</mapper>
运行可以正常输出信息,查询到用户信息。

UserMapper.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.fan.mybatis.mapper.UserMapper"><select id="checkLogin" resultType="User"><!--select * from t_user where username = #{arg0} and password = #{arg1}--><!--select * from t_user where username = #{param1} and password = #{param2}--><!--select * from t_user where username = '${arg0}' and password = '${arg0}'-->select * from t_user where username = '${param1}' and password = '${param2}'</select>
</mapper>

如果当前参数有两个时,mybatis会自动把这两个参数放在一个map集合中的。放在map集合中,会以两种方式来存储数据。
第一种方式:以arg0,arg1为键,以参数值为值
第二种方式:以parma1,param2为键,以参数值为值。
相当于从map集合中访问存储的数据。通过map中的键访问对应的值。
5.3、map集合类型的参数
若mapper解耦中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在map中
UserMapper接口
package com.fan.mybatis.mapper;import com.fan.mybatis.pojo.User;/*** 3、若mapper接口方法的参数为map集合类型的参数* 只需要通过#{}和${}访问map集合的键,就可以获取相对应的值,一定要注意${}的单引号问题*/
public interface UserMapper {/*** 添加用户信息* @param user*/void insertUser(User user);
}
ParameterTest.java
@Test
public void testCheckLoginByMap(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);Map<String,Object> map = new HashMap<>();map.put("username","admin");map.put("password","123456");User user = mapper.checkLoginByMap(map);System.out.println(user);
}
UserMapper.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.fan.mybatis.mapper.UserMapper"><select id="checkLoginByMap" resultType="User">select * from t_user where username = #{username} and password = #{password}</select>
</mapper>
运行测试类

5.4、实体类类型的参数
添加用户信息
UserMapper接口
package com.fan.mybatis.mapper;import com.fan.mybatis.pojo.User;/*** 4、若mapper接口方法的参数为实体类类型的参数* 只需要通过#{}和${}访问是实体类中的属性名,就可以获取相对应的属性值,一定要注意${}的单引号问题* 属性名只跟getXxx和setXXX的方法名有关系,把set和get去掉,剩余的字母首字母小写,就是当前的属性名*/
public interface UserMapper {/*** 添加用户信息* @param user*/void insertUser(User user);
}
ParameterTest.java
@Test
public void testInsertUser(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);User user = new User(null,"root","123456",33,"女","123@qq.com");mapper.insertUser(user);
}
运行测试


5.5、使用@Param注解标识参数
可以通过@Param注解标识mapper接口中的方法参数,
此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;以param1,param2…为键,以参数为值;只需要通过$
${}需要手动加单引号。
User checkLoginByParam(@Param("username") String username, @Param("password") String password);
加上@Param(“username”)后,mybatis仍然会将两个参数放进map中,放进map中的键就是@Param括号中的username和password
UserMapper接口
package com.fan.mybatis.mapper;import com.fan.mybatis.pojo.User;
import org.apache.ibatis.annotations.Param;/*** 5、可以在mapper接口方法的参数上设置@Param注解* 此时MyBatis会将这些参数放在map中,以两种方式进行存储* a> 以@Param注解的value属性值为键,以参数为值* b> 以param1,param2...为键,以参数为值* 只需要通过#{}和${}访问map集合的键,就可以获取相对应的值,一定要注意${}的单引号问题。*/
public interface UserMapper {/*** 验证登录(使用@Param)* @param username* @param password* @return*/User checkLoginByParam(@Param("username") String username, @Param("password") String password);
}
UserMapper.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.fan.mybatis.mapper.UserMapper"><!-- User checkLoginByParam(@Param("username") String username, @Param("password") String password); --><select id="checkLoginByParam" resultType="User">select * from t_user where username = #{username} and password = #{password}</select></mapper>
ParameterTest.java
@Test
public void testCheckLoginByParam(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);User user = mapper.checkLoginByParam("admin","123456");System.out.println(user);
}
运行

相关文章:
MyBatis学习笔记(五) —— MyBatis获取参数值的两种方式
5、MyBatis获取参数值的两种方式 MyBatis获取参数值的两种方式:${} 和 #{} ${} 的本质就是字符串拼接, #{} 的本质就是占位符赋值 ${} 使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号&a…...
go module构建项目
在go 1.11版本中引入了Go Module内置的包管理模块,是GOPATH的替代品,集成了版本控制和软件包分发支持的功能。即go使用modules管理依赖,项目依赖构建时不需要再依赖GOPATH环境变量。 要使用go module首先要激活modules .升级go到1.11版本 .这…...
已经准备上千道软件测试面试题了,建议大家收藏!!!还有视频详解!
2023华为软件测试笔试面试真题,抓紧收藏不然就看不到了_测试小鬼的博客-CSDN博客_华为软件测试工程师面试题1、对计算机软件和硬件资源进行管理和控制的软件是(D)A.文件管理程序B.输入输出管理程序C.命令出来程序D.操作系统2、在没有需求文档…...
C++设计模式(19)——访问者模式
亦称: Visitor 意图 访问者模式是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。 问题 假如你的团队开发了一款能够使用巨型图像中地理信息的应用程序。 图像中的每个节点既能代表复杂实体 (例如一座城市)…...
ChatGPT 的工作原理:机器人背后的模型
这篇对支持 ChatGPT 的机器学习模型的温和介绍,将从大型语言模型的介绍开始,深入探讨使 GPT-3 得到训练的革命性自我注意机制,然后深入研究人类反馈的强化学习,使 ChatGPT 与众不同的新技术。 大型语言模型 ChatGPT 是一类被称…...
FreeRTOS入门(04):中断、内存、追踪与调试
文章目录目的中断内存堆(heap)栈(stack)断言调试总结目的 有了前面的几篇文章 FreeRTOS 基本上已经可以在项目中使用上了: 《FreeRTOS入门(01):基础说明与使用演示》 《FreeRTOS入门…...
【C语言】带你彻底理解指针(1)
✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦!!✨✨✨✨ 文章目录指针的介绍:一、简单指针🌈1.1 指针的定义与使用1.2 指针与数组二、指针数组✨三、数组指针🌞3.1 数组指针的定义3.2 ”数组名“与”&数组名“3.…...
C/C++ 中 JSON 库的使用 (CJSON/nlohmann)
C/C 中 JSON 库的使用 (CJSON/nlohmann)概述cjson基本操作从(字符指针)缓冲区中解析出JSON结构转成成JS字符串(将传入的JSON结构转化为字符串)将JSON结构所占用的数据空间释放JSON 值的创建创建一个值类型的数据创建一个对象(文档)…...
【Opencv项目实战】目标检测:自动检测出现的所有动态目标
文章目录一、项目思路二、算法详解2.1、计算两个数组或数组与标量之间的每个元素的绝对差。2.2、轮廓检测 绘制物体轮廓 绘制矩阵轮廓2.3、连续窗口显示2.4、读取视频,显示视频,保存视频三、项目实战:实时动态目标检测实时动态目标检测一、…...
活动报名:Tapdata Cloud V3 最新功能全解与核心应用场景演示
作为中国的 “Fivetran/Airbyte”, Tapdata Cloud 自初版公测以来,已累积10,000 注册用户。核心场景包括 Any Source → Any Target 的实时数据库同步、数据入湖入仓,以及通用 ETL 处理等。近期,功能特性全面优化的 Tapdata Cloud V3 也已开放…...
人工智能AI威武,爱也……恨也……
人工智能AI威武,爱也!恨也!!它会创作会代码,从它那儿能仿到更好的思维;多它那里可以学到更好的代码。它聪慧全能,成为一坨人偷懒神器;变成“智者”作弊的“倚天屠龙”!&a…...
SpringBoot-基础篇
SpringBoot基础篇 在基础篇中,我给学习者的定位是先上手,能够使用SpringBoot搭建基于SpringBoot的web项目开发,所以内容设置较少,主要包含如下内容: SpringBoot快速入门SpringBoot基础配置基于SpringBoot整合SSMP…...
Tapdata Connector 实用指南:实时数仓场景之数据实时同步至 ClickHouse
【前言】作为中国的 “Fivetran/Airbyte”, Tapdata 是一个以低延迟数据移动为核心优势构建的现代数据平台,内置 60 数据连接器,拥有稳定的实时采集和传输能力、秒级响应的数据实时计算能力、稳定易用的数据实时服务能力,以及低代码可视化操作…...
刷题专练之数组移除元素
文章目录前言一、移除元素1.题目介绍2.思路:3.代码二、移动零1.题目介绍2.思路3.代码三、删除有序数组中的重复项1.题目介绍2.思想3.代码四、80. 删除有序数组中的重复项 II1.题目介绍2.思路3.代码4.推荐题解前言 我每个刷题篇的题目顺序都是特别安排的,…...
常见激活函数Activation Function的选择
Activation Function激活函数一般会神经网络中隐层和输出层上,其中作用在输出层主要用于适配输出,比如sigmoid函数可用于生成[0,1]之间的概率估计值。而作用于隐层主要用于增加神经网络的非线性,增加了网络的表达能力,本文主要介绍…...
大厂跟进ChatGPT,为什么百度“文心一言”成色最好?【快评】
作者 | 曾响铃 文 | 响铃说 赶ChatGPT热度,百度3月初就要发布与ChatGPT类似的人工智能聊天机器人服务“文心一言”(英文名:ERNIE Bot),似乎无法提振资本市场对百度的信心。 2022年第四季度及全年未经审计的财报发布…...
ChatGPT和Web3:人工智能如何帮助您建立和发展您的 Web3 公司
ChatGPT是OpenAI在2022年11月推出的聊天机器人。该机器人建立在OpenAI的GPT-3人工智能家族上,并通过监督学习和强化学习技术进行了优化。 与ChatGPT机器人聊天时,你会感觉自己在与一个懂得一切并以非常教育性的方式回答的朋友交谈。回答在许多知识领域非…...
【人工智能 AI】怎样实施RPA 机器人流程自动化(Robotic Process Automation)?核心技术有哪些?
文章目录 RPA 简介RPA的实施RPA的核心技术1. 自动化测试(1)自动化测试工具(2)自动化测试框架2. 自动化脚本(1)自动化脚本语言(2)自动化脚本框架3. 机器学习(1)机器学习模型(2)机器学习框架(3)自然语言处理(4)图像处理(5)深度学习(6)机器人操作系统RPA核心能…...
基于BP神经网络的性别识别,BP神经网络详细原理,自编码神经网络代码,神经网络案例之18
目标 背影 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数, BP神经网络的传递函数 数据 神经网络参数 基于BP神经网络 性别识别的MATLAB代码 效果图 结果分析 展望 背影 男人体内蛋白质比例大,女生…...
2023年消费电子行业研究报告
第一章 行业概况 消费电子行业是电子信息行业的子行业。消费电子是指围绕着消费者应用而设计的与生活、工作和娱乐息息相关的电子类产品,通常会应用于娱乐、通讯以及文书用途,最终实现消费者自由选择资讯、享受娱乐的目的,主要侧重于个人购买…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...
五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
轻量级Docker管理工具Docker Switchboard
简介 什么是 Docker Switchboard ? Docker Switchboard 是一个轻量级的 Web 应用程序,用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器,使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...
