MyBatis实现数据库的CRUD

news2025/1/15 19:54:49

本文主要讲解使用MyBatis框架快速实现数据库中最常用的操作——CRUD。本文讲解的SQL语句都是MyBatis基于注解的方式定义的,相对简单。

Mybatis中#占位符和$拼接符的区别

“#”占位符

在使用MyBatis操作数据库的时候,可以直接使用如下SQL语句删除一条数据:

    @Delete("delete from user where id=5")
    public Integer deleteById();

这条SQL语句可以成功删除user表中id为5的用户,但是存在一个问题:硬编码。这条用于删除数据的SQL将删除的条件写死了只能删除id为5的用户,但假如说下一次需要删除id为6的用户就必须重新编写一条SQL,即使这两条SQL语句只是条件略有差别。这样不但会增加我们编码的工作,还会降低数据库的执行效率。为了解决这个问题,我们可以使用#占位符代替条件:

    @Delete("delete from user where id=#{id}")
    public Integer deleteById(Integer id);

使用#占位符,在SQL语句的删除条件中进行占位,这样编写SQL语句之后,就需要给deleteById方法传递需要删除的用户的id,在程序编译时,就会将这条SQL语句编译为一条预编译SQL

delete from user where id=?

然后再用方法中传递的参数id去对预编译SQL中的?进行参数绑定(将Java方法中的参数SQL语句中的占位符建立关联并赋值的操作),从而避免硬编码的问题,并且还可以提高SQL语句的执行效率。预编译SQL的好处此处不再赘述,有关预编译SQL的详情可以参考这篇文章:预编译SQL- 掘金。

“$”拼接符

和#占位符不同,$只是拼接符,是直接将参数值拼接在SQL中,并不能使SQL语句变成预编译SQL,所以说就算使用$拼接符可以解决SQL语句硬编码问题,但是还是存在SQL注入问题性能低下的问题(预编译SQL可以解决这些问题),所以说$拼接符使用十分少。但是当SQL语句中的表名和字段名需要动态变化的时候,就只能使用$拼接符,如:

select * from ${tablename}

这种动态的表名会使用$拼接符

Create

CRUD中的“C”操作是指create,create操作是在数据库中新增一条数据,通过MyBatis中的@Insert注解可以便捷的新增数据。当进行数据新增操作时,往往会涉及多个不同类型的属性。从数据组织和管理的角度出发,为了更好地维护数据的完整性和关联性,更方便的使用数据;通常会将这些相关属性封装为一个实体对象。这种实体对象的设计遵循面向对象编程的原则,以业务逻辑中的实际实体为蓝本,例如在用户管理系统中,用户相关的属性(如用户名、密码、姓名、年龄等)会被封装在一个User实体对象中。这个实体对象会作为参数传递给负责新增数据的方法,SQL中的占位符会获取对象中的属性来进行参数绑定

    @Insert("insert into user(id, username, password, name, age) " +
            "values (#{id}, #{username}, #{password}, #{name}, #{age})")
    public Integer insertUser(User user);

SQL语句中values中的值就是User对象中的属性,是#占位符从User对象中的属性中获取的。获取细节本文不做细究,但是#占位符中的参数和User对象属性建议相同(便于参数绑定)。

测试该方法:

    @Test
    public void testInsert() {
        User user = new User(null, "zhouyu", "123456", "周瑜", 23);
        Integer rows = userMapper.insertUser(user);
        System.out.println("影响的行数是:" + rows);
    }

(因为id字段是主键,并且自增,所以说不需要传递id的参数。)

原数据表:

测试结果:

如图所示,新增用户方法insertUser成功在数据库表中插入(新增)了一条新的用户数据,观察数据库表和返回值(影响的行数)可以发现新增方法成功了。

需要说明的是:用户的id是自增的,前面自测的时候创建了很多user,所以说id自增到了10,虽然删除了这些user,但是id也是从10开始自增的,所以说再次添加user,id从10自增,则变成11。

Read

CRUD中的“R”操作是指read,read操作是查询(读取)数据库中的数据,通过MyBatis中的@Select注解可以便捷的完成数据的查询:

    @Select("select * from user where username = #{username} and password = #{password}")
    public void selectUser(@Param("username")String username, @Param("password")String password);

此处的查询条件只有两个usernamepassword),只涉及到了两个字段(属性),所以说没有必要将属性封装到User对象中传递,可以直接传递;但是需要非常注意的是此处传递的是参数名#占位符绑定的也是参数名,但是在编译后方法形参列表中的参数名不会保留,只会保留参数的类型,而#占位符参数绑定是在编译后进行的,此时方法形参列表中有两个参数(此时只有类型了),#占位符无法根据参数名进行准确绑定,所以说就会报错。为了解决这个问题,需要在方法的形参之前添加@Param注解指定该参数的名字#占位符中也需要使用和@Param注解中相同的名字(不一定需要和形参名字一样,只需要和@Param注解中的名字一样即可),这样才可以正确参数绑定。但使用官方的SpringBoot框架,无需使用@Param注解,只要保证#占位符中的参数和方法的形参名相同即可,也可以完成参数绑定。(所以说建议#占位符中参数和实体类的属性名相同)。

测试方法:

    @Test
    public void testFind() {
        User user = userMapper.selectUser("liubei", "123456");
        System.out.println(user);
    }

 如图所示,根据usernamepassword成功查询到了对应的用户信息,并封装为了User实体对象,说明查找方法selectUser成功。

Update

CRUD的“U”是指update,update操作是更新数据库中的数据,通过MyBatis中的@Update注解可以便捷的完成数据的更新:

    @Update("update user set username=#{username}, password=#{password}, name=#{name}, age=#{age} where id=#{id}")
    public Integer updateUser(User user);

insert操作类似,由于需要更新的字段比较多,所以说需要将要更新的字段封装为对应实体对象,然后通过#占位符获取对象的属性,完成SQL语句的参数绑定需要注意的是,在insert操作中,因为用户的id是自增的,所以说不需要传递id属性,但是在update操作中,绝大部分情况都是需要根据id属性寻找需要更新的数据,大多数时候是需要传递id属性的,但是也需要根据具体情况而定。

测试方法:

    @Test
    public void testUpdate() {
        User user = new User(1, "liubei", "123456", "刘备", 25);
        Integer rows = userMapper.updateUser(user);
        System.out.println("影响的行数是:" + rows);
    }

测试前数据表:

测试结果:

如图所示,运行updateUser方法之后,发现id为1的用户被修改为了刘备,说明该修改方法成功修改了用户数据。

Delete

CRUD的“U”是指delete,delete操作是删除数据库中的数据,通过MyBatis中的@Delete注解可以便捷的完成数据的删除:

    @Delete("delete from user where id=#{id}")
    public Integer deleteById(Integer id);

在MyBatis中执行所有的DML语句都是有返回值的,是int类型,代表这条语句影响的记录数,通过测试方法来测试下这个删除方法:

原数据表:

测试方法:

    @Test
    public void testDelete() {
        Integer rows = userMapper.deleteById(5);
        System.out.println("影响的行数是:" + rows);
    }

我们看到#占位符确实将SQL语句变成了一条预编译SQL,并且这条SQL影响了一条记录。看看数据库中的变化: 

id为5的记录确实被删除了,说明deleteUser方法成功运行,从数据库中删除了一个用户。

总结

CRUD是数据库中的基本操作,是必须要会的技能,通过MyBatis框架,我们可以十分便捷的操作数据库,完成CRUD操作。

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

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

相关文章

Spring Boot 下的Swagger 3.0 与 Swagger 2.0 的详细对比

先说结论: Swgger 3.0 与Swagger 2.0 区别很大,Swagger3.0用了最新的注释实现更强大的功能,同时使得代码更优雅。 就个人而言,如果新项目推荐使用Swgger 3.0,对于工具而言新的一定比旧的好;对接于旧项目原…

关于2025年智能化招聘管理系统平台发展趋势

2025年,招聘管理领域正站在变革的十字路口,全新的技术浪潮与不断变化的职场生态相互碰撞,促使招聘管理系统成为重塑企业人才战略的关键力量。智能化招聘管理系统平台在这一背景下迅速崛起,其发展趋势不仅影响企业的招聘效率与质量…

go语言的sdk 适合用go原生还是gozero框架开发的判断与总结

在决定是否使用 Go 原生(纯 Go)开发,还是使用 GoZero 框架开发时,主要取决于项目的需求、规模和开发的复杂性。GoZero 框架提供了一些额外的功能,如微服务架构、RPC 支持、API 网关、任务调度等,这些是基于…

Elasticsearch 批量导入数据(_bluk方法)

官方API&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html 建议先看API POST /<索引名>/_bulk 格式要求&#xff1a; POST _bulk { "index" : { "_index" : "test", "_id" : &q…

Mysql--重点篇--索引(索引分类,Hash和B-tree索引,聚簇和非聚簇索引,回表查询,覆盖索引,索引工作原理,索引失效,索引创建原则等)

索引是数据库中用于加速查询操作的重要机制。通过索引&#xff0c;MySQL可以快速定位到满足查询条件的数据行&#xff0c;而不需要扫描整个表。合理的索引设计可以显著提高查询性能&#xff0c;但不合理的索引可能会导致性能下降和磁盘空间浪费。因此&#xff0c;理解索引的工作…

mybatis-spring @MapperScan走读分析

接上一篇文章&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145100531&#xff0c; 本文注解分析mybatis-spring中的MapperScan注解&#xff0c;则将容易许多。 目录 MapperScan注解定义ConfigurationClassPostProcessor扫描注册beanDefinitionorg.mybatis.s…

【STM32】HAL库USB实现软件升级DFU的功能操作及配置

【STM32】HAL库USB实现软件升级DFU的功能操作及配置 文章目录 DFUHAL库的DFU配置修改代码添加条件判断和跳转代码段DFU烧录附录&#xff1a;Cortex-M架构的SysTick系统定时器精准延时和MCU位带操作SysTick系统定时器精准延时延时函数阻塞延时非阻塞延时 位带操作位带代码位带宏…

计算机视觉算法实战——实时车辆检测和分类(主页有相关源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​​​​​​​​​​​​​​​​ 1. 领域介绍✨✨ 实时车辆检测和分类是计算机视觉中的一个重要应用领域&#xff0c;旨在从视频流或…

机器学习(1):线性回归概念

1 线性回归基础 1.1 什么是线性 例如&#xff1a;汽车每小时60KM&#xff0c;3小时可以行使多长距离&#xff1f;已知汽车的速度&#xff0c;则汽车的行使距离只与时间唯一相关。在二元的直角坐标系中&#xff0c;描出这一关系的图是一条直线&#xff0c;所以称为线性关系。 线…

ThinkPHP 8的一对一关联

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 编程与应用开…

探索图像编辑的无限可能——Adobe Photoshop全解析

文章目录 前言一、PS的历史二、PS的应用场景三、PS的功能及工具用法四、图层的概念五、调整与滤镜六、创建蒙版七、绘制形状与路径八、实战练习结语 前言 在当今数字化的世界里&#xff0c;视觉内容无处不在&#xff0c;而创建和编辑这些内容的能力已经成为许多行业的核心技能…

LabVIEW开发X光图像的边缘检测

在医疗影像处理中&#xff0c;X光图像的分析对于骨折、肿瘤等病变的检测非常重要。X光图像中包含许多关键信息&#xff0c;然而&#xff0c;由于图像噪声的干扰&#xff0c;直接从图像中提取有用的特征&#xff08;如骨折的边缘&#xff09;变得非常困难。边缘检测作为图像处理…

SOLID原则学习,接口隔离原则(Interface Segregation Principle, ISP)

文章目录 1. 定义2. 为什么要遵循接口隔离原则&#xff1f;3. 违反接口隔离原则的例子4. 遵循接口隔离原则的改进5. 总结 1. 定义 接口隔离原则&#xff08;Interface Segregation Principle, ISP&#xff09; 接口隔离原则是面向对象设计中的五大原则&#xff08;SOLID&#…

浅谈云计算12 | KVM虚拟化技术

KVM虚拟化技术 一、KVM虚拟化技术基础1.1 KVM虚拟化技术简介1.2 KVM虚拟化技术架构1.2.1 KVM内核模块1.2.2 用户空间工具&#xff08;QEMU、Libvirt等&#xff09; 二、KVM虚拟化技术原理2.1 硬件辅助虚拟化2.2 VMCS结构与工作机制 三、KVM虚拟化技术面临的挑战与应对策略3.1 性…

unity如何在urp管线下合并spine的渲染批次

对于导入unity的spine来说,他会对每个spine生成独有的材质,虽然他们使用的是同一个shader,但由于附带独有的贴图,这样在项目使用中会由于材质贴图不同而导致无法合批. 而为什么选用urp,因为在built-in管线中,对于GPU-instancing,即使通过使用图集的方式统一了贴图,也会由于spi…

list的迭代器模拟实现和迭代器失效(续)

文章目录 list的迭代器operator->普通迭代器和const迭代器迭代器模版迭代器失效析构拷贝构造赋值重载 initializer_list list的迭代器 对迭代器进行封装&#xff0c;迭代器的指针还是4个字节&#xff0c;在物理上是一样的&#xff0c;但是底层是完全不同的 迭代器是浅拷贝&a…

一文通透OpenVLA及其源码剖析——基于Prismatic VLM(SigLIP、DinoV2、Llama 2)及离散化动作预测

前言 当对机器人动作策略的预测越来越成熟稳定之后(比如ACT、比如扩散策略diffusion policy)&#xff0c;为了让机器人可以拥有更好的泛化能力&#xff0c;比较典型的途径之一便是基于预训练过的大语言模型中的广泛知识&#xff0c;然后加一个policy head(当然&#xff0c;一开…

Easysearch Rollup 使用指南

背景 在现代数据驱动的世界中&#xff0c;时序数据的处理变得越来越重要。无论是监控系统、日志分析&#xff0c;还是物联网设备的数据收集&#xff0c;时序数据都占据了大量的存储空间。随着时间的推移&#xff0c;这些数据的存储成本和管理复杂度也在不断增加。 为了解决这…

FPGA EDA软件的位流验证

位流验证&#xff0c;对于芯片研发是一个非常重要的测试手段&#xff0c;对于纯软件开发人员&#xff0c;最难理解的就是位流验证。在FPGA芯片研发中&#xff0c;位流验证是在做什么&#xff0c;在哪些阶段需要做位流验证&#xff0c;如何做&#xff1f;都是问题。 我们先整体的…

[免费]SpringBoot+Vue新能源汽车充电桩管理系统【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue新能源汽车充电桩管理系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue新能源汽车充电桩管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 随着信息化时代的到来&#xff0…