学会Mybatis框架:让你的代码更具灵活性、可维护性、安全性和高效性【二.动态SQL】

news2025/1/14 17:58:52

🥳🥳Welcome Huihui's Code World ! !🥳🥳

接下来看看由辉辉所写的关于Mybatis的相关操作吧

        

目录

🥳🥳Welcome Huihui's Code World ! !🥳🥳

一.Mybatis动态SQL如何应用

1.需求

2.问题分析

3.为什么使用动态SQL

二.Mybatis中的常用标签

1.if标签

2.foreach标签

三. 使用Mybatis中的动态SQL完成模糊查询

1.使用#{字段名}

2.使用${字段名}

3.使用concat{'%',#{字段名},'%'}

四、MyBatis结果映射 

1.resultType进行结果映射

2.resultMap进行结果映射


在学习一个东西之前,我们应该要知道它能够给我带来哪些好处,这样的话,我们学习它才会更有目标性,更有方向感。那我们采用对比的方式,来看看Mybatis到底解决了我们什么问题

        当我们还是初级开发工程师的时候,可能写过这样的代码:

//我们需要修改商品的信息,那我们就需要拿到它的id,然后再去修改它的相关信息
String sql="update goods set bname =?, price=? where bid =?"
//如果我此时没有传递bname,因为在我的业务功能中我不需要修改bname,
//那么我在传参的时候我就不会给它传递值,我预想的结果应该是它会照样是之前的那个值,
//可是它却变成了null!!!
String sql="update goods set bname =null, price=1232 where bid =2"
//这是因为我们没有传值,所以会默认给一个null值

        还有当我们写了电商项目中的购物车,那我们应该就会遇到这样的情况:当我们需要全选进行结算时。那么我们需要拿到用户所选商品的id,如果用户选择了多个,那么我们就要将这几个用户选中的id接收(数组),然后遍历,再将其分割,再执行sql语句...

        类似上述这样的情况,还有很多,它们都指向了一个问题:就是我们的sql语句没法很好的被改动,一动则要修改很多地方,所以很多初级开发员通常不会选择动sql,而是选择去适应sql语句,多写一些代码,但这样往往是行不通的...

        所以,我们今天要了解的是一个秘密神器--Mybatis中的动态sql!!!

一.Mybatis动态SQL如何应用

1.需求

假设我们要查询用户信息,但是用户的年龄可能在不同的范围内,我们需要根据年龄的不同来查询不同的信息。

2.问题分析

这个问题需要我们在运行时根据年龄的不同来生成不同的SQL语句,这就需要使用到动态SQL

3.为什么使用动态SQL

因为动态SQL可以根据不同的条件生成不同的SQL语句,这样就可以满足我们的需求

应用过程和解答步骤:首先,我们需要在Mapper接口中定义一个方法,该方法接收一个年龄参数;然后,在对应的XML文件中编写动态SQL;最后,在Service层调用这个方法。

【如果年龄小于18岁,那么就查询用户的名字和年龄;如果年龄大于等于18岁且小于60岁,那么就查询用户的姓名、年龄和性别;如果年龄大于等于60岁,那么就查询用户的姓名、年龄和电话】

上面的文字分析,你或许还是会觉得很懵,那么接下来我就用代码来演示意识使用动态SQL的好处, 那么我将会讲到mybatis动态SQL中比较常用的两种的标签

二.Mybatis中的常用标签

1.if标签

假设我们需要查询某个书城的所有神话小说,包括书名中含有为"圣墟"的和书本ID为56的。 首先需要根据书名中含有为"圣墟"的查询到对应的信息,然后根据书本ID和书名查询到对应的书本信息

这里需要使用if标签来实现动态拼接SQL

 d. 应用过程和解答步骤:首先使用if标签判断书本ID是否存在,如果存在则拼接查询书本信息的SQL语句,书名也是一样,如果都存在,则将这两个SQL语句拼接起来,得到最终的查询结果

<select id="selectBook" parameterType="Book" resultType="Book">
  SELECT * FROM Book WHERE 1=1
  <if test="bname!= null">
     AND bname like #{bname}
  </if>
  <if test="bid!= null ">
     AND bid like #{bid}
  </if>
</select>

2.foreach标签

 <select id="selectByBid" resultType="com.wh.model.Book" parameterType="java.util.List" >
    select
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bid in
    <foreach collection="bids" item="bid" open="(" close=")" separator=",">
      #{bid}
    </foreach>
  </select>

然后需要在BookMapper中写方法

 List<Book> selectByBid(@Param("bids") List bids);

BookBiz

  List<Book> selectByBid(List bids);

BookBizImpl

  @Override
    public List<Book> selectByBid(List bids) {
        return bookMapper.selectByBid(bids);
    }

测试

  @Test
    public void selectByBid() {
        List<Integer> bids = Arrays.asList(new Integer[]{56,57,58});
        bookBiz.selectByBid(bids).forEach(System.out::println);
    }

结果

三. 使用Mybatis中的动态SQL完成模糊查询

1.使用#{字段名}

 <select id="selectBooksLike1" resultType="com.wh.model.Book" parameterType="java.lang.String">
  select * from t_mvc_book where bname like #{bname}
</select>

写完这个xml文件的代码之后,也需要像上面的foreach标签那样在BookBiz,BookBizImpl...中写相应的代码,因为代码逻辑都相似,在这里我就不做过多的赘述了...

结果

2.使用${字段名}

  <select id="selectBooksLike2" resultType="com.wh.model.Book" parameterType="java.lang.String">
  select * from t_mvc_book where bname like ${bname}
</select>

 我们使用${字段名}的时候,需要格外注意,因为容易出现问题

 那么这是为什么呢?我们可以看下面这张图

我们也可以对比看看使用#{字段名}时,参数是什么样的

那我们应该怎么解决呢?其实很简单,看下面的代码👇

  <select id="selectBooksLike2" resultType="com.wh.model.Book" parameterType="java.lang.String">
  select * from t_mvc_book where bname like '${bname}'
</select>

 那么就阔以看到结果了

3.使用concat{'%',#{字段名},'%'}

<select id="selectBooksLike3" resultType="com.wh.model.Book" parameterType="java.lang.String">
  select * from t_mvc_book where bname like concat('%',#{bname},'%')
</select>

 结果

  •  #{字段名}和${字段名}的区别
    • #{}表示使用用户输入的值作为参数,而${}表示使用预定义的变量值作为参数
    • #自带引号$传参不带引号
    • ${}
    • ${}可能会导致SQL注入的风险,因为它允许我们在SQL语句中插入任意的值(SQL注入攻击:SQL注入是一种代码注入技术,攻击者通过在SQL语句中插入恶意的代码来控制数据库。为了防止SQL注入,我们应该尽量避免直接拼接SQL语句,而应该使用参数化查询或者其他安全的方法)
      • 举个例子说明一下:

        假设有一个Web应用,用户可以通过搜索框输入关键词查询商品信息。现在我们要分析这个应用是否存在SQL注入的风险。

        在这个应用中,用户输入的关键词会被拼接到SQL查询语句中,如:SELECT * FROM products WHERE keyword = '用户输入的关键词';。如果攻击者在搜索框中输入特殊字符,如单引号('),那么拼接后的查询语句可能变成:SELECT * FROM products WHERE keyword = '' OR '1'='1';。这样,原本的查询条件就被绕过了,攻击者可以获取到所有商品的详细信息

    • ${}也有它的好处,它可以用来做动态列
      • 举个例子说明一下:

        假设我们有一个销售记录表,其中包含以下列:产品ID、产品名称、销售数量、销售日期和销售价格。现在,我们希望根据销售数量对产品进行分组,并计算每个产品的总销售额。

        为了实现这个需求,我们需要在表中添加一个新列(例如“产品类别”),并根据销售数量对数据进行分组。然后,我们可以使用聚合函数(如SUM)来计算每个产品的总销售额,但是这样的话,我们需要修改的地方就有很多,那么这个时候我们就可以用到动态列,因为动态列允许我们在不修改表结构的情况下实现这个需求

四、MyBatis结果映射 

在使用MyBatis中拥有多个场景,返回的结果是多样的,resultType/resultMap

1返回单表的对应的实体类,仅有一个查询结果,可以用resultType/resultMap

2返回单表的对应的实体类,有多个查询结果,可以用resultType/resultMap

3返回多表对应结果,仅有一个查询结果,通常用resultType也可以用resultMap

4返回多表对应结果,有多个查询结果,通常用resultType也可以用resultMap

5返回单个列段,仅有一个查询结果,就用resultType

6返回单个列段,有多个查询结果,就用resultType

  总结就是在Mybatis中结果集的处理分为两种:

①resultMap:适合使用返回值是自定义实体类的情况

②resultType:适合使用返回值的数据类型是非自定义的,即jdk的提供的类型

 如果是单表的情况下,resultType与resultMap都可以使用。
1 使用resultMap返回映射关系,指的是实体类与数据库字段的关系

2 使用resultType返回List<T>

3 使用resultType返回单个对象

4 使用resultType返回List<Map>【适用于多表查询返回结果集】

5 使用resultType返回Map<String,Object>【适用于多表查询返回单个结果集】
 

1.resultType进行结果映射

假设我们有一个用户表user,包含以下字段:id、name、age、gender、email。现在需要根据这些字段查询用户信息并返回一个User对象。

首先,我们需要定义一个User类,用于存储查询结果:

public class User {
    private int id;
    private String name;
    private int age;
    private String gender;
    private String email;
    // getter和setter方法省略
}

然后,在MyBatis的mapper文件中,我们可以使用resultType来映射查询结果到User对象上

<select id="getUserById" resultType="com.example.User">
  SELECT id, name, age, gender, email
  FROM user
  WHERE id = #{id}
</select>

在上面的配置中,我们使用了resultType属性来指定查询结果映射到的Java对象的全限定名。这样,当执行查询语句时,MyBatis会自动将查询结果映射到指定的Java对象上

2.resultMap进行结果映射


假设我们有一个订单表order,包含以下字段:id、user_id、product_id、price、quantity。现在需要根据这些字段查询订单信息并返回一个Order对象

首先,我们需要定义一个Order类,用于存储查询结果:

public class Order {
    private int id;
    private int userId;
    private int productId;
    private double price;
    private int quantity;
    // getter和setter方法省略
}

然后,在MyBatis的mapper文件中,我们可以使用resultMap来映射查询结果到Order对象上。具体配置如下:


<resultMap id="OrderResultMap" type="com.example.Order">
  <id property="id" column="id" />
  <result property="userId" column="user_id" />
  <result property="productId" column="product_id" />
  <result property="price" column="price" />
  <result property="quantity" column="quantity" />
</resultMap>
<select id="getOrderById" resultMap="OrderResultMap">
  SELECT id, user_id, product_id, price, quantity
  FROM order
  WHERE id = #{id}
</select>

在上面的配置中,我们定义了一个名为"OrderResultMap"的resultMap,它的type属性指定了要映射的Java对象的全限定名。接下来,我们为每个字段指定了对应的属性名和数据库表中的列名。最后,在查询语句中引用这个resultMap即可将查询结果映射到Order对象上。

需要注意的是,如果查询结果中的某个字段在Java对象中没有对应的属性,那么该字段将被映射为null。此外,如果查询结果中的某个字段在Java对象中有多个对应的属性,那么该字段的值将被映射为一个列表或数组

 好啦,今天的分享就到这了,希望能够帮到你呢!😊😊     

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

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

相关文章

2022美亚杯个人赛复刻

案件详情 于2022年10月&#xff0c;有市民因接获伪冒快递公司的电邮&#xff0c;不慎地于匪徒架设的假网站提供了个人信用咭资料导致经济损失。 警方追查下发现当中一名受骗市民男子李大輝 (TaiFai) 的信用卡曾经被匪徒在区内的商舖购物。 后来警方根据IP地址&#xff0c;锁定…

js实现定时器

用原生js实现一个倒计时效果.最下面有全部源码,需要自取 js语法: setTimeout:定时器 document.getElementById:Document的方法 getElementById()返回一个匹配特定 ID的元素。由于元素的 ID 在大部分情况下要求是独一无二的&#xff0c;这个方法自然而然地成为了一个高效查找特…

第三篇:对话框窗口部件 QDialog

对话框窗口部件 QDialog 对话框&#xff08;Dialog&#xff09;是计算机图形用户界面&#xff08;GUI&#xff09;中的一种常见窗口类型&#xff0c;通常用于与用户进行交互、获取信息、提供反馈或执行特定任务。对话框的主要目的是与用户进行短期的、有限的交互&#xff0c;以…

【校招VIP】产品职位理解之团队的配合和推进

考点介绍&#xff1a; 对于简历上有实习经验的同学&#xff0c;对于团队配合和项目推进是一个非常常见的提问点。产品经理经常会面临项目延期&#xff0c;无法上线的情况。基于此&#xff0c;产品经理应该做些什么来保障项目按时上线呢&#xff1f; 『产品职位理解之团队的配合…

THUHCSI人机语音交互实验室9篇论文被语音旗舰国际会议INTERSPEECH录用

2023年ISCA国际语音通讯学会年会&#xff08;2023 Annual Conference of the International Speech Communication Association, INTERSPEECH 2023&#xff09;将于2023年8月20日-24日在爱尔兰都柏林召开&#xff0c;清华大学人机语音交互实验室&#xff08;THUHCSI&#xff09…

视频监控平台EasyCVR视频汇聚平台档案库房图书馆等可视化管理平台应用场景全面解析

档案是一种特殊的记录留存文献&#xff0c;具有珍贵的精神财富价值。它们是人类活动的真实见证&#xff0c;是辉煌时刻的历史记录&#xff0c;在社会发展和经济建设中发挥着至关重要的作用。 随着市场经济的不断发展和人类文明的飞速推进&#xff0c;档案的价值和作用变得越来…

【广州华锐互动】VR工厂消防安全演习提供了一种全新、生动的安全教育方式

在工业生产环境中&#xff0c;安全永远是首要的考虑因素。近年来&#xff0c;随着科技的发展&#xff0c;虚拟现实(VR)技术在各种领域的应用越来越广泛&#xff0c;包括教育和培训。其中&#xff0c;VR工厂消防安全演习就是一个典型的例子&#xff0c;它为员工提供了一种全新的…

msvcr120.dll丢失的解决方法,win10系统dll报错解决方法

今天&#xff0c;我将和大家分享一个在win10系统中经常遇到的问题&#xff1a;msvcr120.dll丢失。相信很多朋友在使用电脑的过程中都会遇到这个问题&#xff0c;那么如何解决呢&#xff1f;接下来&#xff0c;就让我为大家详细讲解一下解决方法。 首先&#xff0c;我们来了解一…

基于Spark+django的国漫推荐系统--计算机毕业设计项目

近年来&#xff0c;随着互联网的蓬勃发展&#xff0c;企事业单位对信息的管理提出了更高的要求。以传统的管理方式已无法满足现代人们的需求。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;随着各行业的不断发展&#xff0c;基…

pdf怎么转换成图片?用这几种简单方法搞定

pdf怎么转换成图片&#xff1f;PDF作为一种通用的文档格式&#xff0c;广泛应用于各个领域。然而&#xff0c;在某些情况下&#xff0c;我们可能需要将PDF文件转换成图片格式&#xff0c;以便更方便地在网页、社交媒体或演示中使用。下面就给大家介绍三种简单而高效的方法来实现…

基于swing的旅游管理系统java jsp旅行团信息mysql源代码

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 基于swing的旅游管理系统 系统有1权限&#xff1a;管…

【Win】Dell Command PowerShell Provider 一款强大的IT工具

Dell Command | PowerShell Provider 是一款强大的IT工具&#xff0c;它允许用户通过 Windows PowerShell 界面轻松管理 Dell 硬件平台的 BIOS 配置。它提供了一系列的 PowerShell cmdlets命令&#xff0c;这些命令可以帮助 IT 管理员对 Dell 硬件平台进行 BIOS 配置的控制和管…

【ES6】—【必备知识】—扩展运算符与rest参数

一、扩展运算符 1. 定义&#xff1a;把数组或类数组展开成用逗号隔开的值 function foo(a,b,c) {console.log(a,b,c) } let arr [1,2,3] foo(...arr)2. 把两个数组合并 2-1. ES5 实现 let arr1 [1,2,3] let arr2 [4,5,6] Array.prototype.push.apply(arr1, arr2) consol…

【PHP】文件包含-includerequire

文章目录 文件包含意义&#xff1a;四种形式文件加载原理include和require的区别文件的加载路径文件嵌套包含 文件包含 文件包含&#xff1a;在一个PHP脚本中&#xff0c;去将另外一个文件&#xff08;PHP&#xff09;包含进来&#xff0c;去合作完成一件事情。 意义&#xf…

sql递归查询

一、postgresql 递归sql with recursive p as(select t1.* from t_org_test t1 where t1.id2union allselect t2.*from t_org_test t2 join p on t2.parent_idp.id) select id,name,parent_id from p; sql中with xxxx as () 是对一个查询子句做别名&#xff0c;同时数据库会对…

【计算机视觉】递归神经网络在图像超分的应用Deep Recursive Residual Network for Image Super Resolution

DRCN: Deeply-Recursive Convolutional Network for Image Super-Resolution 总结 这篇文章是第一次将之前已有的递归神经网络(Recursive Neural Network)结构应用在图像超分辨率上。为了增加网络的感受野&#xff0c;提高网络性能&#xff0c;引入了深度递归神经网络&#x…

Unity脚本常用生命周期

Unity脚本在Unity引擎运行时会经历多个阶段的变化。如创建&#xff0c;初始化&#xff0c;按帧执行&#xff0c;固定执行&#xff0c;绘制&#xff0c;禁用&#xff0c;销毁等等。具体如下图所示&#xff1a; 我们创建脚本时都是默认继承了MonoBehaviour类&#xff0c;而MonoBe…

【文心一言】如何申请获得体验资格,并简单使用它的强大功能

目录 一、文心一言1.1、它能做什么1.2、技术特点1.3、申请方法 二、功能体验2.1、文心一言2.2、写冒泡排序代码 测试代码2.3、画一个爱心2.4、画一个星空 三、申请和通过3.1、申请时间3.2、通过时间 文心一言&#xff0c;国内首个大型人工智能对话模型&#xff0c;发布已经快一…

直播APP开发,协议盘点(五):实时传输协议RTP

简介&#xff1a; 在直播APP开发的过程中&#xff0c;搭建协议实现相应的功能是开发重点之一&#xff0c;而直播APP开发的协议是繁多且复杂的&#xff0c;所以从前段时间开始&#xff0c;我做了直播开发的协议篇&#xff0c;到今天为止我已经分享了四个协议&#xff0c;下面我为…

3DXML在线查看与转换工具

3DXML 由软件巨头达索系统推出&#xff0c;是 3D 设计和工程中的关键文件格式&#xff0c;提供了封装和共享 3D 数据的系统方法。 为了将简单性与丰富的数据表示相结合&#xff0c;3DXML 在与 STEP 等其他文件格式相比时展现出其独特的优势&#xff0c;特别是在数据丰富性和紧凑…