Mybatis编写SQL

文章目录

  • 一、用注解编写
    • 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【已解决】HtmlWebpackPlugin.getHooks is not a function

安装下面的依赖&#xff0c;获得 html-webpack-plugin 的 beta 版本 npm i html-webpack-pluginnext --save此问题在github上有讨论&#xff1a;https://github.com/facebook/create-react-app/issues/5465

网络报文协议头学习

vxlan&#xff1a;就是通过Vxlan_header头在原始报文前面套了一层UDPIP&#xff08;4/6&#xff09;Eth_hdr 需求背景&#xff1a;VXLAN&#xff1a;简述VXLAN的概念&#xff0c;网络模型及报文格式_vxlan报文格式-CSDN博客 如果服务器作为VTEP&#xff0c;那从服务器发送到接…

Java对象的揭秘

前言 作为一个 Java 程序员&#xff0c;我们在开发中最多的操作要属创建对象了。那么你了解对象多少&#xff1f;它是如何创建&#xff1f;如何存储布局以及如何使用的&#xff1f;本文将对 Java 对象进行揭秘&#xff0c;以及讲解如何使用 JOL 查看对象内存使用情况。 本文是基…

云计算如何助力金融科技企业实现高效运营

一、引言 随着信息技术的飞速发展,云计算作为一种新兴的计算模式,正在逐渐改变着传统金融行业的运营模式。金融科技企业作为金融行业的重要组成部分,面临着日益增长的业务需求和技术挑战。在这一背景下,云计算凭借其弹性扩展、高可用性、低成本等优势,成为金融科技企业实…

VisualSVN Server/TortoiseSVN更改端口号

文章目录 概述VisualSVN Server端更改端口号TortoiseSVN客户端更改远程仓库地址 概述 Subversion&#xff08;SVN&#xff09;是常用的版本管理系统之一。部署在服务器上的SVN Server端通常会在端口号80&#xff0c;或者端口号443上提供服务。其中80是HTTP访问方式的默认端口。…

SSM牙科诊所管理系统-计算机毕业设计源码98077

目 录 摘要 1 绪论 1.1研究目的与意义 1.2国内外研究现状 1.3ssm框架介绍 1.4论文结构与章节安排 2 牙科诊所管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能…

制作ChatPDF之后端Node搭建(三)

后端Node搭建 接上篇:制作ChatPDF之前端Vue搭建&#xff08;二&#xff09; 项目结构 下面是项目的结构图&#xff0c;包括前端 (Vue.js) 和后端 (Node.js) 的项目结构。 pdf-query-app/ ├── frontend/ │ ├── public/ │ │ ├── index.html │ ├── sr…

Python3 match-case 语句

前言 本文主要介绍match-case语句与switch-case的区别&#xff0c;及match-case语句的基本用法。 文章目录 前言一、switch-case 和match-case的区别二、match-case的基本用法1、可匹配的数据类型2、多条件匹配3、通配符匹配 一、switch-case 和match-case的区别 C语言里面s…

C++20实战之channel

C20实战之channel 继前面两节的直播&#xff0c;讲解了thread、jthread、stop_token、stop_source、stop_callback、cv、cv_any等的用法与底层实现&#xff0c;那么如何基于这些知识实现一个小项目呢&#xff1f; 于是引出了这篇&#xff0c;写一个channel出来。 注&#xff1a…

Python-算法编程100例-双指针(入门级)

1、盛水最多的容器 from typing import Listclass Solution:def maxArea(self, height: List[int]) -> int:# 双指针初始化l 0r len(height) - 1max_area 0# 循环终止条件while l < r:# 指针调整条件if height[l] < height[r]:# 指针调整前计算中间值max_area max…

FreeRTOS基础(四):静态创建任务

上一篇博客&#xff0c;我们讲解了FreeRTOS中如何动态创建任务&#xff0c;那么这一讲&#xff0c;我们从实战出发&#xff0c;规范我们在FreeRTOS下的编码风格&#xff0c;掌握静态创建任务的编码风格&#xff0c;达到实战应用&#xff01; 目录 一、空闲任务和空闲任务钩子…

决定短视频打开率的要素:成都鼎茂宏升文化传媒公司

​ 在当下这个短视频盛行的时代&#xff0c;无论是个人创作者还是企业品牌&#xff0c;都希望通过短视频平台获得更多的曝光和关注。然而&#xff0c;如何让自己的短视频在众多内容中脱颖而出&#xff0c;吸引用户的点击和观看&#xff0c;成为了摆在我们面前的重要问题。成都…

【爬虫工具】油管视频批量采集软件

一、背景介绍 1.1 爬取目标 我用Python独立开发了一款爬虫软件&#xff0c;作用是&#xff1a;通过搜索关键词采集ytb的搜索结果&#xff0c;包含14个关键字段&#xff1a;关键词,页码,视频标题,视频id,视频链接,发布时间,视频时长,频道名称,频道id,频道链接,播放数,点赞数,评…

开源模型应用落地-LangSmith试炼-入门初体验-监控和自动化(五)

一、前言 在许多应用程序中&#xff0c;特别是在大型语言模型(LLM)应用程序中&#xff0c;收集用户反馈以了解应用程序在实际场景中的表现是非常重要的。 LangSmith可以轻松地将用户反馈附加到跟踪数据中。通常最好提供一个简单的机制(如赞成和反对按钮)来收集用户对应用程序响…

工控一体机5寸显示器电容触摸屏(YA05WK)产品规格说明书

如果您对工控一体机有任何疑问或需求&#xff0c;或者对如何集成工控一体机到您的业务感兴趣&#xff0c;可移步控芯捷科技。 一、硬件功能介绍 YA05WK是我公司推出的一款新型安卓屏&#xff0c;4核Cortex-A7 架构&#xff0c;主频1.2GHz的CPU。采用12V供电&#xff0c;标配5寸…

使用QT生成二维码的两种方式

目录 使用QRenCode生成二维码编译生成QRenCode库使用QRenCode结果演示优缺点&#xff1a; 使用QZXing进行二维码的编码和解码编译源码使用QZXing库运行结果优缺点 使用QRenCode生成二维码 编译生成QRenCode库 QRenCode开源库 下载好之后使用cmake-gui打开进行构建生成。 点击…

mathtype7.0产品密钥及2024最新软件激活教程步骤

在数字化教育日益普及的今天&#xff0c;如何有效利用技术工具来提高数学学习的效率和质量&#xff0c;成为了教育工作者和学生共同关注的热点。特别是在处理复杂的数学公式、符号以及方程式时&#xff0c;传统的输入方式往往费时费力&#xff0c;且容易出错。为此&#xff0c;…

如何用python做一个用户登录界面——浔川python社

1 需解决的问题&#xff1a; 1.1如何用python做一个用户登录界面&#xff1f; 1.2需要用到哪些库、模块&#xff1f; 2 问题解决&#xff1a; 2.1 回答 1.1 &#xff1a;合理即可&#xff0c;无标准回答。 2.2 回答 1.2 &#xff1a;tk库&#xff08;缩写&#xff09;、GUL界面…

redis基础学习

redis是一个键值对类型的NoSql类型的数据库。 NoSql&#xff08;Non-relational SQL的缩写&#xff0c;也有人看作是not only sql的缩写&#xff09;型数据库&#xff0c;具有以下特征&#xff1a; 1、非结构化&#xff1a;几乎没有约束&#xff0c;约束很少&#xff0c;这要看…

【LLM】两篇多模态LLM综述MultiModal Large Language Models

note &#xff08;一&#xff09;现有的 MM-LLM 的趋势&#xff1a; (1)从专门强调 MM 理解对特定模态的生成的进展&#xff0c;并进一步演变为任何到任何模态的转换&#xff08;例如&#xff0c;MiniGPT-4 → MiniGPT-5 → NExT-GPT&#xff09;&#xff1b; (2) 从 MM PT 提…