MyBatis框架-动态SQL

动态SQL

什么是动态SQL:动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.

动态 SQLMyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
if
choose (when, otherwise)
trim (where, set)
foreach

搭建测试环境

新建一个用户表
CREATE TABLE `user`  (`id` int(20) NOT NULL,`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`pwd` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`age` int(3) NULL DEFAULT NULL,`role` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8;
-- 插入数据;
INSERT INTO `test`.`user`(`id`, `name`, `pwd`, `age`, `role`) VALUES (1, '小明', '123456', 18, '管理员');
INSERT INTO `test`.`user`(`id`, `name`, `pwd`, `age`, `role`) VALUES (2, '张三', '321321', 16, '普通用户');
INSERT INTO `test`.`user`(`id`, `name`, `pwd`, `age`, `role`) VALUES (3, '李四', '321123', 16, 'VIP用户');
User.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {private int id;  //idprivate String name;   //姓名private String pwd;   //密码private int age;private String role;}
UserMapper.java
public interface UserMapper {}
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.sin.mapper.UserMapper"></mapper>
mybatis-config.xml
<mappers><mapper resource="mapper/UserMapper.xml"/>
</mappers>

if标签

需求:页面上,有三个筛选条件,如下图所示:那个值不为空就查询那个值。例如:用户名不为名,就查询用户名,年龄不为空就查询年龄,如果用户名和年龄都不为空,就用户名加年龄加权限。

在这里插入图片描述

UserMapper.java
    List<User> selectUser(Map map);
UserrMapper.xml
  <!--查询用户常规sql语句:select * from user where name = #{name} and age = #{age} and role = #{role}--><select id="selectUser" resultType="com.sin.pojo.User" parameterType="map">select * from user where<if test="name != null">name = #{name}</if><if test="age !=null">and age = #{age}</if><if test="role !=null">and role=#{role}</if></select>
测试
@Test
public void testSelectUser(){SqlSession session = MyBatisUtil.getSession();UserMapper mapper = session.getMapper(UserMapper.class);HashMap<String, String> map = new HashMap<String, String>();map.put("name","小明");map.put("age","18");map.put("role","管理员");List<User> users = mapper.selectUser(map);System.out.println(users);session.close();
}
测试结果

在这里插入图片描述

如果用户名不传,会不会出问题?

肯定会的。可以通过测试查看日志的输出。

发现SQL变成了,select * from user where and age = ? and role = ?

在这里插入图片描述

解决办法
方法一: 在where 后面添加 1 or 1。 (不推荐这样的写法)
<!--查询用户常规sql语句:select * from user where name = #{name} and age = #{age} and role = #{role}
-->
<select id="selectUser" resultType="com.sin.pojo.User" parameterType="map">select * from user where 1 = 1<if test="name != null">name = #{name}</if><if test="age !=null">and age = #{age}</if><if test="role !=null">and role=#{role}</if>
</select>
测试
@Test
public void testSelectUser(){SqlSession session = MyBatisUtil.getSession();UserMapper mapper = session.getMapper(UserMapper.class);HashMap<String, String> map = new HashMap<String, String>();//map.put("name","小明");map.put("age","18");map.put("role","管理员");List<User> users = mapper.selectUser(map);System.out.println(users);session.close();
}
测试结果

在这里插入图片描述

方法二:采用mybatis 里的 <where> 标签。 (推荐)
<!--查询用户常规sql语句:select * from user where name = #{name} and age = #{age} and role = #{role}
-->
<select id="selectUser" resultType="com.sin.pojo.User" parameterType="map">select * from user<where><if test="name != null">name = #{name}</if><if test="age !=null">and age = #{age}</if><if test="role !=null">and role=#{role}</if></where></select>
测试
@Test
public void testSelectUser(){SqlSession session = MyBatisUtil.getSession();UserMapper mapper = session.getMapper(UserMapper.class);HashMap<String, String> map = new HashMap<String, String>();//map.put("name","小明");map.put("age","18");map.put("role","管理员");List<User> users = mapper.selectUser(map);System.out.println(users);session.close();
}
测试结果

在这里插入图片描述

如果 <where> 标签里有返回值的话,它就插入一个where。如果标签里的内容是以AND 或OR 开头的,会忽略掉。

set标签

如果我用户名,年龄,权限,其中任意一个值有值,就更新该值。

UserMapper.java
int updateUser(Map map);
UserMapper.xml
    <!--更新用户常规语句 :UPDATE `user` SET `name` = #{name}, `age` = #{age}, `role` = #{role} WHERE `id` = #{id}--><update id="updateUser" parameterType="map">update user<set><if test="name != null">name = #{name},</if><if test="age !=null">age = #{age},</if><if test="role !=null">role = #{role}</if></set>where id = #{id};</update>
测试
@Test
public void testUpdateUser(){SqlSession session = MyBatisUtil.getSession();UserMapper mapper = session.getMapper(UserMapper.class);HashMap<String, String> map = new HashMap<String, String>();map.put("id","1");map.put("name","管理员");map.put("age","22");map.put("role","VIP管理员");// 返回执行成功条数mapper.updateUser(map);session.close();
}
测试结果

在这里插入图片描述

choose语句

有时候,我们会根据不同的用户权限给不同的查询条件,查询条件有一个满足即可,这时候我们使用 choose 标签可以解决这个问题了,类似于 Java 的 switch 语句

需求:如果用户名和权限同时有值,只能查询其中一个。

UserMapper.java
List<User> selectUserChoose(Map map);
UserMapper.xml
<select id="selectUserChoose" resultType="com.sin.pojo.User">select * from user<where><choose><when test="name != null">and name = #{name}</when><when test="age != null">and age = #{age}</when><when test="role !=#{role}">and role = #{role}</when></choose></where>
</select>
测试
@Test
public void testSelectUserChoose(){SqlSession session = MyBatisUtil.getSession();UserMapper mapper = session.getMapper(UserMapper.class);HashMap<String, String> map = new HashMap<String, String>();map.put("name","小明");map.put("age","18");map.put("role","普通用户");List<User> users = mapper.selectUserChoose(map);System.out.println(users);session.close();
}
测试结果

在这里插入图片描述

SQL片段

有时候可能某个 sql 语句我们会反复用到,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用。

提取SQL片段:
<sql id="userSql">select * from user
</sql>
<sql id="userSql">select * from user
</sql>
<select id="selectUser" resultType="com.sin.pojo.User" parameterType="map"><!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace --><include refid="userSql"></include><!-- 在这里还可以引用其他的 sql 片段 --><where><if test="name != null">name = #{name}</if><if test="age !=null">and age = #{age}</if><if test="role !=null">and role=#{role}</if></where></select>

Foreach语句

常用于:批量添加,批量删除,in 查询。

批量添加
UserMapper.java
// 批量添加
int batchAdd(List<Map> users);
UserMapper.xml
<insert id="batchAdd">insert into user(id,name,pwd,age,role)values<foreach collection="list" item="item" separator=",">(#{item.id},#{item.name},#{item.pwd},#{item.age},#{item.role})</foreach>
</insert>
测试
// 测试批量添加方法
@Test
public void testBatchAdd() {SqlSession session = MyBatisUtil.getSession();  //获取SqlSession连接UserMapper mapper = session.getMapper(UserMapper.class);List<Map> mapList = new ArrayList<Map>();for (int i = 0; i < 5; i++) {String[] names = new String[]{"刘备","张飞","关羽","诸葛亮","赵云"};Map<String,String> map = new HashMap<String, String>();map.put("id",1+""+i);map.put("name",names[i]);map.put("pwd", String.format("%06d", new Random().nextInt(999999)));map.put("age",2+""+i);map.put("role",i+"号管理员");mapList.add(map);}mapper.batchAdd(mapList);session.close();
}
测试结果

在这里插入图片描述

批量删除
UserMappe.java
// 接口添加方法
int batchDel(List<Integer> users);
UserMapper.xml
<delete id="batchDel">delete from user where  idin  <foreach collection="list" item="id" open="(" close=")" separator=",">#{id}</foreach>
</delete>
测试
// 测试批量删除方法
@Test
public void testBatchDel() {SqlSession session = MyBatisUtil.getSession();  //获取SqlSession连接UserMapper mapper = session.getMapper(UserMapper.class);List<Integer> mapList = new ArrayList<Integer>();mapList.add(1);mapList.add(2);mapList.add(3);mapper.batchDel(mapList);session.close();
}
测试结果

在这里插入图片描述

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

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

相关文章

Axios学习

文章目录 Axios1.Json-server的搭建2.Axios的基本使用3.Axios的其他使用4.Axios响应结果的结构分析5.Axios配置对象详细说明6.axios的默认配置7.axios创建实例对象&#xff08;create&#xff09;8.axios拦截器1.请求拦截器2.响应拦截器 9.取消请求10.源码分析 Axios 1.Json-s…

小迪安全25WEB 攻防-通用漏洞SQL 读写注入MYSQLMSSQLPostgreSQL

#知识点&#xff1a; 1、SQL 注入-MYSQL 数据库 2、SQL 注入-MSSQL(SQL server) 数据库 3、SQL 注入-PostgreSQL 数据库 #详细点&#xff1a; Access 无高权限注入点-只能猜解&#xff0c;还是暴力猜解 因为access的数据库是独立存在的&#xff0c;不存在统一管理 …

GitLab安装配置

一、GitLab的简介 GitLab是开源的代码托管平台&#xff0c;提供版本控制功能、代码审查、持续集成等工具&#xff0c;帮助团队协作开发软件项目。用户可以创建仓库存储代码&#xff0c;管理问题追踪&#xff0c;部署自动化流程等。 二、GitLab的安装 1、Rocky_Linux 下载安装 …

应用回归分析:多重共线性

多重共线性的概念 在回归分析中&#xff0c;我们通常关注的是如何利用一个或多个自变量&#xff08;解释变量&#xff09;来预测一个因变量&#xff08;响应变量&#xff09;。当我们使用多元线性回归模型时&#xff0c;理想的情况是模型中的每一个自变量都能提供独特的、对因…

【嵌入式学习】C++QT-Day6-C++基础

作业&#xff1a; 1.思维导图 见我的博客&#xff1a;https://lingjun.life/wiki/EmbeddedNote/19Cpp 2.编程题&#xff1a; 以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了…

2024 前端面试题(GPT回答 + 示例代码 + 解释)No.114 - No.121

本文题目来源于全网收集&#xff0c;答案来源于 ChatGPT 和 博主&#xff08;的小部分……&#xff09; 格式&#xff1a;题目 h3 回答 text 参考大佬博客补充 text 示例代码 code 解释 quote 补充 quote 上一篇链接&#xff1a;2024 前端面试题&#xff08;GPT回答 示例…

汽车网络安全--关于供应商网络安全能力维度的思考

目录 1.关于CSMS的理解 2.OEM如何评审供应商 2.1 质量评审 2.2 网络安全能力评审 3.小结 1.关于CSMS的理解 最近在和朋友们交流汽车网络安全趋势时&#xff0c;讨论最多的是供应商如何向OEM证明其网络安全能力。 这是很重要的一环&#xff0c;因为随着汽车网络安全相关强…

三防平板电脑丨亿道工业三防平板丨三防平板定制丨机场维修应用

随着全球航空交通的增长和机场运营的扩展&#xff0c;机场维护的重要性日益凸显。为确保机场设施的安全和顺畅运行&#xff0c;采取适当的措施来加强机场维护至关重要。其中&#xff0c;三防平板是一种有效的工具&#xff0c;它可以提供持久耐用的表面保护&#xff0c;使机场维…

微信小程序 搜索框实现模糊搜索(带模拟数据,js,wxml,wxss齐全)

最近在做一个小程序的页面&#xff0c;搜索框困扰了我很久&#xff0c;今天终于把搜索框给做了出来&#xff0c;记录一下过程 我主要使用的就是wx的if&#xff0c;当我输入框用户点击的时候&#xff0c;我前面的显示界面添加上false属性&#xff0c;然后我搜索页面显示出true的…

【Jvm】类加载机制(Class Loading Mechanism)原理及应用场景

文章目录 Jvm基本组成一.什么是JVM类的加载二.类的生命周期阶段1&#xff1a;加载阶段2&#xff1a;验证阶段3&#xff1a;准备阶段4&#xff1a;解析阶段5&#xff1a;初始化 三.类初始化时机四.类加载器1.引导类加载器&#xff08;Bootstrap Class Loader&#xff09;2.拓展类…

leetcode13题罗马数字转成整数

代码 public static int romanToInt(String s) {// 创建一个HashMap&#xff0c;将罗马数字字符映射为整数值HashMap<Character, Integer> map new HashMap<>();map.put(I, 1);map.put(V, 5);map.put(X, 10);map.put(L, 50);map.put(C, 100);map.put(D, 500);map.…

Eclipse 创建 Hello World 工程

Eclipse 创建 Hello World 工程 1. Hello WorldReferences Download and install the Eclipse IDE. 1. Hello World Eclipse -> double click -> Launch 单击蓝色方框 (右上角) 最大化 IDE File -> New -> C Project -> Finish Project name&#xff1a;工程名…

Matlab|基于支持向量机的电力短期负荷预测【最小二乘、标准粒子群、改进粒子群】

目录 主要内容 部分代码 结果一览 下载链接 主要内容 该程序主要是对电力短期负荷进行预测&#xff0c;采用三种方法&#xff0c;分别是最小二乘支持向量机&#xff08;LSSVM&#xff09;、标准粒子群算法支持向量机和改进粒子群算法支持向量机三种方法对负荷进行…

LeetCode每日一题【209. 长度最小的子数组】

题目&#xff1a; 思路1&#xff1a;暴力循环 class Solution { public:int minSubArrayLen(int target, vector<int>& nums) {int len INT_MAX;for(int i0;i<nums.size();i){int sum 0;for(int ji;j<nums.size();j){sumnums[j];if(sum>target){len mi…

推荐彩虹知识付费商城免授权7.0源码

彩虹知识付费商城免授权7.0源码&#xff0c;最低配置环境 PHP7.2 1、上传源码到网站根目录&#xff0c;导入数据库文件&#xff1a;xydai.sql 2、修改数据库配置文件&#xff1a;/config.php 3、后台&#xff1a;/admin 账号&#xff1a;admin 密码&#xff1a;123456 4、前…

八、计算机视觉-边界填充

文章目录 前言一、原理二、具体的实现 前言 在Python中使用OpenCV进行边界填充&#xff08;也称为zero padding&#xff09;是一种常见的图像处理操作&#xff0c;通常用于在图像周围添加额外的像素以便进行卷积或其他操作。下面是使用OpenCV进行边界填充的基本原理和方法 一…

BufferedImage 这个类在jdk17中使用哪个import导入

在Java开发中&#xff0c;BufferedImage 类是用于处理图像数据的一个类。在JDK 17中&#xff0c;BufferedImage 类属于 java.awt.image 包。因此&#xff0c;要在你的Java程序中使用 BufferedImage 类&#xff0c;你需要通过以下方式导入该类&#xff1a; import java.awt.ima…

OpenCV DNN 活体检测项目环境配置等各阶段tips

date: 2020-09-22 14:53 资料来源《OpenCV深度学习应用与性能优化实践》第八章。 在复现这个项目的时候发现一些可以调整的小tips。 环境配置阶段 使用conda 创建python 工作环境时&#xff0c;注释掉requirems.txt 里的opencv-python-inference-engine4.1.2.1&#xff0c;安…

Spring6学习技术|简要介绍+安装环境+入门案例+log4j2日志

学习材料 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09; 碎碎念一下吧&#xff0c;javaWeb跟完了全程。还是感觉啥也不知道&#xff0c;啥也没学会。2025年春天能找到实习吗&#xff1f;真的好担心。 环境安装 纠…

基于Java SSM框架实现电影售票系统项目【项目源码】计算机毕业设计

基于java的SSM框架实现电影售票系统演示 SSM框架 当今流行的“SSM组合框架”是Spring SpringMVC MyBatis的缩写&#xff0c;受到很多的追捧&#xff0c;“组合SSM框架”是强强联手、各司其职、协调互补的团队精神。web项目的框架&#xff0c;通常更简单的数据源。Spring属于…