MyBatis - 基础使用Ⅰ

news2024/12/26 23:46:02

这篇文章将讲解MyBatis的基础使用,MyBatis的学习是非常重要的,在前面学习servlet的时候,我们就能感受到将数据持久化存储的重要性,当时在使用JDBC的时候非常繁琐麻烦,但是在Spring里,提供了一种框架可以轻松且惬意的实现数据存储的功能:MyBatis。

MyBatis的学习只分为俩部分:1.配置MyBatis的环境 2.设置配置信息

1.MyBatis的环境搭建

        在Spring里的MyBatis因为依靠SpringBoot实现的,因此使用MyBatis的话,环境搭建如下:

在依赖注入里面引入这俩依赖,MyBatis配置就完成了 

2.设置MyBatis的配置信息

        2.1 设置数据库连接的相关信息

在application中进行:

 

如果使⽤ mysql-connector-java 是 5.x 之前的使⽤的是“com.mysql.jdbc.Driver”,如果是⼤于 5.x使⽤的是“com.mysql.cj.jdbc.Driver”

        2.2 设置MyBatis的xml保存路径和命名方式

 这时候 环境就搭建完成咯~~
 

3.Mybatis基本使用

 上图来看 每个Mybatis的使用(命令)包括俩个组件:Inteface和xml,Interface是供Controller使用的接口,而xml就是sql语句放在这里,但是xml怎么实现接口的方法呢?Mybatis通过代理的方式:生成一个代理对象:会将interface方法的声明和xml方法的实现组成一个代理对象,进行填充。这里可以用一个例子来解释,你有一个苹果手机和一个安卓数据线,这时候你无法进行充电,但是如果说有一个转换头,就可以实现充电的功能,这个转换头就是Mybatis,将Interface和xml进行组合变成一个虚拟对象,就可供其他类或者方法进行调用了。

        Mybatis有俩部分组成:Inteface(让其他层进行调用/注入) 和 xml(提供了具体的实现sql语句)

        我们想要从数据库里获取数据到页面上,我们就需要做以下步骤:

由于在xml文件中已经规范了Mybatis的保持路径和命名规范了,因此:

xml文件: 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="getAll" resultType="com.example.demo.entity.UserEntity">
        select * from userinfo
    </select>
</mapper>

select标签内 id 是方法名字,resultType 是返回的类所在的位置。

如果我们想不通过输入网址的方式来实现测试功能的话,我们就要涉及到单元测试的相关知识了

接下来简单讲一下单元测试的使用方法:

4.单元测试基础使用

        由于在Spring里内置了相关单元测试的框架,因此在使用单元测试的时候,我们就不必再引入一个新的依赖了,具体使用如下:

        

 @SpringBootTest的注解表明当前的类还是在Spring上运行的

 那就写一个按id查询返回操作的代码吧:

在接口的代码中,关于传参还是要用到注解,这里的@Param注解内部写的“id”意思是把你传入的参数id命名为id存进spring中(换句话说存到了MyBatis中)。

         4.2 获取动态参数

        在xml文件中的sql语句里我们在设置条件的时候 用到了 ${} 这样的形式来获取动态参数,这里其实就是直接替换的方式,啥意思呢?就是直接将 id = 后面的值直接更换成在Spring中存取的id的值,还有一种方式 是 #{} ,它的意思是先写成 id = ? 的形式,就是先用个占位符,然后再替换值,二者有啥区别?

        正如上面的代码,因为是id数值型数据,我们无法感知到啥区别,但如果传递的参数是String的呢?用直接替换的方式的话,需要在外面加上个 ' ',因为sql语句进行存在String操作的时候需要加上单引号,而直接替换的方式,无法进行自动加' ' ,#{}则不同,先使用的是占位符,然后识别到String 再进行替换,替换的时候就相当于自动加上了' '

在 MyBatis 中,#{} 和 ${} 都是用于 SQL 语句中的变量替换,但它们的使用方式和作用是不同的。

#{} 主要用于向 SQL 中传递参数,可以防止 SQL 注入攻击。在 SQL 执行前,MyBatis 会将 #{} 替换成一个占位符 "?", 然后使用 PreparedStatement 进行预编译,最终执行 SQL 语句时将参数值设置到占位符中。因此,使用 #{} 可以提高 SQL 执行的安全性和效率。

例如:SELECT * FROM user WHERE id = #{id}

${} 主要用于替换 SQL 语句中的表名、列名等部分,不能防止 SQL 注入攻击,不会对参数进行预编译处理。在 SQL 执行前,MyBatis 会直接将 ${} 替换成变量的值,然后与其他 SQL 文本一起拼接成最终的 SQL 语句。因此,使用 ${} 可以方便地构造动态 SQL,但同时也带来了安全隐患。

例如:SELECT * FROM ${tablename} WHERE id = ${id}

总结一下,#{} 主要用于传递参数,防止 SQL 注入攻击;${} 主要用于替换 SQL 语句中的表名、列名等部分,方便构建动态 SQL,但存在 SQL 注入风险

如果是排序查询的话,那就只能使用${},因为如果是使用占位符的形式的话,因为spring识别到 #{}里面的数据是String类型,在替换的时候,会在外面加上个' '(sql),无法进行正常的排序查询。 

5.增删改操作

        5.1修改操作

         5.2 删除操作

        5.3 增加操作

        5.3.2 返回id的增加操作 

在xml文件修改一下

6. 查询操作

        6.1 单表查询

        查询特定Id的userinfo表:

         6.2 模糊查询

        模糊查询就是在sql语句中使用了like关键字,但是我们如果直接使用 #{}  的话会出问题的,因为先将目标位置替换之后,因为要替换的是String类型, 替换之后会出现  like ' ... '  的形式~~

         这时候sql中一个concat函数就能够有效的帮助我们。

        虽然在增删改操作可以不设置返回的数据类型,返回一个受影响的行数就ok了,但是在查询操作中,必须是要设置返回的类型是啥,我们至今使用的是resultType ,resultType在使用的时候是非常方便的,直接指明你要返回的类型是哪个类,但是如果是实体类中的数据名称,与sql语段的名称,直接使用resultType似乎鸡肋了~~,这时候resultMap就大显神威了。

        6.3 resultMap

 我们先将实体类中的password改成pwd,使用上面BaseMap也能正常运行。

 

         6.2 多表查询

                6.2.1 一对一

        想象一下场景:我们想获取文章表的数据并且在数据里面有用户表的username属性。

     这样就ok了。

         6.2.2 一对多

        我们再假设个场景:当你输入一个uid也就是文章表的用户id,就查询到该用户的所有文章。

7. 动态SQL

        先讲讲为什么用动态sql吧:

使用动态 SQL 可以让 SQL 语句更加灵活、可维护和易于扩展。具体来说,动态 SQL 的优点包括:

  1. 条件分支:动态 SQL 可以根据不同的条件拼接不同的SQL语句,从而实现不同的查询需求,这比使用多个固定 SQL 的方式更加灵活。

  2. 参数化:动态 SQL 可以使用参数化语法,从而可以避免 SQL 注入攻击,并且可以减少 SQL 执行计划的生成次数,提高 SQL 的执行效率。

  3. 可维护性:使用动态 SQL 可以将 SQL 语句拆分成多个小段,每个小段都有明确的含义和作用,这样就方便后期维护和修改,而不必修改整个 SQL 语句。

  4. 可复用性:使用动态 SQL 可以将多个相似的 SQL 语句抽象成一个通用的 SQL 模板,不仅可以减少代码量,还可以提高代码复用性。

总之,使用动态SQL可以让开发者更加简便地编写 SQL 语句,并且可以在不牺牲性能的情况下提高系统的灵活性、可维护性和可扩展性。

        7.1 if标签

         这里常见的适用场景是在我们进入用户信息填写的时候,有的信息是必填也有的是不必填的,那些不是必须要填的,我们往往会空着,意思是就是在insert语句中values后面的值没有他就ok了,那这种类似条件判断的实现就要靠if标签实现了。

我们设计一下添加用户表的场景 具体代码如下:

         7.2 trim标签

注意下面的代码,trim标签里面prefix的意思是这个整体前面加个  "("   suffix则是在结尾处加个 ")"

而suffixOverrides则是去掉最后面的元素(指的是在 )前面的元素),意思就是如果说pwd不为空传进去的话,此时会加上   “  ,” 就会报错,实现suffixOverrides的话就可以避免这种情况了。

        7.3 where标签

        当然有了上面的trim标签似乎也可以实现动态的trim标签就是删除多的元素嘛,开头加个where就ok了,但是还有更简单的方式去实现动态where,那就是where标签。

        实现一个 :你可以传与不传username和id,根据你传还是没传具体的数据来查询表结构。

    <select id="getByDiy" resultType="com.example.demo.entity.UserEntity">
        select * from userinfo
        <where>
            <if test="username != null">
                and username = #{username}
            </if>
            <if test="id">
                and id = #{id}
            </if>
        </where>
    </select>

        7.4 set标签

        一样的道理,set标签相当于是trim简化版~~但需要注意的是where默认是删除前面的,set是默认删除后面的多余的字符。

        7.5 foreach标签

单元测试代码

    //加个事务标签进行回滚操作
    @Transactional
    @Test
    void delByList() {
        List<Integer> list = new ArrayList<>();
        for(int i = 0; i < 2;i++){
            list.add(i);
        }
        articleMapper.delByList(list);
    }

xml文件

    <delete id="delByList">
        delete from articleinfo where id in 
        <foreach collection="list" item="item" open="(" close=")" separator=",">
            #{item}
        </foreach>
    </delete>

接口/声明方法

    int delByList(List<Integer> list);

        collection表明的是具体的传过去的参数集合,item就是遍历时的每一个对象,open、close就是开头结尾加上这俩东西,separator则是自动的在自动的检测添加,给遍历的对象。

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

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

相关文章

真题详解(传引用)-软件设计(七十五)

真题详解&#xff08;补码转换&#xff09;-软件设计&#xff08;七十四)https://blog.csdn.net/ke1ying/article/details/130674214 分治算法技术设计______。 答案&#xff1a;1、问题划分 2、递归求解 3、合并解 虚拟存储体系_____两级构成。 解析&#xff1a;主存 和 辅…

vue项目打包成桌面应用并修改图标

目录 1. 打包为桌面应用 2.修改图标 1. 打包为桌面应用 1.在vux项目的终端执行打包 npm run build 2.会在项目文件夹里面出现一个dist文件夹 里面有这几个文件组成 3.在这里需要添加一个 package.json 文件 package.json 内容 {"name": "鼠标放图标上面的提…

环形链表解释约瑟夫问题

环形链表解释约瑟夫问题 来自尚硅谷开放课程的迁移学习&#xff0c;致敬尚硅谷的各位老师&#xff0c;受益匪浅&#xff01;&#xff01;&#xff01; 单向链表&#xff0c;双向链表&#xff0c;环形链表对比介绍 单向链表、双向链表和环形链表都是常见的链表数据结构&#…

介绍如何在 MySQL 中创建新用户并授予权限?

MySQL 是一个开源的关系型数据库管理系统&#xff0c;常用于存储和管理大量的结构化数据。在使用 MySQL 进行数据管理时&#xff0c;为了安全和方便管理&#xff0c;通常需要创建新用户并授予相应的权限。本文将介绍如何在 MySQL 中创建新用户并授予权限的方法。 创建新用户 在…

第十一章结构性模式—组合模式

文章目录 组合模式解决的问题概念结构 实例组合模式的分类优点使用场景 结构型模式描述如何将类或对象按某种布局组成更大的结构&#xff0c;有以下两种&#xff1a; 类结构型模式&#xff1a;采用继承机制来组织接口和类。 对象结构型模式&#xff1a;釆用组合或聚合来组合对…

shell脚本之“awk“命令

文章目录 1.awk工作原理2.awk命令演示操作部分2.1 按行输出文本演示操作2.2 BEGIN模式演示操作2.3 按字段输出文本演示操作2.4 通过管道、双引号调用Shell命令2.5 date命令演示操作2.6 getline参数详解2.7 awk命令的数组操作 3. 总结 1.awk工作原理 逐行读取文本&#xff0c;默…

位域和字节对齐

结构体中的位域 位域是一种特殊的结构体成员&#xff0c;它允许将一个字节或多个字节中的每个位作为一个独立的成员来使用。位域的语法形式为&#xff1a; struct {type [member_name] : width; }; 其中&#xff0c;type 表示位域成员的类型&#xff0c;可以是 int、unsigne…

网络编程——TCP编程

TCP编程 流程服务器客户端 函数接口1、socket2、bind3、listen4、accept5、recv6、send7、connet 实现双工通信server.ccelient.c优化代码 流程 在C语言中进行TCP编程的一般步骤如下&#xff1a; &#xff08;1&#xff09;包含头文件&#xff1a; 在代码中包含必要的头文件&a…

面对象QgsPolygon

几何对象中的面用QgsPolygon进行封装&#xff0c;也称为多边形简单的多边形是由一串点连接而成&#xff0c;并首尾闭合多边形的结构更复杂&#xff0c;除了有一个外部轮廓&#xff0c;还可能包括内部多个轮廓 创建面对象 QgsPolygon() #创建一个空的面 使用setExteriorRing设…

Spring AOP 实践指南

Spring AOP 实践指南 文章目录 Spring AOP 实践指南一、概述1、简介2、官方资料3、本文档说明 二、基本使用1、引入依赖2、定义切面3、定义切点4、创建 HelloController5、启动项目&#xff0c;访问测试 三、通知1、概述五种通知通知的顺序 2、通知方法接受的参数3、前置通知代…

Thread线程学习(1) 了解线程的基本知识——什么是线程

本专栏将记录有关线程方面的知识 在计算机科学领域中&#xff0c;线程&#xff08;Thread&#xff09;是一种执行计算机程序的基本单元。对于初学者来说&#xff0c;理解线程是学习并发编程的关键一步。本文将带你了解线程的基础知识&#xff0c;包括线程的定义、线程与进程的关…

GPT神奇应用:给孩子做每日安排

正文共 1163 字&#xff0c;阅读大约需要 4 分钟 家长必备技巧&#xff0c;您将在4分钟后获得以下超能力&#xff1a; 快速生成每日安排计划 Beezy评级 &#xff1a;B级 *经过简单的寻找&#xff0c; 大部分人能立刻掌握。主要节省时间。 推荐人 | Kim 编辑者 | Linda ●图片…

JavaScript实现打印倒金字塔的代码

以下为实现打印倒金字塔的程序代码和运行截图 目录 前言 一、实现打印倒金字塔 1.1 运行流程及思想 1.2 代码段 1.3 JavaScript语句代码 1.4 运行截图 前言 1.若有选择&#xff0c;您可以在目录里进行快速查找&#xff1b; 2.本博文代码可以根据题目要求实现相关使用功…

动态规划专题

动态规划专题 最长递增子序列LeetCode 300. 最长递增子序列解题思路代码实现 LeetCode 354. 俄罗斯套娃信封问题解题思路代码实现 总结 不要纠结&#xff0c;干就完事了&#xff0c;熟练度很重要&#xff01;&#xff01;&#xff01;多练习&#xff0c;多总结&#xff01;&…

【Redis】Redis中bitmap的原理和使用

文章目录 一、原理二、BitMap 相关命令三、BitMap 空间计算四、使用场景1. 用户签到2. 统计活跃用户&#xff08;用户登陆情况&#xff09;3. 统计用户在线状态4. 实现布隆过滤器 五、总结 一、原理 先声明一下&#xff1a;Redis 有5种数据类型&#xff0c;而 BitMap 在 Redis…

【k8s】Ubuntu22.04离线部署k8s集群:搭建软件仓库和镜像仓库(repo节点)

上两篇主要记录了在CentOS 7环境中离线部署k8s的方案&#xff0c;本篇继续介绍方案二在Ubuntu 22.04的实现。&#xff08;当然&#xff0c;整体思路还是跟上篇基本相似&#xff09; 目录 Ubuntu22.04离线部署k8s集群&#xff1a;搭建软件仓库和镜像仓库&#xff08;repo节点&am…

总结852

学习目标&#xff1a; 月目标&#xff1a;5月&#xff08;张宇强化前10讲&#xff0c;背诵15篇短文&#xff0c;熟词僻义300词基础词&#xff09; 周目标&#xff1a;张宇强化前5讲并完成相应的习题并记录&#xff0c;英语背3篇文章并回诵 每日必复习&#xff08;5分钟&#…

云上高校导航 小程序 开发教程 1.0.1

​ Gitee仓库&#xff1a;云上高校导航 GitHub仓库&#xff1a;云上高校导航 “云上高校导航”是一套基于小程序云开发的校园导航类系统开发方案&#xff0c;该开发方案可供开发者进行二次开发&#xff0c;用于解决师生和访客的校园出行需求。 项目优势及创新&#xff1a;…

ChatGPT vs. Bing vs. Bard

随着 2022 年 ChatGTP 的推出&#xff0c;人工智能聊天机器人的世界突然走上了一条新道路。如今&#xff0c;密切关注 AI 的人都知道&#xff0c;不同公司推出了几款产品。从谷歌拥有自己的 Bard AI&#xff0c;到微软发布新的 Bing AI Chat&#xff0c;再到 OpenAI 发布GPT-4。…

云服务器搭建Python项目实现学术优化chatgpt

云服务器搭建实现学术优化chatgpt 1 服务器准备2 云服务器配置2.1 python虚拟环境2.1.1 python3.9安装配置2.1.2 下载python项目2.1.3 创建python虚拟环境 3 后台运行python项目&#xff08;不然不能关闭与云服务器的连接&#xff0c;那意义何在&#xff1f;&#xff09; 1 服务…