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

Mybatis-特殊SQL的执行

1. 模糊查询

在MyBatis中进行模糊查询时,有以下三种常见的实现方式:


1.1. 错误示范

先来个准备操作,并做一个错误示例

根据姓名,模糊查询用户,(x小x)

更新数据表

SQLMapper.java

package com.sakurapaid.mybatis3.select.mapper;import com.sakurapaid.mybatis3.select.bean.User;
import org.apache.ibatis.annotations.Param;import java.util.List;public interface SQLMapper {// 根据姓名,模糊查询用户,(x小x)List<User> findUserByName(@Param("name") String name);
}

SQLMapper.xml、

这是错误示例,我是——like '%#{name}%'

<?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.sakurapaid.mybatis3.select.mapper.SQLMapper"><!--根据姓名,模糊查询用户,(x小x)--><select id="findUserByName" resultType="com.sakurapaid.mybatis3.select.bean.User">select * from user where name like '%#{name}%'</select>
</mapper>

测试输出

package com.sakurapaid.mybatis3.select.test;import com.sakurapaid.mybatis3.select.bean.User;
import com.sakurapaid.mybatis3.select.mapper.SQLMapper;
import com.sakurapaid.mybatis3.select.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;import java.util.List;public class SQLTest {@Testpublic void test(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);List<User> out = mapper.findUserByName("小");for (User user : out) {System.out.println(user);}}
}

记住我上面的SQL语句,编译时就会报错

在 SQL 查询语句中使用了 MyBatis 的动态参数 #{name},但在对应的 mapper 映射配置中未正确设置该参数,导致在执行 SQL 查询时,JDBC 无法识别并适配这个参数,从而抛出了“Parameter index out of range”的异常。


所以,#{ }虽然常用,但并不是万能的,遇到模糊查询还是要适当调整的,也就引出了下面要讲到的三种在mybatis中模糊查询的方法


1.2. 方式一:使用#{}占位符

#{ }占位符结合contact函数

<select id="findUserByName" resultType="com.sakurapaid.mybatis3.select.bean.User">select * from user where name like concat('%',#{name},'%')</select>

解释
这里使用了#{}占位符来传递参数name。MyBatis会将#{name}替换为预编译语句中的参数,并自动为其加上单引号。通过concat函数将通配符%与参数值拼接成完整的模糊查询条件。这种方式能够防止SQL注入,因为参数值是经过预编译处理的,且无需手动添加单引号。

测试输出:

测试语句还是最上面那个


1.3. 方式二:使用${}变量替换

直接使用${ },但记得要加引号

<select id="testMohu" resultType="User">select * from user where name like '%${name}%'
</select>

解释
这种方式使用${}变量替换符来嵌入参数name的值。${name}会被直接替换为变量的值,不会添加任何额外的引号。因此,如果传入的name值为,生成的SQL语句将是select * from t_user where username like '%小%'。这种方式虽然简洁,但存在SQL注入的风险,因为变量值未经预编译直接插入到SQL语句中。除非能确保传入值的安全性,否则不建议使用此方式。

测试输出:

测试语句还是最上面那个


1.4. 方式三:手动添加双引号

最推荐的,也是实际开发中最常用的

<select id="testMohu" resultType="User">select * from user where name like "%"#{name}"%"
</select>

解释
这种方式结合了#{}占位符的预编译安全性与手动添加双引号来包裹通配符和参数。虽然看起来与方式一类似,但这里的#{name}被双引号包围,使得MyBatis在替换参数时,生成的SQL语句中参数值仍被双引号包围,形如select * from user where name like "%'小'%"


2. 批量删除

要使用${ },而非#{ },来避免自动添加单引号


定义接口方法

// 批量删除用户
int deleteMore(@Param("ids") String ids);

编写Mapper XML映射文件

看清楚我这个错误示范

<delete id="deleteMore">delete from user where id in (#{ids})
</delete>

测试输出

@Test
public void test(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);int i = mapper.deleteMore("4,5,6");System.out.println(i);
}

不能使用#{ },只能使用${ }

<delete id="deleteMore">delete from user where id in (${ids})
</delete>

受影响行数1,因为我表里的id值只有1-4,就删除了4,


3. 动态设置表名

也要使用${ },而非#{ },来避免自动添加单引号


定义接口方法

/*** 动态设置表名,查询所有的用户信息* @param tableName* @return*/
List<User> getAllUser(@Param("tableName") String tableName);

编写Mapper XML映射文件

看清楚我这个错误示范

<select id="getAllUser" resultType="com.sakurapaid.mybatis3.select.bean.User">select * from #{tableName}
</select>

测试输出

@Test
public void test(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);List<User> allUser = mapper.getAllUser("user");allUser.forEach(System.out::println);
}

不能使用#{ },只能使用${ }

<select id="getAllUser" resultType="com.sakurapaid.mybatis3.select.bean.User">select * from ${tableName}
</select>


4. 添加功能获取自增的主键

在数据库应用开发中,使用自增主键是一种常见且实用的设计策略。自增主键字段的值会自动递增,每当插入一条新记录时,数据库系统会为其自动分配一个唯一的、递增的整数值作为主键。

场景一:简化数据插入操作

场景描述: 当需要在数据库中创建新的实体记录(如用户、订单、文章等)时,开发者通常需要为这些记录指定一个唯一的标识符。使用自增主键可以免去手动为每条新记录生成唯一ID的复杂性。

使用自增主键: 开发者只需关注其他非主键字段的数据填充,插入操作时无需指定主键值。数据库系统会自动为新插入的记录生成下一个自增主键值。例如,在创建新用户时,只需提供用户名、密码、邮箱等信息,主键ID由数据库自动生成。

场景二:确保数据唯一性

场景描述: 在多用户并发环境下,如果没有有效的机制保证主键的唯一性,可能会出现主键冲突,导致数据插入失败。自增主键能有效防止此类问题。

使用自增主键: 数据库系统内部对自增主键的管理确保了每次插入新记录时主键值的唯一性。即使在高并发场景下,不同用户同时尝试插入记录,也不会产生相同的主键值,从而避免数据冲突。


定义接口方法

// 添加用户
int insertUser(User user);

编写Mapper XML映射文件

useGeneratedKeys="true":指示MyBatis在执行INSERT操作后使用JDBC的getGeneratedKeys()方法获取数据库自动生成的主键值。

keyProperty="id":指定获取到的自增主键值应被赋给传入映射语句的参数对象(如User)的特定属性(如id),实现主键值的自动回填。

两者结合使用,确保在插入新记录后,自动生成的主键能被无缝地赋给对应的Java对象属性,简化了主键管理与后续业务逻辑的处理。

<!--useGeneratedKeys:设置使用自增的主键-->
<!--keyProperty:因为增删改有统一的返回值是受影响的行数,
因此只能将获取的自增的主键放在传输的参数user对象的某个属性中-->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">insert into user values (null,#{name},#{age},#{sex});
</insert>

测试输出

@Test
public void test(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);User user = new User(null, "李四", 23, "男");int i = mapper.insertUser(user);if (i > 0) {System.out.println("插入成功");System.out.println(user);} else {System.out.println("插入失败");}
}

相关文章:

Mybatis-特殊SQL的执行

1. 模糊查询 在MyBatis中进行模糊查询时&#xff0c;有以下三种常见的实现方式&#xff1a; 1.1. 错误示范 先来个准备操作&#xff0c;并做一个错误示例 根据姓名&#xff0c;模糊查询用户&#xff0c;(x小x) 更新数据表 SQLMapper.java package com.sakurapaid.mybatis3…...

金融衍生品市场

金融衍生品市场 衍生金融品的作用衍生金融工具远期合约期货合约期权 衍生金融品的作用 套期保值&#xff08;Hedging&#xff09; 组合多头头寸(long position)与空头头寸(short position)例&#xff1a;股票与股指期货 投机 衍生金融工具 远期合约 定义&#xff1a;在将来…...

2、Cocos Creator 下载安装

Cocos Creator 从 v2.3.2 开始接入了全新的 Dashboard 系统&#xff0c;能够同时对多版本引擎和项目进行统一升级和管理&#xff01;Cocos Dashboard 将做为 Creator 各引擎统一的下载器和启动入口&#xff0c;方便升级和管理多个版本的 Creator。还集成了统一的项目管理及创建…...

Docker版本:18.06.1安装

1、操作系统&#xff1a;CentOS 7.5以上 2、Docker版本&#xff1a;18.06.1 1、解压 tar -xvf docker-18.06.1-ce.tgz2、将解压出来的docker文件内容移动到 /usr/bin/ 目录下 cp docker/* /usr/bin/3、将docker注册为service vim /etc/systemd/system/docker.service将下列…...

记 SpringBoot 使用@RequestBody 接收不到参数

POST请求&#xff0c;前端传的参数名字跟后端规定的参数一样。但是通过RequestBody注解接收的参数始终为NULL&#xff01; //实体类中属性没有用驼峰命名 private String SubscribeID; /*** 标题*/ private String Title;解决方案&#xff1a; 1、字段上使用JsonProperty(valu…...

unity 打包安卓错误汇集

Failed to find target with hash string "android-34’ in: D:Pr 他说找不到sdk34level的我用as打开后卸载又重装&#xff0c;最后解决了 我放到Plugins/Android/下面的Java代码没有被编译 这个不知道为什么。我故意把代码写的有问题&#xff0c;会报错那种&#xff…...

C语言-文件操作

&#x1f308;很高兴可以来阅读我的博客&#xff01;&#x1f31f;我热衷于分享&#x1f58a;学习经验&#xff0c;&#x1f3eb;多彩生活&#xff0c;精彩足球赛事⚽&#x1f517;我的CSDN&#xff1a; Kevin ’ s blog&#x1f4c2;专栏收录&#xff1a;C预言 1. 文件的作用 …...

ADB 操作命令详解及用法大全

ADB 简介 ADB&#xff0c;全称 Android Debug Bridge&#xff0c;是 Google 提供的一款用于 Android 平台设备&#xff08;包括真机和模拟器&#xff09;调试、交互和管理的命令行工具。通过 ADB&#xff0c;开发者可以在电脑上对连接的 Android 设备执行一系列高级操作&#…...

指针数组。

指针数组 int c[5]{1,2,3,4,5};int *pc;printf("p:%d",p);return 0;输出&#xff1a;p:-756683712 说明p是地址值&#xff0c;*p就是取这个地址上的元素的值。所以printf(“*p:%d”,*p); 打印出来的是 *p:1 *pc,c是c[5]数组的首地址元素。 #include <iostream>…...

GitHub开源项目权限管理-使用账号和个人令牌访问

1.打开后台账号设置 2.找到左下角的Developer settings 3.找到Personal access tokens 的 Tokens(classic) 4.选择创建新证书 5.填写证书信息 6.点击生成证书&#xff0c;复制证书并且保存起来&#xff08;血泪教训&#xff0c;证书只会在创建时显示一次&#xff0c;以后就再也…...

DevSecOps平台架构系列-亚马逊云AWS DevSecOps平台架构

目录 一、概述 二、AWS DevSecOps实施原则 2.1 尽早采用安全测试&#xff0c;加速问题反馈 2.2 优先考虑预防性安全控制 2.3 部署检测性安全控制时&#xff0c;确保有与之互补的响应性安全控制 2.4 安全自动化 2.5 总结 三、AWS DevSecOps关键组件 3.1 关键组件 3.2 关…...

KaTex 常用公式编辑

原文&#xff1a;https://blog.iyatt.com/?p7854 注&#xff1a;语法上和 Latex 差不多一样&#xff0c;我是因为 WordPress 上使用 WP Githuber MD 插件&#xff0c;才用的 KaTex&#xff08;插件里面的 LaTex 模块有 bug&#xff0c;无法渲染&#xff09; 希腊字母 大写代…...

域攻防渗透之委派攻击

出身寒微&#xff0c;不是耻辱&#xff0c;能屈能伸&#xff0c;方为丈夫。 约束性委派的利用 原理 非约束性委派被委派的机器会直接得到发布委派的用户的TGT&#xff0c;是十分不安全的&#xff0c;因此微软推出了约束性委派&#xff0c;还扩充kerberos协议&#xff0c;添加…...

优雅的使用ChromeDriver

在网页自动化测试中,我们经常需要控制浏览器执行各种操作。对于Python开发者来说,可以使用 Selenium 库来实现这一目的。Selenium需要与浏览器的驱动程序(Driver)配合使用,本文将介绍如何在Windows 11系统下载ChromeDriver并正确保存。 第一步:确定Chrome浏览器版本号 打开Ch…...

react native hooks 页面出现重绘问题,如何解决

在React Native应用中&#xff0c;使用Hooks导致页面出现频繁重绘或性能问题时&#xff0c;可以尝试以下策略来优化和解决问题&#xff1a; 减少不必要的状态更新&#xff1a; 使用 React.memo 高阶组件包裹那些不需要每次父组件状态改变时都重新渲染的子组件。它通过浅比较pro…...

kafka安装并测试

一. Linux下ZooKeeper的安装及使用 1、创建工作目录&#xff0c;下载安装包 #创建安装目录 mkdir -p /opt/zookeeper #移动到目录 cd /opt/zookeepe #下载zookeeper安装包 wget https://mirrors.aliyun.com/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz #解…...

flutter路由跳转

Navigator.of(context).push(); //路由跳转(模块方式) Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {return const Page() ;//Page()指页面}, )) Navigator.pushNamed(context, "/") //路由跳转(路由方式) Navigator.pop(cont…...

微服务项目小结1

01.微服务的概念 单体、分布式、集群 (面试用到)微服务把之前的大的应用&#xff0c;按照业务功能拆分成若干个小的模块&#xff0c;每个模块都是独立的开发&#xff0c;测试&#xff0c;上线&#xff0c;维护缺点: 开发成本高&#xff0c;众多服务出错的处理(容错),分布式事务…...

【小熊猫 ide】更新支持mingw 支持c++20

没有format 头文件 GCC版本对C++的支持情况即使我使用11,也没有format 头文件小熊猫 ide https://wwe.lanzoui.com/b01os0mwd最新11可以自己更新https://royqh1979.gitee.io/redpandacpp/docsy/docs/gcc13 才支持format [7GCC 13 has added support for std::format.](https:/…...

ESD保护二极管ESD9B3.3ST5G 以更小的空间实现强大的保护 车规级TVS二极管更给力

什么是汽车级TVS二极管&#xff1f; TVS二极管是一种用于保护电子电路的电子元件。它主要用于电路中的过电压保护&#xff0c;防止电压过高而损坏其他部件。TVS二极管通常被称为“汽车级”是因为它们能够满足汽车电子系统的特殊要求。 在汽车电子系统中&#xff0c;由于车辆启…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…...