Mybatis基础操作

news2024/12/26 11:04:07

在这里插入图片描述

文章目录

  • 一. Mybatis单表操作
    • 删除操作
    • 查询操作
    • #{} 与 ${}的区别
    • 更新操作
    • 新增操作
  • 二. Mybatis多表操作

一. Mybatis单表操作

删除操作

在这里插入图片描述
我们接着使用昨天的表和程序,我们来实现通过id删除数据:
在这里插入图片描述
我们这样就可以实现将id = 1的数据进行删除了,但是这样有什么问题呢?这样把代码写死了,所以我们需要动态的接收id来进行删除。
这里介绍两种MyBatis获取参数的两种实现:
1.#{} 占位符替换
2.${} 字符串拼接
这会我们先用,后面给大家讲解区别

// 注解方式
@Delete("delete from userinfo where id = #{id}}")
    int deleteById(Integer id);

xml方式:
在这里插入图片描述
我们来测试一下结果,但是我们并不想真正的进行落盘操作,所以我们在执行方法时开启事务:
在这里插入图片描述
在这里插入图片描述
但是我们目前并不能看到Mybatis底层到底执行了什么样的sql语句,我们其实可以借助Mybatis的日志看到的,但是默认是关闭的,我们需要手动开启。
在yml配置文件配置以下信息:

# 配置mybatis的日志,指定输出到控制台
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

再次执行test,我们发现不仅打印了sql信息,而且还显示了我们在Test中执行完毕进行Rolled back
在这里插入图片描述

查询操作

根据id查询员工信息
在这里插入图片描述

<select id="getById" resultType="com.example.demo.entity.User">
        select * from userinfo where id = #{id}
</select>

在这里插入图片描述

在这里插入图片描述

这里大家需要注意一件事:
当我们进行查询操作时,会进行数据库信息到实体对象是数据封装,这里分为两种情况:
1.实体类属性名和数据库查询返回的字段名一致,mybatis会自动进行封装
2.如果实体类属性名和数据库查询返回的字段名不一致,则不能自动封装,会出现null值的情况
在这里插入图片描述
因为我们这里是一致的所以没有出现空的情况,我们来将数据库字段名改一下再来试一下。
在这里插入图片描述
在这里插入图片描述
我们发现当我们实体类属性名和数据库查询返回的字段名不一致,则不能自动封装,那么如何进行封装呢? 有以下三种方案:
1.起别名: 在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样

<select id="getById" resultType="com.example.demo.entity.User">
        select id,username,password,photo,create_time createTime,updatetime,state
        from userinfo where id = #{id}
</select>

在这里插入图片描述

2.开启驼峰命名: 如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰映射规则

# 开启驼峰命名自动映射,从数据库字段名create_time映射到属性名createTime
mybatis:
  configuration:
    map-underscore-to-camel-case: true

在这里插入图片描述
3.返回字典映射:resultMap 字段名称和程序中属性名不同时,可使用resultMap配置映射

<resultMap id="usermap" type="com.example.demo.entity.User">
        <id column="id" property="id"></id>
        <result column="create_time" property="createTime"></result>
</resultMap>

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

如果我们要进行条件查询呢?
在这里插入图片描述
我们先使用sql写一下我们需要查询的sql:

select * from userinfo where username like '%张%' and updatetime between 2023-05-12 11:09:01 and 2023-05-12 11:09:01 order by desc;

在这里插入图片描述

在这里插入图片描述
但是我们的#{}是不能出现在’'之内的,因为我们的#{}生成的是占位符? 所以我们这里不能使用#{},这里我们可以使用${}进行字符串拼接

<select id="getList" resultType="com.example.demo.entity.User">
        select * from userinfo
                 where username like '%${username}%'
                   and updatetime between #{createTime} and #{updateTime}
                    order by updatetime desc
</select>
@Test
    void getList() {
        User user = new User();
        user.setUsername("张三");
        user.setCreateTime(LocalDateTime.of(2023,05,12,11,9,01));
        user.setUpdateTime(LocalDateTime.of(2023,05,12,11,9,01));
        List<User> list = userMapper.getList(user);
        list.stream().forEach(System.out::println);
    }

在这里插入图片描述
我们发现这里是直接拼接到sql语句中,但是${}性能低、不安全、存在SQL注入问题
我们可以使用concat函数,concat函数是干什么的呢?我先给大家演示一下:
在这里插入图片描述
我们可以发现,其实concat就是一个字符串拼接函数
在这里插入图片描述
我们就可以将代码改为#{}的方式
在这里插入图片描述
参数名说明:
在SpringBoot的2.x版本:

在这里插入图片描述
在SpringBoot的1.x版本/单独使用mybatis:
:
为啥不是参数直接映射呢?
在这里插入图片描述
因为在该版本在编译时,并不会保留参数名,因此我们参数名不能对应,因此需要使用@Param

#{} 与 ${}的区别

1.#{paramName} -> 占位符模式
在这里插入图片描述
2.${paramName} -> 直接替换
在这里插入图片描述
#{}预编译的SQL有以下优势:
性能更高,更安全(防止SQL注入)
在这里插入图片描述
SQL注入是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法

我们来写一个简单的SQL注入的案例:
在这里插入图片描述
在这里插入图片描述
因为使用${}传递字符串类型参数时,只会传递数值,所以我们需要手动加’ '转换为字符串

在这里插入图片描述

这是我们数据库里的两组数据,我们来测试一下登录功能
在这里插入图片描述

我们使用正确的账号密码是可以登录的
在这里插入图片描述
使用错误的密码是登录不上去的,我们现在使用SQL注入的方式进行登录
在这里插入图片描述
为什么呢?我们这里的密码输入的是错误的,为什么登录成功了
在这里插入图片描述
看到这里是不是恍然大悟了。
${}拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题,我们在开发中尽量避免使用。

更新操作

在这里插入图片描述
修改id用户的密码为password
在这里插入图片描述
在这里插入图片描述

新增操作

我们给userinfo新增一个用户
在这里插入图片描述
在这里插入图片描述

@Test
    void addUser() {
        User user = new User();
        user.setUsername("zhangsan");
        user.setPassword("123456");
        int count = userMapper.addUser(user);
        System.out.println("新增了"+ count + "行" );
    }

我们没有加@Transactional注解,直接进行落盘操作。
在这里插入图片描述
如果我们仅仅只是想获取该操作受影响的行数,操作起来也是比较简单的。
如果返回值想要获取id主键值呢?
我们需要在里面设置两个属性值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二. Mybatis多表操作

我们先在mycnblog下在建一张表
在这里插入图片描述
在这里插入图片描述
然后插入一条数据,我们创建ActicleInfo的实体类:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Article {
    private Integer id;
    private String title;
    private String content;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
    private Integer uid;
    private Integer rcount;
    private Integer state;
}

但是我们还需要username属性,但不再Article中,我们创建一个Article的扩展类
在这里插入图片描述
我们创建Article的Mapper接口

@Mapper
public interface ArticleMapper {

    //查询文章详情
    ArticleVO getDetail(Integer id);
}

在这里插入图片描述

<select id="getDetail" resultType="com.example.demo.entity.vo.ArticleVO">
        select a.*,u.username from articleinfo a left join userinfo u on u.id = a.uid
        where a.id = #{id}
    </select>

测试类:

@SpringBootTest
class ArticleMapperTest {

    @Autowired
    private ArticleMapper articleMapper;
    @Test
    void getDetail() {
        ArticleVO articleVO = articleMapper.getDetail(1);
        System.out.println(articleVO);
    }
}

在这里插入图片描述
为什么我们这里打印了username,我们来查看ArticleVO的字节码
在这里插入图片描述
我们发现我们@Data注解的toString只会打印自己的属性不会打印父类属性的信息,这里我们自己重写一下toString()方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
再去执行,信息就可以全部打印了

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

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

相关文章

FE_JS对象的理解

对象是JS中的引用数据类型&#xff0c;对象是一种复合数据类型&#xff0c;在对象中可以保存多个不同数据类型的属性。使用typeof检查一个对象时&#xff0c;会返回object。 1 对象创建模式 - Object构造函数模式 套路: 先创建空Object对象, 再动态添加属性/方法 适用场景: 起…

【LeetCode: 1335. 工作计划的最低难度 | 暴力递归=>记忆化搜索=>动态规划 】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

又一个开源便斩获 7k star 的新模型「GitHub 热点速览」

作者&#xff1a;HelloGitHub-小鱼干 Star 并不能代表什么&#xff0c;但是绝对能表示一个项目的受欢迎程度。就像刚开源一周就有 7k star 的新模型&#xff0c;输入文本 / 图像就能获得 3D 对象。除了这个新模型&#xff0c;本周还有一款新的 Web 3D 渲染引擎 Orillusion&…

MySQL学习---17、MySQL8其它新特性

1、MySQL新增特性 1.1 更简便的NoSQL支持 NoSQL泛指非关系型数据库和数据存储。随着互联网平台的规模飞速发展&#xff0c;传统的关系型数据库已经越来越不能瞒住需求。从5.6版本开始&#xff0c;MySQL就开始支持简单的NoSQL存储功能。MySQL 8对这一功能做了优化&#xff0c;…

阿里P8强烈推荐的可伸缩服务架构:框架与中间件笔记

随着企业业务量的增加&#xff0c;流量洪峰在不断挑战着业务系统的承载能力&#xff0c;设计高并发、可伸缩的系统已成为软件架构师的紧迫任务&#xff0c;而分布式、可伸缩的架构模式已成为抵御洪峰的有效方案之一。本书汇集了作者在多年核心系统开发中的架构及实践经验&#…

【算法】--- 几分钟带你走进排序算法大门(上)

文章目录 前言&#x1f31f;一、常见的排序算法&#xff1a;&#x1f31f;二、直接插入排序排序&#xff1a;&#x1f4d2;2.1 基本思想&#xff1a;&#x1f4d2;2.2 代码&#xff1a;&#x1f4d2;2.3 时间复杂度&#xff1a;O(N^2)&#x1f4d2;2.4 流程图详解&#xff1a; …

聚观早报 | Midjourney官方在QQ开启内测;富士康印度新工厂动工

今日要闻&#xff1a;Midjourney官方在QQ开启内测&#xff1b;富士康印度新工厂动工&#xff1b;闲鱼将开收软件服务费&#xff1b;专家建议五年内禁售燃油车&#xff1b;笑果文化已被立案调查 Midjourney官方在QQ开启内测 5 月 15 日&#xff0c;据 Midjourney AI 微信公众号…

Unity之OpenXR+XR Interaction Toolkit实现 手枪模型的拆卸和组装

前言 之前我们曾实现过PC端的模型的拆卸和组装&#xff0c;如果使用VR模式来实现物体的拆卸呢&#xff1f;如何使用双手手柄来控制物体&#xff0c;拆卸物体呢&#xff1f;今天我们就来实现一个VR小Demo&#xff0c;基于OpenXR &#xff0c;XR Interaction Toolkit插件来实现。…

程序员面试宝典

前言 编者: 大淘宝技术开发工程师 / 刘苏宏(淘苏) 淘苏(花名)目前是大淘宝技术的一名开发工程师。从国企 跳槽来到互联网&#xff0c;【职业规划】是他被问得最多&#xff0c;也思考得 最多的问题。 扫一扫&#xff0c;关注公众号【大淘宝技术】 了解更多大淘宝技术干货沉淀 …

技术架构演进之路-Docker【一】

技术架构演进之路 了解每种技术架构以及如何演进的&#xff0c;熟悉Docker在架构中的核心作用 八大架构演进 单机架构 当前服务由应用服务和数据库服务两个服务组成&#xff0c;应用服务由 用户模块、商品模块、交易模块三个模块组成&#xff0c;我们可以理解它为 淘宝。用户模…

互联网时代,自媒体宣发的概念、优势、策略及注意事项

自媒体宣发是指通过自己或者委托专业机构&#xff0c;运用自媒体平台传播宣传信息的一种方式。在互联网时代&#xff0c;自媒体已经成为了企业推广的一种重要手段。本文将为大家介绍自媒体宣发的概念、优势、策略及注意事项。#自媒体# 一、什么是自媒体宣发&#xff1f; 自媒体…

通配符SSL证书是什么?

通配符SSL证书可以对申请的域名保护以外&#xff0c;还可以对下一级子域名无限使用&#xff0c;适合存在很多二级域名项目的网站&#xff0c;这样不需要额外对子域名申请SSL证书&#xff0c;还可以进行同意管理及部署SSL证书避免跨站窜站的问题。 申请通配符SSL证书 一、申请通…

SSH远程终端神器,你在用哪一款

唠嗑部分 在我们日常开发中啊&#xff0c;不可避免的要与Linux打交道&#xff0c;虽然我们作为开发&#xff0c;不要求我们对Linux有多么的专业&#xff0c;但是基本的操作还是要会的&#xff0c;举几个常用的例子&#xff1a; 1、查看nginx配置&#xff0c;配置转发 2、清理…

蓝桥杯模块学习4——数码管

第一章 硬件部分 1.1 电路的组成部分 1.1.1 译码器和锁存器 具体可回顾之前LED灯的文章&#xff1a; https://blog.csdn.net/weixin_63568691/article/details/130660096 1.1.2 共阳极数码管&#xff1a; 原理图&#xff1a; 功能&#xff1a; &#xff08;1&#xff09;可…

[网鼎杯 2020 青龙组]bang 复现--frida-dexdump安卓脱壳工具的使用

一.前言 在NSSCTF练习安卓逆向,第一次遇到安卓脱壳题 大佬的题解只有一句话"frida-dexdump一把嗦" 听起来容易做起来难,还遇到了安卓虚拟机的玄学bug,折磨了我很久,好在最终使用真机成功dump并得到flag 题目来源:[网鼎杯 2020 青龙组]bang 如果直接用jadx打开会发现…

重大喜讯!国产讯飞星火大模型将超越chatGPT!

引言 近年来&#xff0c;随着人工智能技术的快速发展&#xff0c;自然语言处理成为了研究的热点。而在自然语言处理领域&#xff0c;ChatGPT是一个备受关注的模型&#xff0c;它的出现极大地推动了自然语言处理技术的发展。然而&#xff0c;最近国内一家公司——讯飞&#xff0…

记录--10个超级实用的Set、Map使用技巧

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 Set是一种类似于数组的数据结构&#xff0c;但是它的值是唯一的&#xff0c;即Set中的每个值只会出现一次。Set对象的实例可以用于存储任何类型的唯一值&#xff0c;从而使它们非常适用于去重。 Map是…

如何为研发团队打造专属的效能提升路径|QECon 演讲回顾

近日&#xff0c;ONES 受邀参加 2023 QECon 全球软件质量&效能大会&#xff08;深圳站&#xff09;。在会上&#xff0c;ONES 研发效能改进咨询顾问陈仪&#xff0c;发表了主题为《如何为研发团队打造专属的效能提升路径》的演讲。 陈仪有着丰富的咨询经验&#xff0c;曾带…

C++考试

文章目录 1.程序填空1.1函数调用1.2前置和后置“”、“--”运算符重载1.3异常处理1.4文本文件读取 2.程序阅读2.1C编程基础2.2继承与派生2.3静态成员2.4继承与派生2.5 输入输出2.6 模板 3.程序改错3.1三种访问权限3.2 友元3.3抽象类不能实例化对象3.4常数据成员初始化必须使用构…

面试题总结

1、0513 1.重载和重写的区别? 重载发生在同一类中&#xff0c;同名的方法如果有不同的参数列表&#xff08;类型不同、个数不同、顺序不同&#xff09;则视为重载。 重写发生在父子类中&#xff0c;重写要求子类重写之后的方法与父类被重写方法有相同的返回类型&#xff0c;比…