Mybatis编写SQL

news2024/11/26 20:33:39

文章目录

  • 一、用注解编写
    • 1.1 增
      • 普通增加
      • 获取自增ID
    • 1.2 删和改
    • 1.3 查
      • 单表查询
      • 多表查询
  • 二、用xml编写
    • 2.1 使用xml的流程
    • 2.2 增
      • 普通增加
      • 获取自增ID
    • 2.3 删 和 改
    • 2.4 查
  • 三、#{} 和 ${}
    • 3.1 #{} 、${}
    • 3.1 预编译 SQL 、即时编译SQL

两种写法是可以同时存在的

一、用注解编写

1.1 增

普通增加

  1. 拼接字符串:如果注解里面的字符串太长了,可以用 +即【拼接字符串】的方式。直接按回车即可。
  2. 返回值:增删改时,返回值可以为Integer,也可以为void。但我们一般还是会设置为Integer的,因为【有时候我们的程序是否执行成功,是没有什么提示的,此时,我们就可以用“受影响的行数”来判断程序有无执行成功】
    • 当为Integer时,返回的是“受影响的行数”
    • 为void就什么都不返回
  3. 参数:也可以一个一个传。因为要传的参数比较多,此处是用对象来传参
@Mapper
public interface UserInfoMapper {
    @Insert("insert into userinfo (username, password, age, gender, phone)" +
            "values(#{username}, #{password}, #{age}, #{gender}, #{phone})")
    Integer insert(UserInfo userInfo);
}

获取自增ID

  1. 使用场景:有很多服务都是需要拿到id后,才能进行下一步操作。如订单团队,需要获取你的订单ID,后续才能进行支付对账操作。
  2. 代码:使用@Options注解
    • useGeneratedKeys:是否自动生成key,默认为false,这里要设置为 true
    • keyProperty:要把生成的key(主键)的值赋值给谁。下面示例中是赋值给了userinfo对象的id属性。
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("insert into userinfo (username, password, age, gender, phone)" +
        "values(#{username}, #{password}, #{age}, #{gender}, #{phone})")
Integer insert(UserInfo userInfo);

1.2 删和改

  1. 删除
 @Delete("delete from userinfo where id = #{id}")
 Integer delete(Integer id);
  1. 修改
@Mapper
public interface UserInfoMapper {

    @Update("update userinfo set age = #{age} where id = #{id}")
    Integer update(UserInfo userInfo);
}
@Slf4j
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Test
    void update() {
        UserInfo userInfo = new UserInfo();
        userInfo.setAge(22);
        userInfo.setId(11);
        Integer res = userInfoMapper.update(userInfo);
        //使用返回值判断【程序是否正确运行】
        if (res > 0){
            log.info("数据更新成功");
        }
    }
}

1.3 查

单表查询

  1. 不带有参数
@Mapper
public interface UserInfoMapper {
    @Select("select * from userInfo")
    List<UserInfo> selectAll();
}
  1. 带参数
    • 如果只有一个参数,名称是可以不匹配的,但通常情况下,为了方便去阅读,我们还是会让他们保持一致
    • 如果有多个参数,是需要我们匹配的

参数匹配

@Mapper
public interface UserInfoMapper {
    @Select("select * from userInfo where id = #{id}")
    UserInfo selectUser(Integer id);
}

参数不匹配

@Mapper
public interface UserInfoMapper {
    @Select("select * from userinfo where id = #{id}")
    UserInfo selectUser(Integer id123);
}

多表查询

  1. 避免使用多表查询:我们要尽量避免使用多表查询,尤其是性能要求很高的项目

    • 原因
      • :如果查询两个表分别要10s,把他们放在一起查询肯定会大于10s,因为多表查询还有【整理】的操作
      • 程序员不可控:Java方面可以使用多线程的方式优化多表查询,但如果直接使用多表查询的SQL语句,相当于直接把优化的操作交给了Mysql,程序员层面无法再优化了
      • 会影响其他项目:通过情况下,数据库是集群使用的,即很多项目都会用到一个数据库。此时,当出现慢查询时,会影响整个集群,即会影响到所有使用该集群的项目。
      • 扩容效率低:当要进行扩容操作时,Java服务器扩容十分方便,但是数据库集群扩容就需要专门的人员来处理,十分麻烦
    • 多表查询的优势:操作简单。如果使用多线程优化,我们还需要进行逻辑上的处理,所以一些对性能要求不是很高的项目,还是可以使用多表查询的
  2. 如何使用多表查询:直接用多表查询的SQL + Java对象有对应的属性

    • 原理:Mybatis不在乎是多表SQL还是单表SQL
      • Mybatis的工作是把这个方法的SQL语句发送给Mysql,在Mysql给我们返回一个结果(可以通过打印的Mybatis日志查看)后,Mybatis进行结果映射,并按照方法定义返回对应的值
      • 所以,Mybatis根本不关注SQL是单表还是多表,它所关注的只是如何进行结果映射,我们只要确保对象里有对应的属性就行。

在这里插入图片描述

二、用xml编写

2.1 使用xml的流程

  1. 配置数据库资源:和注解时配置的一样
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  1. 配置路径
    在这里插入图片描述
  2. 对xml进行声明
    • namespace:表示要实现哪个接口,要求写接口的全限定类名(如果按住ctrl能来到想要的接口,就说明没有写错路径)
<?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.UserInfoXMLMapper">

</mapper>
  1. 编写xml
    • 换行规则:xml的SQL区域,换行直接敲回车即可,整块会被当成一个字符串
    • 返回类型的指定:只有查询时,需要去说明返回的类型,其他的增删改则不需要指定
      • 指定返回类型的规则
        • 使用全限定类名
        • 不需要指定返回的是List,Mybatis能识别出我们返回的是List 还是 其他的数据类型
@Mapper
public interface UserInfoXMLMapper {
    List<UserInfo> selectAll();
}
<?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.UserInfoXMLMapper">
    <select id="selectAll" resultType="com.example.demo.model.UserInfo">
       select * from userinfo	<!-->直接在这里写SQL语句即可<-->
    </select>
</mapper>

2.2 增

普通增加

  1. 未重命名
@Mapper
public interface UserInfoXMLMapper {
    Integer insert(UserInfo userInfo);
}
<?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.UserInfoXMLMapper">
    <insert id="insert">
        insert into userinfo (username, password, age, gender, phone)
        values(#{username}, #{password}, #{age},
        #{gender}, #{phone})
    </insert>
</mapper>
  1. 重命名:重命名方法和【注解方式】一致
@Mapper
public interface UserInfoXMLMapper {
   
    Integer insert(@Param("user") UserInfo userInfo);
}
<?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.UserInfoXMLMapper">
    <insert id="insert">
        insert into userinfo (username, password, age, gender, phone)
        values(#{user.username}, #{user.password}, #{user.age},
        #{user.gender}, #{user.phone})
    </insert>
</mapper>

获取自增ID

<?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.UserInfoXMLMapper">
    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into userinfo (username, password, age, gender, phone)
        values(#{username}, #{password}, #{age},
        #{gender}, #{phone})
    </insert>
</mapper>

2.3 删 和 改

  1. 删除
<delete id="delete">
    delete from userinfo where id = #{id}
</delete>
  1. 修改
<update id="update">
    update userinfo set age = #{age} where id = #{id}
</update>

2.4 查

  1. 关于resultType的指定
    • 范围:只有查询操作需要指定
    • 使用方法:使用全限定类名。不需要指定返回的是List,Mybatis能识别出我们返回的是List 还是 其他的数据类型
<?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.UserInfoXMLMapper">
    <select id="selectAll" resultType="com.example.demo.model.UserInfo">
       select * from userinfo	<!-->直接在这里写SQL语句即可<-->
    </select>
</mapper>

三、#{} 和 ${}

3.1 #{} 、${}

  1. 使用方面:优先使用#,不能直接使用#,就搭配内置函数或写多个接口等,最后考虑用$
  2. #{}、${}区别
    • 共同点:都是用来获取变量的值
    • 不同点
      • #{}是预编译SQL,${}是即时编译SQL
      • 特殊情况下不能直接使用#
  3. 无法使用直接#的场景:当参数为String,自动加的引号多此一举时。如排序、模糊查询、表名字段名等作为了参数。下面的解决方法其实也是#{}解决SQL注入的方法。
    • 升序降序:如果升序降序是参数,即使我们加了引号也无法运行
      在这里插入图片描述

    • 模糊查询
      在这里插入图片描述

3.1 预编译 SQL 、即时编译SQL

  1. 什么是预编译SQL 和 即时编译SQL
    • 预编译SQL:编译后缓存,后续从缓存拿,直接执行
      • 编译一次后会将编译后的SQL语句缓存起来,后续再执行这条语句时,不会再次编译(只是输入的参数不同),省去了前面的过程,直接执行,以此来提高效率
      • 相当于是一个框架,给你提前预留好一个位置,不管你是什么,都会把你作为id的参数塞进去
    • 即时编译SQL:直接去拼接,不管你这个参数里面是什么样,直接去拼上,也就会有【SQL注入】的问题了。

在这里插入图片描述
在这里插入图片描述

  1. 预编译SQL VS 即时编译SQL区别
    • 性能对比:预编译SQL占优
      • 预编译SQL:因为有缓存,可以直接去拿,性能高
      • 即时编译SQL:当出现【select * from bookinfo where id = ‘1’】的情况时,虽然 Mysql 会自动转化类型,代码依旧可以正常运行。但是当类型不一样时,有可能会出现一些性能问题
    • SQL注入问题:预编译SQL不存在SQL注入的问题,$则有
      • 什么是SQL注入问题:当参数中有SQL语句,可能会把这个语句当做SQL执行。
      • 示例:如【select * from bookinfo bookName = ‘’ or 1 = ‘1’]】,实际需求是要找bookName为【'or 1 = '1】的数据,但由于前后引号闭合了,or直接作为SQL语句执行,最终出现了bug

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

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

相关文章

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-24.5,6 SPI驱动实验-ICM20608 ADC采样值

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

【高校科研前沿】新疆生地所陈亚宁研究员团队在GeoSus发文:在1.5°C和2°C全球升温情景下,中亚地区暴露于极端降水的人口增加

目录 文章简介 1.研究内容 2.相关图件 3.文章引用 文章简介 论文名称&#xff1a;Increased population exposures to extreme precipitation in Central Asia under 1.5 ◦C and 2 ◦C global warming scenarios&#xff08;在1.5C和2C全球变暖情景下&#xff0c;中亚地区…

数学建模 —— 灰色系统(4)

目录 什么是灰色系统&#xff1f; 一、灰色关联分析 1.1 灰色关联分析模型 1.2 灰色关联因素和关联算子集 1.2.1 灰色关联因素 1.2.2 关联算子集 1.3 灰色关联公理与灰色关联度 1.3.1 灰色关联度 1.3.2 灰色关联度计算步骤 1.4 广义关联度 1.4.1 灰色绝对关联…

[AI]大模型训练成本到底有多大?

大模型成本到底有多大&#xff0c;大到太平洋装不下。 上图是早前统计的&#xff0c;目前比较流行的大模型的厂家、模型名称、参数级别和类型。 大模型的成本主要有三块&#xff0c;分别是训练成本、推理成本、储存成本。 大模型的成本确实主要涉及训练成本、推理成本和储存成…

Python 包安装及常用命令【python 入门】

背景&#xff1a; 近期看到一个项目&#xff0c;做微信只能机器人&#xff0c;服务是使用python搭建的&#xff0c;于是拷贝下来自己打算跑一跑&#xff0c;部署一下&#xff0c;可是自己又没有python的经验&#xff0c;于是各种查资料学习&#xff0c;跟着敲一敲&#xff0c;顺…

Signac|成年小鼠大脑 单细胞ATAC分析(1)

引言 在本教程中&#xff0c;我们将探讨由10x Genomics公司提供的成年小鼠大脑细胞的单细胞ATAC-seq数据集。本教程中使用的所有相关文件均可在10x Genomics官方网站上获取。 本教程复现了之前在人类外周血单核细胞&#xff08;PBMC&#xff09;的Signac入门教程中执行的命令。…

【机器学习】使用Stable Diffusion实现潜在空间搜索

1、引言 1.1 潜在空间的概念 潜在空间&#xff08;Latent Space&#xff09;是在机器学习和深度学习中一个重要的概念&#xff0c;它指的是用于表示数据的一种低维空间。这个空间编码了数据中包含的所有有用信息的压缩表示&#xff0c;通常比原始数据空间的维数更低&#xff…

java守护线程介绍

在Java中&#xff0c;守护线程&#xff08;Daemon Thread&#xff09;是一种特殊类型的线程&#xff0c;它在后台默默地运行&#xff0c;为其他线程提供服务。当 JVM 中只剩下守护线程时&#xff0c;JVM 会退出。这意味着&#xff0c;守护线程不应该执行关键的任务&#xff0c;…

COMPUTEX 2024 国际电脑展即将举行,英伟达宣布将Copilot+引入RTX系列设备,赋能游戏本AI助理

COMPUTEX 2024 国际电脑展即将于2024年6月4日至7日在台北南港展览馆1馆及2馆盛大举行。作为业界瞩目的盛会&#xff0c;本次展会不仅吸引了全球各地的科技爱好者&#xff0c;更迎来了AMD CEO苏姿丰博士和NVIDIA首席执行官黄仁勋的精彩演讲。 在展会的开幕之际&#xff0c;图形…

【Python】教你彻底了解Python中的模块和包

​​​​ 文章目录 一、模块的概念1. 导入模块2. 导入特定对象3. 给模块或对象取别名 二、标准库模块1. 常用标准库模块2. 使用示例 三、自定义模块1. 创建模块2. 使用自定义模块 四、包的结构与使用1. 创建包2. 使用包中的模块 五、包的深入使用1. 相对导入2. 子包3. 使用子包…

策略模式+简单工厂

&#x1f347;工厂模式 &#x1f348;工厂模式向策略模式过度——工厂加一个保安 &#x1f34f;策略模式 &#x1f350;策略模式简单工厂 声明本文需要理解多态的基础上才能来学习 欢迎前来学习——继承和多态 学习记录 工厂模式 需要什么就生成什么 // 工厂模式 class Fact…

DP读书:如何使用badge?(开源项目下的标咋用)

最近在冲论坛&#xff0c;很少更一些内容了。但遇到了一个真的有趣的&#xff1a; 开源项目下&#xff0c;蓝蓝绿绿的标是怎么用的呢&#xff1f; 这是我的主页Readme&#xff0c;在看一些NXP的主仓时&#xff0c;突然发现没有这个玩&#xff0c;就自己整了个 再比如我的CSDN专…

php高级之框架源码、宏扩展原理与开发

在使用框架的时候我们经常会看到如下代码 类的方法不会显示地声明在代码里面&#xff0c;而是通过扩展的形式后续加进去&#xff0c;这么做的好处是可以降低代码的耦合度、保证源码的完整性。我自己看着框架源码实现了这个功能。 以下是结果: base代码 index.php <?php…

WPS表格插件方方格子【凑数】功能:选出和等于固定数字的数

文章目录 后来发现可以下载方方格子插件&#xff0c;使用【凑数】功能https://ffcell.lanzouj.com/iwhfc1kjhayh【凑数】快速【凑数】 导师让沾发票&#xff0c;需要选出若干个数额的发票&#xff0c;使它们的和等于一个指定数。不知道怎么办了&#xff0c;查了一下&#xff0c…

【MySQL】数据库入门基础

文章目录 一、数据库的概念1. 什么是数据库2. 主流数据库3. mysql和mysqld的区别 二、MySQL基本使用1. 安装MySQL服务器在 CentOS 上安装 MySQL 服务器在 Ubuntu 上安装 MySQL 服务器验证安装 2. 服务器管理启动服务器查看服务器连接服务器停止服务器重启服务器 3. 服务器&…

三十九、openlayers官网示例Extent Interaction解析——在地图上绘制范围并获取数据

官网demo 地址&#xff1a; Extent Interaction 在openlayers中可以使用ExtentInteraction添加交互事件&#xff0c;配合shiftKeyOnly实现按住shift键绘制边界区域。 const map new Map({layers: [new TileLayer({source: new OSM(),}),],target: "map",view: new …

【贡献度分析(帕累托图)】

文章目录 前言一、贡献度分析是什么&#xff1f;二、使用步骤1. 准备数据2. 排序数据3. 绘制帕累托图4. 分析结果5. 实际应用 三、示例代码 前言 贡献度分析也称为帕累托分析。它可以帮助我们理解数据集中各个因素对整体影响的程度&#xff0c;从而优先处理最重要的因素&#…

oracle数据库通过impdp导入数据时提示,ORA-31684:对象类型用户xxx已存在,和ORA-39151:表xxx存在的解决办法

前提条件&#xff1a;首先备份原数据库中此用户对应的schemas 比如名为cams_wf的schemas 以便出了问题后还可以恢复原数据。 解决办法一、 通过命令或者数据库管理工具删除掉此schemas下的所有表&#xff0c;然后在impdp中加入ignorey 来忽略ORA-31684&#xff1a;对象类型用…

分享一个 .Net core Console 项目使用 SqlSugar 的详细例子

前言 SqlSugar 是一款老牌的 .NET 开源 ORM 框架&#xff0c;性能高&#xff0c;功能全面&#xff0c;使用简单&#xff0c;支持 .NET FrameWork、.NET Core3.1、.NET5、.NET6、.NET7、.NET8、.NET9 等版本&#xff0c;线上论坛非常活跃&#xff0c;今天给大伙分享一个 .Net c…

SCARA机器人中旋转花键的维护和保养方法!

作为精密传动元件的一种&#xff0c;旋转花键在工作过程中承受了较大的负荷。在自动化设备上运用广泛&#xff0c;如&#xff1a;水平多关节机械手臂&#xff08;SCARA&#xff09;、产业用机器人、自动装载机、雷射加工机、搬运装置、机械加工中心的ATC装置等&#xff0c;最适…