动态sql语句

1.1 动态sql语句概述

Mybatis 的映射文件中,业务逻辑复杂时, SQL是动态变化的,此时在前面的学习中 SQL 就不能满足要求了。

参考的官方文档:
在这里插入图片描述

1.2 动态 SQL 之<if>

根据实体类的不同取值,使用不同的 SQL语句来进行查询
比如在 id 如果不为空时可以根据id查询,如果username 不为空时还要加入用户名作为条件。
这种情况在多条件组合查询中经常会碰到

  <select id="findColl" parameterType="user" resultType="user">select * from T_user<where> <!--表示where--><if test="id!=0">id=#{id}</if><if test="username!=null and username!=''">and username=#{username}</if></where>

编写dao接口:

//多条件查询
public List<User> findColl(User user);

当查询条件id和username都存在时,控制台打印的sql语句如下:

     @Testpublic void findCollT(){SqlSession sqlSession = MybatisUtils.getSqlSession(true);UserDao mapper = sqlSession.getMapper(UserDao.class);User user=new User();user.setId(1);user.setUsername("张三");List<User> coll = mapper.findColl(user);System.out.println(coll.toString());MybatisUtils.closeSqlSession(sqlSession);}

在这里插入图片描述

当查询条件只有id存在时,控制台打印的sql语句如下:

 //获得MyBatis框架生成的UserDao接口的实现类
@Testpublic void findCollT(){SqlSession sqlSession = MybatisUtils.getSqlSession(true);UserDao mapper = sqlSession.getMapper(UserDao.class);User user=new User();user.setId(1);List<User> coll = mapper.findColl(user);System.out.println(coll.toString());MybatisUtils.closeSqlSession(sqlSession);}

在这里插入图片描述

总结语法:

<where>:条件标签。如果有动态条件,则使用该标签代替 where 关键字。
<if>:条件判断标签。
<if test=“条件判断”>查询条件拼接
</if>

1.3 动态sql之set (update insert)

  <!-- 动态语句 set 更新语句 update 表名 set name=#{name} --><update id="updateMap" parameterType="map">update T_user <set><if test="username!=null">username=#{username},</if><if test="sex!=null">sex=#{sex}</if></set><where><if test="id!=null">id=#{id}</if></where></update><!-- 动态语句 set 插入语句 insert into 表名 set name=#{name},age=#{age} --><insert id="saveMap" parameterType="map">insert into T_user<set><if test="id!=null">id=#{id},</if><if test="username!=null">username=#{username},</if><if test="sex!=null">sex=#{sex},</if><if test="address!=null">address=#{address},</if><if test="birthday!=null">birthday=#{birthday}</if></set></insert>

编写dao接口添加方法:

public int updateMap(Map<String ,Object> map);public int saveMap(Map<String ,Object> map);

测试类编写:

修改的测试方法
@Testpublic void updatemap(){SqlSession sqlSession = MybatisUtils.getSqlSession(true);UserDao mapper = sqlSession.getMapper(UserDao.class);Map<String,Object> map=new HashMap<>();map.put("id",1);map.put("username","老六");map.put("sex","女");int i = mapper.updateMap(map);System.out.println(i);}
添加的测试方法@Testpublic void savemapT(){SqlSession sqlSession = MybatisUtils.getSqlSession(true);UserDao mapper = sqlSession.getMapper(UserDao.class);Map<String,Object> map=new HashMap<>();map.put("username","老六");map.put("sex","女");map.put("address","郑州");map.put("birthday",Date.valueOf("2010-03-09"));int i = mapper.saveMap(map);System.out.println(i);}

总结语法:

<set>:条件标签。set 元素可以用于动态包含需要更新的列
<if>:条件判断标签。
<if test="条件判断">查询条件拼接
</if>

1.4 动态sql之choose (when, otherwise)

相当于Java中的switch语句

当when有条件满足的时候,就跳出choose

 <choose><when test="条件1">...</when><when test="条件2">...</when><when test="条件3">...</when><otherwise>其他条件</otherwise>
</choose>

代码演示步骤:

1、编写Dao接口代码

2、编写mapper文件

3、测试运行

代码实现:

编写Dao接口代码

public List<User> showUserfindAll(@Param("username") String username,@Param("sex") String sex,@Param("address") String address,@Param("birthday") Date birthday;

编写mapper文件

<!-- 动态语句choose when when otherwise -->
<!-- if elseif elseif else<choose><when test=""></when><when test=""></when><when test=""></when><otherwise>...</otherwise></choose>-->
<select id="showUserfindAll" resultType="cn.zxy.pojo.User">select * from user where <choose><when test="username!=null and username!=''">username like concat("%",#{username},"%")</when><when test="sex!=null and sex!=''">sex =#{sex}</when><when test="address!=null and address!=''">address like concat("%",#{address},"%")</when><otherwise>year(birthday)=year(#{birthday})</otherwise></choose>

另一种写法

<select id="showUserfindAll" resultType="cn.zxy.pojo.User">select * from user <where><choose><when test="username!=null"><choose><when test="username.indexOf('%')!=-1"> username like #{username}</when><when test="username.indexOf('_')!=-1">username like #{username}</when><otherwise>username = #{username}</otherwise></choose></when><when test="sex!=null and sex!=''">sex =#{sex}</when><when test="address!=null and address!=''">address like concat("%",#{address},"%")</when><otherwise>birthday=#{birthday}</otherwise></choose></where></select>

实体和数据库名字不匹配

<!-- 查询中如果表字段名和实体类名不一致,不想定义ResultMap,可以使用查询的列名 -->
<sql id="s1p">id,user_name username,birthday birth,address addr,sex sex</sql><select id="showUserfindAll" resultType="cn.zxy.pojo.User">select <include refid="s1p"/> from user where 1=1<choose><when test="username!=null"><choose><when test="username.indexOf('%')!=-1">user_name like #{username}</when><when test="username.indexOf('_')!=-1">user_name like #{username}</when><otherwise>user_name = #{username}</otherwise></choose></when><when test="sex!=null and sex!=''">and sex =#{sex}</when><when test="address!=null and address!=''">and address like concat("%",#{addr},"%")</when><otherwise>and year(birthday)=year(#{birth})</otherwise></choose>
</select>

测试运行

 @Testpublic void test() throws IOException {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);SqlSession session = factory.openSession();UserDao userDao = session.getMapper(UserDao.class);List<User> users = userDao.showUserfindAll("小_", "男", "河", null);System.out.println(users.toString());}

1.5 动态 SQL 之<foreach>

循环执行sql的拼接操作,例如:SELECT * FROM user WHERE id IN (1,2,5)。

foreach 迭代一个集合,通常用于in条件

属性:

  • item 查询条件

  • collection:必须指定

    • list

    • array

    • map—key

  • open : 括号 (

  • separator :分割符 ,

  • close :括号 )

例子如下

  <!--循环迭代-->
<select id="findByIds" parameterType="list" resultType="user"><!--collection: 表示集合存储类型 分别为 list array数组open : id in (  是指代  where id in(close: 闭合括号item : 查询条件separator: 分割符-->select * from T_user<where><foreach collection="list" open="id in (" close=")" item="id" separator=",">#{id}</foreach></where>
</select>

编写dao接口:

//根据多个id查询
public List<User> findByIds(List<Integer> ids);

测试代码片段如下:

 @Testpublic void findByidst() {//获取sqlssession给定的对象SqlSession sqlSession = MybatisUtils.getSqlSession(true);UserDao mapper = sqlSession.getMapper(UserDao.class);//创建list集合 并赋值List<Integer> list=new ArrayList<>();list.add(1);list.add(3);list.add(5);//把集合里面的值赋给mapperList<User> byIds = mapper.findByIds(list);for (User byId : byIds) {System.out.println(byId);}MybatisUtils.closeSqlSession(sqlSession);}

批量插入:

Mapper接口编写

public  void insert(List<User> list);

映射文件编写:

 <insert id="insert" parameterType="user">insert into user values<foreach collection="list" separator="," item="user">(#{user.id},#{user.username},#{user.sex},#{user.address},#{user.birthday})</foreach></insert>

测试类编写:

 @Testpublic void inTest(){SqlSession sqlSession = MyBatisUtils.getSqlSession(true);DUserMapper mapper = sqlSession.getMapper(DUserMapper.class);long start=System.currentTimeMillis();log.info("开始的时间{}",start);List<User> userList=new ArrayList<>();User user;for (int i = 0; i < 5; i++) {user=new User();user.setUsername("唐"+i);user.setSex("男");user.setAddress("河南北京");user.setBirthday(new Date());userList.add(user);}mapper.insert(userList);long end = System.currentTimeMillis();log.info("结束的时间{}",(end-start));}

总结语法:

<foreach>:循环遍历标签。适用于多个参数或者的关系。<foreach collection="" open="" close="" item="" separator="">获取参数</foreach>

属性
collection:参数容器类型, (list-集合, array-数组)
open:开始的 SQL 语句 id in (
close:结束的 SQL 语句
item:参数变量名
separator:分隔符

1.6 SQL片段抽取

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的

<!--抽取sql片段简化编写-->
<sql id="selectUser" select * from student</sql>
<!--根据id查询-->
<select id="findById" parameterType="int" resultType="user"><include refid="selectUser"></include> where id=#{id}
</select>
<!--根据ids遍历-->
<select id="findByIds" parameterType="list" resultType="student"><include refid="selectUser"></include><where><foreach collection="array" open="id in(" close=")" item="id" separator=",">#{id}</foreach></where>
</select>

总结语法:

我们可以将一些重复性的 SQL 语句进行抽取,以达到复用的效果。

-  <sql>:抽取 SQL 语句标签。 
-  <include>:引入 SQL 片段标签。 <sql id=“片段唯一标识”>抽取的 SQL 语句</sql> 
<include refid=“片段唯一标识”/>

1.7 知识小结

MyBatis映射文件配置:

<select>:查询
​
<insert>:插入
​
<update>:修改
​
<delete>:删除
​
<where>:where条件
​
<if>:if判断
​
<foreach>:循环
​
<sql>:sql片段抽取
​

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

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

相关文章

leetcode_001两数之和

1. 题目 两数之和 2. 题意 找到数组中和为给定值的两个值的坐标。 3. 题解 3.1 暴力 两重循环&#xff0c;直接列举出来。 class Solution1 { public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> res;int size nums.size()…

浅谈自动化测试工具 Appium

目录 前言&#xff1a; 一、简单介绍 &#xff08;一&#xff09;测试对象 &#xff08;二&#xff09;支持平台及语言 &#xff08;三&#xff09;工作原理 &#xff08;四&#xff09;安装工具 二、环境搭建 &#xff08;一&#xff09;安装 Android SDK &#xff0…

和chatgpt学架构02-环境搭建

目录 1 安装vs code2 vs code功能介绍3 安装nodejs4 安装vue5 在vs code打开工程总结 我们在上一篇 技术选型 里咨询了chatgpt前后端的框架选择和数据库的选择。有了框架之后就需要选择合适的开发工具了&#xff0c;继续咨询一下chatgpt 我现在选型&#xff0c;前端使用vue&am…

将媒体公司资产迁移到 Amazon S3 的技术方案

随着媒体公司的发展&#xff0c;他们在仓库中积累了大量的旧磁带和未数字化的视频。这些资产可能很有价值&#xff0c;但以目前的形式很难访问和货币化。此外&#xff0c;将这些资产存储在仓库中既有风险又昂贵。 媒体企业可以通过将其资产迁移到云存储来解决这些问题&#xf…

Lua 批量修改文件夹下文件名

local s io.popen("dir C:\\Users\\lizhiyuan\\Desktop\\国家知识产权局ftp法律状态数据\\data /b/s") local filelist s:read("*a")local start_pos 0while 1 do_,end_pos,line string.find(filelist, "([^\n\r].xml)", start_pos)if not e…

Java List中通过对象属性排序,可实现多条件排序

直接上代码&#xff1a; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.Data;import java.util.Comparator; import java.util.List; import java.util.stream.Collectors;/*** List 对象属性排序*/Data AllArgsConstructor clas…

xml.etree.ElementTree

python使用 xml.etree.ElementTree包的时候&#xff0c;对xml中的空标签进行了简写&#xff0c;想恢复成正常模式怎么弄

(学习笔记-TCP连接断开)TCP四次挥手

TCP四次挥手过程 TCP断开连接是通过四次挥手实现的&#xff0c;双方都可以主动断开连接&#xff0c;断开连接后主机中的资源将被释放&#xff0c;四次挥手的过程如下&#xff1a; 客户端打算关闭连接时&#xff0c;会发送一个TCP首部FIN标志位为1的报文&#xff0c;也就是FIN报…

基础语言模型LLaMA

LLaMA包含从7B到65B参数的基础语言模型集合。Meta在数万亿个tokens上训练了模型&#xff0c;LLaMA-13B在大多数基准测试中优于GPT-3&#xff08;175B&#xff09;。 来自&#xff1a;LLaMA: Open and Efficient Foundation Language Models 目录 背景概述方法预训练数据架构Op…

LangChain + Embedding + Chromdb,关联使用ChatGLM的本地搭建训练平台教程

一.介绍 OpenAI 在国内用户注册会遇到各种阻力&#xff0c;目前可行的方法是使用本地数据集的功能实现联网搜索并给出回答&#xff0c;提炼出TXT、WORD 文档里的内容。 现在主流的技术是基于强大的第三方开源库&#xff1a;LangChain 。 文档地址&#xff1a;&#x1f99c;…

基于单片机的教室智能照明台灯控制系统的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;LCD1602液晶显示当前时间、年月日、时分秒、前教室人数&#xff1b;2路红外探头用来感应当前教室进出人数&#xff1b;按键可以设置当前时间、自动手动模式、开启和关闭教室灯光时间&#xff1b;在手动模式下&#xff0c;可以通过按…

Ip-Limit: 轻量级注解式IP限流组件(一)

author: van , ggfanwentaogmail.comIp-Limit: 轻量级注解式IP限流组件 项目简介 基于JVM缓存的轻量级、注解式IP限流组件&#xff0c;方便项目快速引用&#xff0c;满足多线程场景。 默认为滑动窗口限流器&#xff0c;内置令牌桶限流器&#xff0c;可通过注解的属性配置修改…

uni-app:单位像素rpx

rpx:响应式单位&#xff0c;长宽可以随着屏幕大小改变&#xff0c;其尺寸根据iPhone 6的标准来参考&#xff08;750rpx为占满屏幕宽&#xff0c;1334rpx为占满屏幕长。7501334rpx&#xff09; 例子&#xff1a; 现在展示型号为iPhone 12 pro的型号&#xff0c;这里750px和750…

关于 let/var/const 的常见面试题

1、题目一 function func(){if(true){var s 123}console.log(s) } func() 打印的答案&#xff1a; 123 》 var是属于函数作用域 2、题目二 function func(){if(true){let s 123}console.log(s) } func() 打印的答案&#xff1a; s is not defined 》 let是属于块级作…

51单片机学习--矩阵键盘、电子密码锁

矩阵键盘的模块原理图&#xff1a; 功能&#xff1a;按下矩阵按键&#xff0c;在LCD上显示对应的数值。 采用模块化编程&#xff0c;在此只给出MatrixKey.c 和 main.c 两部分代码 #include <REGX52.H> #include "Delay.h"/*矩阵键盘读取键码按下不放&#xf…

【有功功率、无功功率】可再生能源配电馈线的鲁棒经济调度研究[IEEE13节点](Matlab代码实现)

&#x1f4a5;1 概述 "有功功率和无功功率" 是与电力系统中能量传输和功率控制相关的两个重要概念。 有功功率&#xff08;Active Power&#xff09;是指电力系统中传输和消耗能量的功率&#xff0c;也被称为实功功率。它负责提供电力系统中的实际电能需求&#xf…

DTU凭什么可以为数据提供高效可靠的稳定传输?

当谈及到智能化的发展时&#xff0c;其实它已经正在影响着各行各业&#xff0c;当前许多传统行业也正在向智能化转变。如果你细心留意的话&#xff0c;就会发现在我们日常生活中多少都会见到它们的身影&#xff0c;例如&#xff1a;村庄各家各户墙外所挂的煤改电设备、居民楼小…

【数学建模】统计分析方法

文章目录 1.回归分析2. 逻辑回归3. 聚类分析4. 判别分析5. 主成分分析6. 因子分析7. 对应分析 1.回归分析 数据量要多&#xff0c;样本总量n越大越好——>保证拟合效果更好&#xff0c;预测效果越好 一般n>40/45较好 方法 建立回归模型 yiβ0β1i……βkxkiεi 所估计的…

vite动态加载图片

参考CSDN 方法一 根据官网的提示, 就是在将asset 前面加上src <img v-if"post.welcomeScreen" :src"/src/assets/blogPhotos/${name}.jpg" alt"" />方法二 关于第二个方法&#xff0c;官网说&#xff1a;“实际上&#xff0c;Vite 并不…

Ubuntu系统cron服务运行 .sh 脚本

1、安装cron # 安装 apt-get install cron 2、常用命令 # 查看状态 sudo systemctl status cron # 开启服务 sudo systemctl start cron # 停止服务 sudo systemctl stop cron # 重启服务 sudo systemctl restart cron 3、编写要定时执行 hello.sh 脚本 #!/bin/bash echo &…