当前位置: 首页 > news >正文

Mybatis操作数据库

本节目标

目标
1.学习Mybatis的动态SQL查询
2.掌握在项目中的应用,可以使用SpringMVC 完成一些基础功能


文章目录

  • 本节目标
  • 前言
  • 一、动态SQL是什么?
  • 二、准备工作
    • 1.配置相关信息
    • 2.创建实体类,Mapper接口,XMl文件
  • 三、标签
    • 1.< if > 标签
    • 2.< trim >标签
    • 3.< where >标签
    • 4< set >标签
    • 5< foreach >标签
  • 四.# 和$ 的区别
    • ${}使用的场景
  • 总结


前言

动态SQL
动态SQL是Mybatis强大特性之一,能够完成不同条件下的不同sql拼接,
可以参考官方文档:Mybatis动态sql


提示:以下是本篇文章正文内容,下面案例可供参考

一、动态SQL是什么?

动态SQL是MyBatis强大特性之一,如果你使用过JDBC或其他类似的框架,你应该能理解根据不同条件拼接SQL语句有多痛苦,例如,拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号,利用动态SQL,可以彻底摆脱这种痛苦
利用动态SQL并非是一件易事,但借助可用于任何SQL映射语句中强大的动态SQL语言,MyBatis显著的提升了这一特性的易用性

二、准备工作

1.配置相关信息

一.连接数据库

注意确认数据库名称,和密码

spring:	
  application:
    name: mybatis
#数据库连接配置
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: liusan11
    driver-class-name: com.mysql.cj.jdbc.Driver

二.配置MyBatis xml 的文件路径

保证路径与xml文件一致

mybatis:
  mapper-locations: classpath:mapper/**Mapper.xml #配置Mybatis Xml的文件路径,在resource/mapper下创建所有表的xml文件

三.配置日志,驼峰命名(根据需求)

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印日志
    map-underscore-to-camel-case: true #配置驼峰自动转换

2.创建实体类,Mapper接口,XMl文件

回归主题,Mybatis的作用是管理数据的信息,如何通过后端进行读取数据,或对数据进行一些操作呢,并且采用动态SQL的方式 ,这不得不需要使用XML来完成接口的实验了

配置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.sponge.mapper.UserInfoXmlMapper">
#注意路径要和Mapper接口保持一致

</mapper>

创建实体类

@Data
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

数据库
在这里插入图片描述

所有工作准备完毕了!!!

三、标签

1.< if > 标签

代码如下(示例):
向数据库添加数据,通过字段名 username,password,gender,age进行添加

有时候这几个字段不是非必要字段,可不填

  <insert id="insertUserInfo">
        insert into user_info
            <trim prefix="(" suffix=")" suffixOverrides=",">
                <if test="username!=null">
                    username,
                </if>
                <if test="password!=null">
                    password,
                </if>
                <if test="gender!=null">
                    gender,
                </if>
                <if test="age!=null">
                    age,
                </if>
            </trim>

        values
            <trim prefix="(" suffix=")" suffixOverrides=",">
                <if test="username!=null">
                    #{username},
                </if>
                <if test="password!=null">
                    #{password},
                </if>
                <if test="gender!=null">
                    #{gender},
                </if>
                <if test="age!=null">
                    #{age},
                </if>
            </trim>
    </insert>

判断sql每个字段是否为空 ,为空就不传!

2.< trim >标签

如上述代码
此标签可用于去除多余的“ ,”,
属性
1.prefix : 加上 ”什么” 的前缀
2.suffix :加上“什么”的后缀
3.prefixOverrides:去掉“什么”的前缀
4.suffixOverrides:去掉“什么”的后缀

3.< where >标签

查询age = 18 并且 delete_flag = 0的数据

  <select id="selectUserInfo" resultType="com.sponge.demo.model.UserInfo">
        select * from user_info where
           <if test="age!=null">
               age = 14 and
           </if>
           <if test="deleteFlag!=null">
               delete_flag = 0
           </if>

    </select>

在这里插入图片描述

使用if标签进行搭配 , 依然是判断字段是否有值而进行传递。
如上图Test方法 所示 , 查询结果是没问题的
现如果我们传 去一个空的userinfo ,而不对age 和deletFlag 赋值 ,则此时的sql语句为
select * from user_info where 导致多了一个 where 会出错,因此使用where标签可以判断后面字段名是否存在而选择性去掉where,可以防止出错
另外,如果仅给userinfo赋值一个age ,此时sql语句为 ==select * from user_info where age = 14 and == 导致多了一个and 会出错 此时可以加上trim标签 进行去除,同样可以使用where标签进行选择性管理 因此 where标签是一个不二的选择

终上所述,where标签的作用是 :选择性的去掉 where 和 and

   <select id="selectUserInfo" resultType="com.sponge.demo.model.UserInfo">
        select * from user_info 
            
            <where>
        <if test="age!=null">
            age = 14 and
        </if>
        <if test="deleteFlag!=null">
            delete_flag = 0
        </if>
            </where>
          

    </select>

4< set >标签

修改操作:通过id修改username ,password,gender

   <update id="updateUserInfo">
        update user_info 
        <set>
        <if test="username!=null">
            usernamm = #{username},
        </if>
        <if test="password!=null">
            password = #{password},
        </if>
        <if test="gender!=null">
            gender=#{gender}
        </if>
        where id = #{id}
         </set>
                
    </update>

同样的,如果 字段都为空,仅id 有值 ,那么sql语句就是update user_info set where id = ? 会导致多了一个
set 而出错 , 加上set 能解决吗?不能 , 因为这是更新语句 ,修改 , 就必须要使用set , 而set标签的作用在于可以去除 多余的“ ,”,这个问题也可以使用 trim 标签进行解决。
因此 set 标签的作用:仅 可以 去掉 多余的 “,” 相当于去掉了trim标签

5< foreach >标签

遍历,进行批量的操作,通过拼接的构成来构造sql

删除id 为 12,13 15 的数据

 <delete id="deleteUserInfo">
        delete from user_info where id in
        <foreach collection="ids" separator="," close=")" open="(" item="id">
            #{id}
        </foreach>
    </delete>

在这里插入图片描述

属性
1.collection : 参数集合名称
2.item:每一项的名称
3.separator:以什么分割
4.open: 以什么开始
5.close: 以什么结束

四.# 和$ 的区别

例1,通过ID查询用户信息
#{}
在这里插入图片描述
在这里插入图片描述
${} 在这里插入图片描述
在这里插入图片描述

例2 ,通过用户名(username)查询用户信息
#{}
在这里插入图片描述
在这里插入图片描述
${}
在这里插入图片描述
在这里插入图片描述

结果显示,使用${} 来传递 username(String)的字段 ,会出现SQl出错

原因是username是字符串类型,在进行判断时候 应该 写username = “admin” 需要加上双引号 , 而$ {} 是直接替换的 相当与直接把 admin 传上去就没有“”。
解决办法:手动加上‘’ 就可以变为字符串类型
在这里插入图片描述

在这里插入图片描述
根据上面不同的差异可以看出,
● #{} 是预编译SQL ,用"?"占位的方式提前对SQL进行编译 ,再把参数填充到SQL语句中,而且会根据参数类型,自动拼接引号‘’
● ${} 是即时SQL ,直接替换 ,不做任何处理

1.性能更高
绝大多数情况下,某一条SQl语句可能被反复调用执行,或者每次执行的时候只有个别的值不同(比如select的where子句值不同,upset的set子句值不同,insert的values的值不同,如果每次都需要上面的语法解析,SQL优化,SQL编译等,效率就明显不行了)
在这里插入图片描述
预编译SQL,编译一次后将编译后的SQL语句缓存起来,后面再次执行这条语句时,不会再次编译(只是输入的参数不同),省去了解析优化的过程来提高效率
2更安全,防止SQL注入
SQL注入:是通过操作输入的数据来修改实现定义好的SQL语句,以达到执行代码对服务器进行攻击的方法
由于没有对用户输入进行充分检查,而SQL又是拼接而成,在用户输入参数时,在参数添加一些SQL关键字,达到SQL运行结果的目的,
sql注入代码:‘ or 1 = '1就会导致数据库漏洞,查询的数据不是自己想要的数据,所以用于查询的字段,尽量使用#{}预查询的方式

${}使用的场景

1.排序功能
在这里插入图片描述
报错原因 使用#{sort } 表示 升序还是降序 ,但是报错 ,原因是# 会对已有的参数进行处理,若是字符串类型 会自动加上“” ,若是int 类型 不变
使用$后
在这里插入图片描述
因此 ${sort } 可以实现排序功能,而#{sort} 就不能实现排序功能
2.like查询

like使用#{}报错,而使用${} 存在SQL注入问题,因此使用mysql的内置函数 concat()处理

在这里插入图片描述

总结

以上就是我们动态Mysql的知识

http://www.dtcms.com/a/122440.html

相关文章:

  • 8. git branch
  • spring mvc 异常处理中@RestControllerAdvice 和 @ControllerAdvice 对比详解
  • Linux服务器——Samba服务器
  • 【C++编程基础-关键字】:constexpr和const
  • Vue3服务端渲染实战:Nuxt3深度解析与高性能SSR架构设计
  • vLLM实战:多机多卡大模型分布式推理部署全流程指南
  • 深入探究Python的re模块及其在爬虫中的应用
  • 界面控件DevExpress WPF v25.1新功能预览 - 数据网格、报表性能增强
  • [特殊字符] Hyperlane:Rust 高性能 HTTP 服务器库,开启 Web 服务新纪元!
  • ARM裸机全集学习笔记【链接来源:向阳而生,逆风翻盘】
  • 智能家居设备
  • Ansible(5)——编写 Playbook
  • SpringMVC的请求-文件上传
  • 如何利用 Java 爬虫获取京东商品详情信息
  • scala总结与spark安装
  • 游戏引擎学习第213天
  • 【scikit-learn基础】--『预处理』之 正则化
  • JetBrains Terminal 又发布新架构,Android Studio 将再次迎来新终端
  • 21 天 Python 计划:MySQL中DML与权限管理
  • Java基础 4.9
  • 如何生成一个requestid
  • 地图服务热点追踪:创新赋能,领航出行与生活
  • Windows 下 Rust 安装全攻略(无需 Visual Studio)
  • 【力扣hot100题】(078)跳跃游戏Ⅱ
  • 用 npm list -g --depth=0 探索全局包的秘密 ✨
  • MySQL中使用索引一定有效吗?如何排查索引效果?
  • uniapp uni-collapse动态切换数据时高度不能自适应
  • 旅行世界宠物养殖合成游戏源码
  • SQL开发的智能助手:通义灵码在IntelliJ IDEA中的应用
  • 银河麒麟V10 Ollama+ShellGPT打造Shell AI助手——筑梦之路