使用标签实现MyBatis的基础操作

news2024/10/8 16:35:32

目录

前言

1.配置MyBatis⽇志打印

2.参数传递 

2.1 #{} 和 ${}区别

 2.2传递多个参数

 3.增删改查

3.1增(Insert)

3.2删(Delete)

3.3改(Update)

 3.4查(Select)


前言

 接下来我们会使用的数据表如下:

对应的实体类为:UserInfoMapper

所有的准备工作都在如下文章。

MyBatis 操作数据库入门-CSDN博客文章浏览阅读169次,点赞5次,收藏11次。什么是MyBatis?MyBatis是⼀款优秀的 持久层 框架,⽤于简化JDBC的开发Mybatis操作数据库的入门步骤:1.创建springboot⼯程2.数据库表准备、实体类3.引⼊Mybatis的相关依赖,配置Mybatis(数据库连接信息)4.编写SQL语句(注解/XML) ,进行测试了解更多MyBatis中文网1.创建springboot⼯程创建springboot⼯程,并导⼊ mybatis的起步依赖、mysql的驱动包。https://blog.csdn.net/WHabc2002/article/details/142743762

 


1.配置MyBatis⽇志打印

在Mybatis当中我们可以借助⽇志, 查看到sql语句的执⾏、执⾏传递的参数以及执⾏结果
在配置⽂件中进⾏配置即可

 如果是application.yml, 配置内容如下

mybatis:
  configuration: # 配置打印 MyBatis 执行的 SQL
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
如果是application.properties, 配置内容如下
#指定mybatis输出⽇志的位置, 输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

 打印形式如下:


2.参数传递 

 像select * from userinfo where id=4这种SQL语句已经写死,只能查找id=4 的数据。我们想要更加自由的使用SQL语句,我们就需要动态的数值。

解决⽅案:

将⽅法中的参数,传给SQL语句,使⽤ #{}或${} 的⽅式获取⽅法中的参数

2.1 #{} 和 ${}区别

1.预编译SQL和即时SQL 的区别

1.#{} 使⽤的是预编译SQL, 通过 ? 占位的⽅式, 提前对SQL进⾏编译, 然后把参数填充到SQL语句 中. #{} 会根据参数类型, ⾃动拼接引号 " "
2.${} 会直接进⾏字符替换, ⼀起对SQL进⾏编译. 如果参数为字符串, 需要加上引号 " "

 1.#{}

    @Select("select * from userinfo where username = #{userName}")
    public Userinfo getUserByName(String userName);

测试结果:

 2.${}

  @Select("select * from userinfo where username = '${userName}'")
    public Userinfo getUserByName2(String userName);

测试结果:

 2.#{}的效率更高

   绝⼤多数情况下, 某⼀条 SQL 语句可能会被反复调⽤执⾏, 或者每次执⾏的时候只有个别的值不同 如果每次都需要 经过1.语法解析, 2.SQL优化、3.SQL编译等,则效率就明显不⾏了。
   预编译SQL,编译⼀次之后会将编译后的SQL语句缓存起来,后⾯再次执⾏这条语句时,不会再次编译 (只是输⼊的参数不同), 省去了解析优化等过程, 以此来提⾼效率

3.#{}更安全(防⽌SQL注⼊) 

因为${} 会直接进⾏字符替换, ⼀起对SQL进⾏编译

SQL注⼊:

  是通过操作输⼊的数据来修改事先定义好的SQL语句,以达到执⾏代码对服务器进⾏攻击的 ⽅法。

 可以得出结论: ${} 会有SQL注⼊的⻛险, 所以我们尽量使⽤#{}完成查询

 既然如此, 是不是 ${} 就没有存在的必要性了呢?

当然不是,#{} 会根据参数类型, 如果参数类型为String,⾃动拼接引号 " ",当我们不想要⾃动拼接引号 " "时,我们选择${},但一旦使用了${},就一定要考虑SQL注入。

例子1:排序

使用 ${}时

    @Select("select * from userinfo order by id ${sort}")
    public List<Userinfo> queryAllUser2(String sort);

测试结果:

 

使用 #{}时

    @Select("select * from userinfo order by id #{sort}")
    public List<Userinfo> queryAllUser3(String sort);

测试结果:

 

2.like 查询 

 @Select("select * from userinfo where username like '%${key}%'")
    public List<Userinfo> queryAllUser3(String key);
#{}会SQL错误,但是${}存在SQL注⼊的问题, 所以不能直接使⽤ ${}
解决办法: 使⽤ mysql 的内置函数 concat() 来处理,实现代码如下:
@Select("select * from userinfo where username like concat('%',#{username},'%')")
    public List<Userinfo> queryAllUser4(String key);

 2.2传递多个参数

1.如果SQL语句中只有一个变量,变量名不需要与参数名对应。

2.如果SQL语句中有多个变量,变量名必需与参数名对应。

3.会自动生成对应参数比如param1自动对应函数的第一个参数。

    @Select("select * from userinfo where username = #{userName} and age = #{age}")
    public List<Userinfo> queryAllUser5(String userName1,int age);

测试结果:

也可以通过 @Param , 设置参数的别名, 如果使⽤ @Param 设置别名, #{...}⾥⾯的属性名必须和
@Param 设置的⼀样

 3.增删改查

3.1增(Insert)

    @Insert("insert into userinfo (username, password, age, gender) " +
            "values (#{username},#{password},#{age},#{gender})")
    Integer insert(Userinfo userinfo);

测试代码:

    @Test
    void insert() {
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("wh");
        userinfo.setPassword("123456");
        userinfo.setAge((byte) 18);
        userinfo.setGender((byte) 1);
        Integer insert = userInfoMapper.insert(userinfo);
        System.out.println(insert);
    }

结果:

 

注意:如果设置了 @Param 属性, #{...}对象就只能是一个整体需要使⽤ 参数.属性 来获取。

    @Insert("insert into userinfo (username, password, age, gender) " +
            "values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender})")
    Integer insert2(@Param("userinfo") Userinfo userinfo);
返回主键
如果想要拿到⾃增id, 需要在Mapper接⼝的⽅法上添加⼀个Options的注解
keyProperty:指定能够唯⼀识别对象的属性
    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into userinfo (username, password, age, gender) " +
            "values (#{username},#{password},#{age},#{gender})")
    Integer insert3(Userinfo userinfo);

测试代码:

    @Test
    void insert3() {
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("bbb");
        userinfo.setPassword("bbb");
        userinfo.setAge((byte) 18);
        userinfo.setGender((byte) 1);
        Integer insert = userInfoMapper.insert3(userinfo);
        System.out.println(userinfo.getId());
    }

3.2删(Delete)

@Delete("delete from userinfo where id = #{id}")
    Integer delete(Integer id);

3.3改(Update)

@Update("update userinfo set password = #{password} where id = #{id}")
    Integer update(UserInfo userInfo);

 3.4查(Select)

    @Select("select * from userinfo")
    public List<UserInfo> queryAllUser();

 测试结果:

原因; 

当⾃动映射查询结果时,MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性 

解决办法:

1.起别名

2.结果映射

 /**
     * 起别名
     * @return
     */
    @Select("SELECT id, username, password, age, gender, phone, " +
            "delete_flag as deleteFlag, create_time as createTime, update_time as updateTime " +
            "FROM `userinfo`")
    List<UserInfo> selectUserInfos();

    /**
     * 指定结果映射关系
     * @return
     */
    @Results(id ="resultMap" , value = {
            @Result(column = "delete_flag", property = "deleteFlag"),
            @Result(column = "create_time", property = "createTime"),
            @Result(column = "update_time", property = "updateTime")
    })
    @Select("SELECT * FROM `userinfo`")
    List<UserInfo> selectUserInfos2();

 3.开启驼峰命名(推荐)

通常数据库列使⽤蛇形命名法进⾏命名(下划线分割各个单词), ⽽ Java 属性⼀般遵循驼峰命名法约定. 为了在这两种命名⽅式之间启⽤⾃动映射,需要将 mapUnderscoreToCamelCase 设置为 true。
我们进行如下配置即可
以application.yml为例:
mybatis:
  configuration:
    map-underscore-to-camel-case: true  #自动驼峰转换

 


以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

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

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

相关文章

全局数据在Python包中模块间管理方法探讨

在开发大型 Python 应用程序时&#xff0c;有时需要多个模块共享和管理全局数据。如何优雅地在 Python 包内的不同模块间共享全局数据是一个常见的设计问题。我们希望避免全局变量的混乱和难以维护的代码&#xff0c;但同时能够安全、高效地管理这些共享数据。 下面我们将探讨…

低代码赋能汽车制造产业链场景系列

当前汽车行业数字化智能化转型浪潮下&#xff0c;整车及其上下游产业链的协同创新正变得至关重要。头部车企与上下游供应链企业正逐步解决在生产管理、业务互通、系统集成等方面的痛点与挑战。电动化、智能化、网联化作为汽车产业的三大趋势&#xff0c;正共同推动未来汽车产业…

MS SQL Server 实战 统计与汇总重复记录

目录 需求 范例运行环境 数据样本设计 功能实现 上传EXCEL文件到数据库 分组统计 SQL 语句 分组汇总 SQL 语句 having 语句过滤最终统计结果 小结 需求 在日常的数据管理应用中&#xff0c;统计和汇总重复记录的情况是经常遇到的一个问题&#xff0c;然后我们会根据统…

文字转语音软件哪个好?这里告诉你

在英语学习的众多环节中&#xff0c;听力练习无疑是至关重要的一环。 然而&#xff0c;平时缺乏英语环境&#xff0c;如何高效地利用身边的英语材料进行听力训练呢&#xff1f;这时&#xff0c;英语文字转语音工具就很重要了&#xff01; 今天&#xff0c;就为大家介绍五款优…

【C++】认识匿名对象

文章目录 目录 文章目录前言一、对匿名对象的解读二、匿名对象的对象类型三、匿名对象的使用总结 前言 在C中&#xff0c;匿名对象是指在没有呗命名的情况下创建的临时对象。它们通常在单个语句中执行一系列操作或调用某个函数&#xff0c;并且不需要将结果存放进变量中。 匿名…

常用动词敬语形式大揭秘,柯桥零基础日语培训

一、常用动词的敬语形式 1. する&#xff08;做&#xff09; • 尊敬语&#xff1a; なさる (Nasaru) 例&#xff1a;社長はよく運動をなさいます。 &#xff08;社长经常锻炼。&#xff09; • 谦逊语&#xff1a; いたす (Itasu) 例&#xff1a;この仕事は私がいたします。 &…

Java解析图形mdb矢量mdb

Java解析图形mdb矢量mdb 背景&#xff1a;项目中需要解析图形mdb&#xff0c;同事积累下的代码无法读取复杂图形&#xff1b;终于在某位大佬的博客下发现新的 解析方法&#xff0c;特此整理记录下。原理&#xff1a;jackcess&#xff08;assess提供解析mdb属性&#xff09;、es…

C++模拟实现二叉搜索树

目录 1.二叉搜索树的概念 2.二叉搜索树的性能分析 3.二叉搜索树的结构和中序遍历 3.1二叉搜索树中节点的结构 3.2二叉搜索树的结构 3.3中序遍历 4.二叉搜索树的插入 5.二叉搜索树的查找 6.二叉树搜索树的删除 7. 二叉搜索树的默认成员函数 8.参考代码 9.二叉搜…

常见的图像处理算法:Canny边缘检测

一、Canny边缘检测算子的由来 Canny 边缘检测算子是一种多级检测算法。1986 年由 John F. Canny 提出&#xff0c;同时提出 了边缘检测的三大准则&#xff1a; 1、低错误率的边缘检测&#xff1a;检测算法应该精确地找到图像中的尽可能多的边缘&#xff0c;尽可能的减少漏检…

【一起学Rust | 框架篇 | Tauri2.0框架】高级概念之安全特性的权限与能力

文章目录 前言一、开发前准备1. 准备项目2. 需求分析1. 监听系统热键2. 切换窗口无边框3. 切换窗口全屏 二、安装插件三、前端实现功能四、配置权限 前言 当前时间为 2024 年 9 月&#xff0c;距离Tauri 2.0 的 RC 版本发布迄今已近一个月。从 Tauri 官方渠道可以看出&#xf…

李飞飞:我不知道什么是AGI

图片来源&#xff1a;Stanford University 你对人工通用智能&#xff08;AGI&#xff09;感到困惑吗&#xff1f;这就是 OpenAI 执着于最终以“造福全人类”的方式创造的东西。你可能想认真对待他们&#xff0c;因为他们刚筹集了 66 亿美元以更接近这个目标。 但如果你仍然在…

揭秘Sui存储基金:灵活且可持续的链上数据管理解决方案

链上数据存储的方法常常被忽视&#xff0c;因为所使用的机制通常是传统和常见的。然而&#xff0c;在去中心化网络中&#xff0c;数据存储对确保数据完整性和长期可访问性至关重要。Sui的链上存储与其他区块链有所不同。 Sui存储基金是为了解决链上数据永久存储问题而设计的核…

企业架构系列(16)ArchiMate第14节:实施和迁移视角

在企业架构中&#xff0c;为了有效地规划和管理架构的变更与实施&#xff0c;通常会使用不同的视角来描述架构的不同方面。本篇涉及到三个主要视角&#xff1a;项目视角、迁移视角以及实施与迁移视角。 一、实施和迁移视角概览 1.项目视角 元素与关系&#xff1a;关注项目本身…

“网络安全等级保护测评入门:基础概念与重要性“

网络安全等级保护测评&#xff08;简称“等保测评”&#xff09;是依据国家网络安全等级保护制度&#xff0c;对信息系统安全等级进行评估和评定的过程。它是提高信息系统安全性、保障信息安全的重要手段。以下是关于等保测评的基础概念与重要性的详细解读&#xff1a; 一、等…

【钱拿不回来了,中介说开源吧】《刚体旋转的四元数模型及捷联惯性导航系统中定向算法》

《刚体旋转的四元数模型及捷联惯性导航系统中定向算法》 1. 摘要 本文深入探讨了四元数在刚体旋转描述中的核心作用以及其在捷联惯性导航系统&#xff08;SINS&#xff09;中确定方向的算法。详细阐述了四元数的理论基础、数学性质和实际应用优势&#xff0c;包括与卡丹角和欧…

小红书AI商单变现,单月收入10000+,真猛!

AI相关的话题在这两年来一直很火爆&#xff0c;很多行业也纷纷和AI结合起来&#xff0c; 从而达到更好的变现效果&#xff0c;这也是未来的发展趋势&#xff0c; 有这个工具确实能给我们的工作和生活带来一些便利 之前也拆解过很多类似的玩法&#xff0c; 比如AI古诗词、数…

软件测试之压力测试

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 压力测试 压力测试是一种软件测试&#xff0c;用于验证软件应用程序的稳定性和可靠性。压力测试的目标是在极其沉重的负载条件下测量软件的健壮性和错误处理能力&…

GSLAM——一个通用的SLAM架构和基准

GSLAM: A General SLAM Framework and Benchmark 开源地址 摘要&#xff1a; SLAM技术最近取得了许多成功&#xff0c;并吸引了高科技公司的关注。然而&#xff0c;如何同一现有或新兴算法的界面&#xff0c;一级有效地进行关于速度、稳健性和可移植性的基准测试仍然是问题。本…

芯片干货 | 同步内置MOS升压恒压5V/2A芯片FP6276B,输入限流可调

芯片概述 FP6276B是一个具有PWM/PSM控制的电流模式增压直流-直流转换器。它的PWM电路内置40mΩ高侧开关和40mΩ低侧开关使该调节器高高效。内部补偿网络还将外部组件计数最小化到只有6个。一个内部的0.6V电压被连接到误差放大器的非反相输入作为精度参考电压。内置的软启动功能…

Llama 3.2 智能代理开发教程

构建研究代理可能很复杂&#xff0c;但使用 LangChain 和 Ollama&#xff0c;它会变得更加简单和模块化。 在本教程中&#xff0c;我们将向你展示如何基于Llama 3.2创建一个研究代理&#xff0c;该代理可以路由查询、执行网络搜索并使用工作流和 LLM 的组合生成详细响应。最后…