Mybatis 使用参数时$与#的区别
之前我们介绍了mybatis中参数的使用,本篇我们在此基础上介绍Mybatis中使用参数时$与#的区别。
如果您对mybatis中参数的使用不太了解,建议您先进行了解后再阅读本篇,可以参考:
Mybatis参数(parameterType)https://blog.csdn.net/m1729339749/article/details/132548838
一、创建实体类
在cn.horse.demo下创建UserInfo、UserInfoQuery类
UserInfo类:
package cn.horse.demo;public class UserInfo {private Integer id;private String name;private Integer age;public void setId(Integer id) {this.id = id;}public Integer getId() {return id;}public void setName(String name) {this.name = name;}public String getName() {return name;}public void setAge(Integer age) {this.age = age;}public Integer getAge() {return age;}@Overridepublic String toString() {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append('{');stringBuilder.append("id: " + this.id);stringBuilder.append(", ");stringBuilder.append("name: " + this.name);stringBuilder.append(", ");stringBuilder.append("age: " + this.age);stringBuilder.append('}');return stringBuilder.toString();}
}
UserInfoQuery类:
package cn.horse.demo;public class UserInfoQuery {private Integer startAge;private Integer endAge;private Integer start;private Integer limit;public void setStartAge(Integer startAge) {this.startAge = startAge;}public Integer getStartAge() {return startAge;}public void setEndAge(Integer endAge) {this.endAge = endAge;}public Integer getEndAge() {return endAge;}public void setStart(Integer start) {this.start = start;}public Integer getStart() {return start;}public void setLimit(Integer limit) {this.limit = limit;}public Integer getLimit() {return limit;}
}
二、创建映射器、Mapper配置
在cn.horse.demo下创建UserInfoMapper接口
UserInfoMapper接口:
package cn.horse.demo;import org.apache.ibatis.annotations.*;import java.util.List;public interface UserInfoMapper {List<UserInfo> find(@Param("query") UserInfoQuery query);
}
在resources下创建cn/horse/demo目录,并在此目录下创建UserInfoMapper.xml配置文件
UserInfoMapper.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">
<mapper namespace="cn.horse.demo.UserInfoMapper"><resultMap id="userInfoMap" type="cn.horse.demo.UserInfo"><result column="ID" property="id" /><result column="USERNAME" property="name"/><result column="AGE" property="age"/></resultMap><select id="find" parameterType="cn.horse.demo.UserInfoQuery" resultMap="userInfoMap">SELECTID,USERNAME,AGEFROM ${userTableName}<where><if test="null != query.startAge">AND AGE >= #{query.startAge}</if><if test="null != query.endAge">AND AGE <= #{query.endAge}</if></where>LIMIT ${query.start}, ${query.limit}</select>
</mapper>
配置中我们使用${userTableName}获取用户表名称,使用${query.start}、${query.limit}获取分页信息,使用#{query.startAge}、#{query.endAge}获取查询条件信息
三、引入配置文件
在resources下新建mybatis-config.xml配置文件,并引入UserInfoMapper映射器。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties><property name="userTableName" value="T_USER"/></properties><settings><setting name="logImpl" value="JDK_LOGGING"/></settings><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="org.gjt.mm.mysql.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/demo?useUnicode=true&useSSL=false&characterEncoding=utf8&allowMultiQueries=true"/><property name="username" value="root"/><property name="password" value="horse"/></dataSource></environment></environments><mappers><mapper class="cn.horse.demo.UserInfoMapper" /></mappers>
</configuration>
这里,我们在mybatis中定义了属性名为userTableName属性值为T_USER的属性,并使用mapper引入了映射器。
四、启动程序
1、数据准备
这里我们直接使用脚本初始化数据库中的数据
-- 如果数据库不存在则创建数据库
CREATE DATABASE IF NOT EXISTS demo DEFAULT CHARSET utf8;
-- 切换数据库
USE demo;
-- 创建用户表
CREATE TABLE IF NOT EXISTS T_USER(ID INT PRIMARY KEY,USERNAME VARCHAR(32) NOT NULL,AGE INT NOT NULL
);
-- 插入用户数据
INSERT INTO T_USER(ID, USERNAME, AGE)
VALUES(1, '张三', 20),(2, '李四', 22),(3, '王五', 24);
创建了一个名称为demo的数据库;并在库里创建了名称为T_USER的用户表并向表中插入了数据
2、会话工具类
在cn.horse.demo包下新建SqlSessionUtils工具类
package cn.horse.demo;import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.InputStream;
import java.util.Objects;public class SqlSessionUtils {private static final SqlSessionFactory sqlSessionFactory;static {// 读取mybatis配置文件InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");// 根据配置创建SqlSession工厂sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}/*** 开启会话* @return*/public static SqlSession openSession() {return sqlSessionFactory.openSession();}/*** 关闭会话* @param sqlSession*/public static void closeSession(SqlSession sqlSession) {if(Objects.nonNull(sqlSession)) {sqlSession.close();}}
}
3、JDK 日志系统配置
在resources的目录下新建logging.properties配置文件
handlers=java.util.logging.ConsoleHandler
.level=INFOcn.horse.demo.level=FINER
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tT.%1$tL %4$s %3$s - %5$s%6$s%n
在cn.horse.demo下创建JdkLogConfig类
JdkLogConfig类:
package cn.horse.demo;import java.io.IOException;
import java.io.InputStream;
import java.util.logging.LogManager;public class JdkLogConfig {public JdkLogConfig() {try {InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("logging.properties");LogManager.getLogManager().readConfiguration(inputStream);} catch (IOException e) {throw new RuntimeException(e);}}
}
4、启动程序
package cn.horse.demo;import org.apache.ibatis.session.SqlSession;import java.util.List;
import java.util.function.Consumer;
import java.util.logging.Logger;public class Main {private static final Logger LOGGER;static {// 引入JDK日志配置System.setProperty("java.util.logging.config.class", "cn.horse.demo.JdkLogConfig");LOGGER = Logger.getLogger("cn.horse.demo.Main");}public static void main(String[] args) throws InterruptedException {execute((UserInfoMapper userInfoMapper) -> {UserInfoQuery query = new UserInfoQuery();query.setStartAge(0);query.setEndAge(24);query.setStart(0);query.setLimit(1);List<UserInfo> userInfoList = userInfoMapper.find(query);for (UserInfo userInfo: userInfoList) {LOGGER.info(userInfo.toString());}});}private static void execute(Consumer<UserInfoMapper> function) {SqlSession sqlSession = null;try {sqlSession = SqlSessionUtils.openSession();function.accept(sqlSession.getMapper(UserInfoMapper.class));sqlSession.commit();} finally {SqlSessionUtils.closeSession(sqlSession);}}
}
execute方法用于执行操作,方法中使用sqlSession.getMapper方法获取映射器对象,然后将映射器对象具体的执行操作委托给了Consumer对象。
执行后的结果如下:
现象:
从日志打印的SQL语句中可以看出参数${userTableName}被替换成了T_USER,${query.start}被替换成了0,${query.limit}被替换成了1;而#{query.startAge}、#{query.endAge}被替换成了?;
结论:
使用$获取参数时在执行SQL语句时参数会被替换,使用$获取的参数可以是在mybatis中定义的属性。
使用#获取参数时在执行SQL语句时会进行预处理以避免SQL注入。
相关文章:
Mybatis 使用参数时$与#的区别
之前我们介绍了mybatis中参数的使用,本篇我们在此基础上介绍Mybatis中使用参数时$与#的区别。 如果您对mybatis中参数的使用不太了解,建议您先进行了解后再阅读本篇,可以参考: Mybatis参数(parameterType)https://blog.csdn.net…...
解锁Spring Boot的强大配置功能:@ConfigurationProperties与@PropertySources详解
解锁Spring Boot的强大配置功能:ConfigurationProperties与PropertySources详解 前言什么是ConfigurationProperties和PropertySourcesConfigurationProperties的使用步骤 1: 创建 Java POJO 类步骤 2: 配置类步骤 3: 配置文件步骤 4: 注入配置属性 PropertySources…...
Java和Vue字符串加密
字符串加密 AES 加密算法 在 Java 中,可以使用不同的加密算法来对字符串进行加密。以下是使用 AES 加密算法的示例代码,演示如何对一个字符串进行加密: import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java…...
Java:java版结巴分词:jieba-analysis
文档 https://github.com/huaban/jieba-analysishttps://mvnrepository.com/artifact/com.huaban/jieba-analysis 依赖 <!-- https://mvnrepository.com/artifact/com.huaban/jieba-analysis --> <dependency><groupId>com.huaban</groupId><art…...
java生成一个符合密码学和安全性的随机秘钥
有时 我们在生成token 或者完成某种加密形式时会需要一个秘钥 但是 有些时候 项目开发并没有规定用什么秘钥 但是 秘钥都是要有一定格式规范的 我们可以通过以下代码生成一个随机秘钥 import java.security.SecureRandom; import java.util.Base64;public class TokenGenerat…...
C++ - 右值引用 和 移动拷贝
右值引用 我们先来了解什么是左值,什么是右值: 左值 和 有值 区分 首先,左值 和 右值 并不是完全意味着 在 "" 左边的就是 左值 ; 在 "" 右边的就是右值。这是不一定的。只能说,在左边的大概率是…...
项目成员积分规则
在当下的项目/团队管理种,如何让成员能清晰的看到,自己的工作、努力在团队种属于那个段位,通过这个形式,并配合其他方式去点燃成员的进步之心。以积分的形式,代替绩效考核,一些零散的想法,欢迎各…...
Linux CentOS7 vim多窗口编辑
我们在用vim编辑文件时,有各种需求。如有时需要在多个文件之间来回操作,一会关闭一个文件,一会再打开另外一个文件,这样来回操作显得太笨拙。有时,vim编辑多行的大文件,来回查看、编辑前面一部分及最后一部…...
git使用,一点点
查看自己有没有安装git git --version 如果没有安装请执行sudo yum install -y git来安装 git 指令 git log 查看日志 git pull 同步远端和本地仓库 这就是冲突的报错: 所以这个时候你要同步一下git pull...
第五章:最新版零基础学习 PYTHON 教程—Python 字符串操作指南(第八节 - 如何在 C/C++、Python 和 Java 中分割字符串?)
通过某些分隔符分割字符串是一项非常常见的任务。例如,我们有一个文件中以逗号分隔的项目列表,并且我们希望数组中包含各个项目。 几乎所有编程语言都提供按某些分隔符分割字符串的函数。 目录 在C中: 在 C++ 中 方法一:使用C++的stringstream API...
【Java】语法特性篇
语法特性篇 Java对象的比较 1. 对象比较的问题 Java中引用类型的变量不能直接按照 > 或者 < 方式进行比较。那为什么可以比较? 因为:对于用户实现自定义类型,都默认继承自Object类,而Object类中提供了equal方法…...
Vim教程
目录 vim 介绍 常用的四种模式 首先先学会如何正确进入和退出vim: normal模式 insert模式: command模式: v-block模式: vim异常退出 vim配置 vim 介绍 Vim是一款高度可定制的文本编辑器,它的前身是Vi…...
selenium查找网页如何处理网站资源一直加载非常卡或者失败的情况
selenium查找网页如何处理网站资源一直加载失败的情况 selenium获取一个网页,某个网页的资源卡了很久还没有加载成功,如何放弃这个卡的数据,继续往下走 有2钟方式。通常可以采用下面的方式一来处理这种情况 方式一、WebDriverWait 这种方式…...
并发工具类库使用的常见问题
一、ThreadLocal在多线程环境中没有清理 由于ThreadLocal是和线程绑定的,如果线程被复用了,也即使用了线程池,那么ThreadLocal中的值是可能被复用的,这个特性如果是开发者没有预料到的,那么会产生很大的问题。例如&am…...
GD32F10X ----RTC
1. RTC的简介 STM32 的实时时钟(RTC)是一个独立的定时器。STM32 的 RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。 RTC 模块和时钟配置…...
使用UiPath和AA构建的解决方案 1. 机器人过程自动化入门
你好!在这本系列,我们将指导您完成一些真实世界的机器人过程自动化(RPA)项目。感谢您的加入。当你完成本系列时,你将具备使用UiPath和Automation Anywhere在最低指导下进行简单到中等复杂度RPA项目的知识、技术和心态。 RPA是一项令人兴奋的新技术,被视为使用新的先进技…...
rust字面量
字面量就是值。值最终必须编码成二进制存储在某块内存上。 变量与字面量的关系就像杯子和水的关系。 字面量是有类型的。字面量类型有:布尔、数字、文本、字节 一、布尔 类型是bool true false 二、数字 通过后缀表示类型 通过前缀表示进制 通过 “_” 来分割数…...
Unix Network Programming Episode 79
‘gai_strerror’ Function The nonzero error return values from getaddrinfo have the names and meanings shown in Figure 11.7. The function gai_strerror takes one of these values as an argument and returns a pointer to the corresponding error string. #incl…...
Cesium展示——wkt 数据绘制
文章目录 需求分析1. 第一步,数据类型转换2. 第二步,数据渲染需求 WKT 是什么:WKT 简介 在这里,我选择将 Cesium 中将wkt数据转化为geoJSON格式后渲染至地球上 分析 1. 第一步,数据类型转换 npm install terraformer-wkt-parser --savelet wkts =...
打造完美家庭空间,让生活更加舒适
在现代繁忙的都市生活中,家是人们温暖而舒适的避风港。而如何打造一个恰到好处的家庭空间,成为了许多人心中的追求。今天,就让我们来探索一些空间布局方案,为您的家庭营造一个完美融合功能与美感的舒适空间。 🏠&…...
解决loadDep:omelette: sill install loadAllDepsIntoIdealTree
报错信息如下: 解决方案: 1、设置为淘宝的镜像源 npm config set registry https://registry.npm.taobao.org 2、 命令检验是否成功 npm config get registry 3、继续运行npm install即可 npm install 运行效果:...
【深蓝学院】手写VIO第2章--IMU传感器--作业
这次作业坑很多,作业说明的不清楚,摸索了很长时间才将此次作业完成,在这里进行记录。 1. T1 1.1 题干 1.2 解答 1.2.1 法1,ros related方法 不知道为什么我的launch不了,在imu_utils目录下面建立build后࿰…...
Android多线程学习:线程
一、概念 进程:系统资源分配的基本单位,进程之间相互独立,不能直接访问其他进程的地址空间。 线程:CPU调度的基本单位,线程之间共享所在进程的资源,包括共享内存,公有数据,全局变量…...
canvas 入门
canvas 入门 canvas是干什么的?canvas 绘制直线canvas画虚线canvas 绘制三角形canvas 绘制正方形canvas 绘制圆形、圆弧与椭圆canvas绘制文本canvas绘制图片 canvas是干什么的? <canvas> 是HTML5中的标签,它是一个容器,可以…...
建议收藏!混迹职场多年总结出的8大技巧!
1. 不要吃“哑巴”亏:不管在什么企业,一定要“会说话”,敢于表达自己,但是又兼顾身边人的感受,考虑好自己的言行将会带来的后果。良好的沟通技巧对于在职场中建立良好的人际关系和解决问题至关重要。学会倾听、表达和理…...
OpenCV4(C++)—— 视频和摄像头的加载、显示与保存
文章目录 一、加载与显示二、保存 一、加载与显示 视频或摄像头的加载是使用 cv::VideoCapture 类。(这个类和 ifstream 类比较相似,视频或摄像头的加载和文本文件操作是大致相同。主要步骤:(1)加载(打开&a…...
excel功能区(ribbonx)编程笔记6-box的使用
box元素用来在组里指定的控件周围放置一个可视的框,其主要目的是将控件作为一个单元组合在一起。 通常情况下,分配到组中的每个控件都被放置在先前的控件下面直到该列被填满,然后下一个控件被放置在其右侧列的顶行。然而,通过在框里面组合命令,可以将几个控件视作一个整体…...
oralce配置访问白名单的方法
目录 配置sqlnet.ora文件 重新加载使配置生效 注意事项 Oracle数据库安全性提升:IP白名单的配置方法 随着互联网的发展,数据库安全问题也越来越严重。Oracle是目前使用较为广泛的一款数据库管理系统,而IP白名单作为提升数据库安全性的有效…...
ToBeWritten之让响应团队参与并做好沟通
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...
自己怎么做彩票投注网站/搜索风云榜百度
单例模式的介绍可参考 https://blog.csdn.net/SummerMangoZz/article/details/57080540 https://blog.csdn.net/qq_37520037/article/details/82719190 体会懒汉式的双重检测的好处 public static synchronized Singleton getInstance() { if(uniqueInstancenull) {…...
浮雕模东莞网站建设/网络推广
《5自由度移动机器人的建模与仿真-硕士论文.pdf》由会员分享,可在线阅读全文,更多相关《5自由度移动机器人的建模与仿真-硕士论文》请在www.woc88.com上搜索。1、Rojas,A..Trajectorylanninginroboticscontinuousathal…...
做投注网站多少钱/seo推广怎么入门
又来写反思了。 这次考试又处在一个放假(之后)的尴尬位置,说实话有点困(虽然中午确实没夜聊),暴力了80,连大众分也没拿到,很伤。 一开始还是先溜一眼三道题,发现T1有点眼…...
家具行业网站建设/怎么免费搭建自己的网站
centos7安装完成后没有网络1、查看网卡信息:命令:lspci | grep -i ethernet网卡信息:Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 05)2、下载网卡驱动( Index of /elrepo/elrepo/el7/x…...
公司网站开发/怎么制作个人网站
1.避免在索引列上使用NOT和!,索引只能告诉我们什么存在与表中,不能告诉我们什么不存在表中 2.索引列上用>替代> 3.oracle采用自下而上的顺序解析where子句,因此表之间的连接必须放在其他where条件之前,那些可以过…...
如何建设学校门户网站/培训课程名称大全
文章目录元组关系演算概述种类第一种R(t)第二种 t[i] θ u[j]第三种 t[i] θ c 或 c θ t[i] 元组关系演算 概述 元组:表示关系表中的记录元组变量:关系表中的某一条记录。元组关系演算公式: 表示的关系表。 在元组关系演算系统中,称 {t|Φ…...