Mybatis第一讲——你会Mybatis吗?

文章目录

  • 什么是Mybatis
    • Mybatis的作用是什么
  • Mybatis 怎么使用
    • 注解的方式
    • 注解的多种使用
      • @Options注解
      • ResultType注解
    • XML的方式
      • update标签
  • #{} 和 ${}符号的区别
    • #{}占位
    • ${}占位
  • ${}占位的危险性(SQL注入)
  • 数据库连接池

什么是Mybatis

首先什么是Mybatis呢?Mybatis是一个持久层框架也就是用来操作数据库的一个框架,我们在最原始的时候使用jdbc进行数据库的操作这使得我们会有大量的重复操作需要进行,那么Mybatis把这些重复的操作进行了集合,使得我们的代码更见的简单,并且对于我们jdbc中需要连接数据库的这个操作也进行了优化,使用配置文件的方式来使得我们的操作变得更加的简单。

Mybatis的作用是什么

那么看了上面之后我们也就知道了Mybatis框架的作用了也就是简单易用,代码简单提供了很多强大且方便的功能帮助我们可以更好更快更方便的编写代码。操纵数据库。

Mybatis 怎么使用

那么有了上面的概念之后,我们来讲述一下Mybatis该怎么使用,首先我们要想使用Mybatis那么我们就要先将Mybatis配置到我们的Spring中也就是说要导入依赖导入什么依赖呢?如下

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>

		<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter-test</artifactId>
            <version>3.0.3</version>
            <scope>test</scope>
        </dependency>

当然这些还是不够因为我们只是把Mybatis引入了进来但是我们还是不能使用,我们可以想一下我们在使用jdbc的时候除了把jar包引入进来之后我们还做了什么工作吗?我们还有的工作就是使用jdbc给我们提供的接口来与我们的目标数据库建立了连接,那么我们这里也是需要建立连接的,那么连接如何建立呢?

spring:
  application:
  name: Spring_Mybaits
  datasource:
    url: jdbc:mysql://127.0.0.1:3308/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: ”写上自己的密码“
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  # 配置 mybatis xml 的文件路径,在 resources/mapper 创建所有表的 xml 文件
  mapper-locations: classpath:mybatis/**Mapper.xml
  configuration: # 配置打印 MyBatis日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true #配置驼峰自动转换

这就是我们配置文件的书写格式我们发现我们的配置文件内定义了我们mybatis的日志信息并且害配置了mybatis如果进行了xml中写的话那么我们也配置了该xml文件的路径信息。那么配置好后我们来看看如何来写代码吧

注解的方式

首先是注解的方式我们的Mybatis写sql代码实在接口类中写的因此我们要先定义一个接口代码并且这个接口代码我们需要使用@Mapper注解来修饰代码如下

package com.example.spring_mybaits.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Update;
import java.util.List;
@Mapper
public interface UserInfoMapper {
}

这里我们定义了一个接口并且使用了Mapper注解进行了修饰那么接下来我们要来写代码了,那么代码该怎么去写呢?那么代码的书写我们先从最简单的查询所有数据开始吧,如何查询所有的数据呢?我们来写一下代码首先,先在接口中写一个select方法的声明

package com.example.spring_mybaits.mapper;

import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface UserInfoMapper {
    List<UserInfo> selectAllUser();
}

第二步实现

package com.example.spring_mybaits.mapper;

import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface UserInfoMapper {
	@Select(" select * from userinfo")
    List<UserInfo> selectAllUser();
}

第三步进行测验
我们需要进行实现test方法那么如何快速的实现test方法呢?我们要进行
在这里插入图片描述
首先点击Generate 弹出下面的这个页面
在这里插入图片描述
然后点击Test
在这里插入图片描述
然后在下面选择你要进行测验的方法,然后光有这些也不够我们的测试代码也是需要进行进一步的书写的。

package com.example.spring_mybaits.mapper;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    UserInfoMapper userInfoMapper;
    @Test
    void selectAllUser() {
        List<UserInfo>list=userInfoMapper.selectAllUser();
        for (UserInfo u:list) {
            System.out.println(u);
        }
    }
}

我们通过查看上面的测试代码我们不难发现,我们实现的接口在这里使用了@Autowired注解进行了修饰,那么这个注解我们之前讲过这相当于是把spring容器中存储的Bean给注入了进去,那么既然如此我们就可以调用这个接口中的方法了。

注解的多种使用

@Options注解

这个注解可以帮助我们获取到查询到的目标主键,比如说我们使用insert插入了一行,然后我们想知道插入的这一行,所被分配到的自动递增的Id是多少,我们可以通过@Options注解进行实现。这个注解的使用方式如下首先这个注解我们需要传递进去两个参数代码如下我们来分别说一下他们的作用

    @Options(useGeneratedKeys = true,keyProperty = "id")
    Integer InsertId(Integer id,Integer age,String username,String password);

useGeneratedKeys :它可以是的Mybatis使用JDBC的getGeneratedKeys方法取出由数据库内部生成的主键
keyProperty :指定能够唯一识别的对象属性,MyBatis 会使⽤ getGeneratedKeys 的返回值或insert 语句的 selectKey ⼦元素设置它的值,默认值:未设置(unset)
注意!注意! 设置 useGeneratedKeys=true 之后, ⽅法返回值依然是受影响的⾏数, ⾃增id 会设置在上
述 keyProperty 指定的属性中

ResultType注解

在我们注解方式去实现的时候我们需要注意到一些特殊的情况比如说我们想要设置其返回的形式,通常适用于我们在写查询语句的时候进行的我们来看一下示例代码

import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.ResultType;

public interface UserMapper {

    @Select("SELECT * FROM users")
    @ResultType(User.class)
    List<User> getAllUsers();
}

那么这里的映射其实就是将结果进行映射,那么这时候会有疑问假如说我们要进行复杂查询的话我们要对多个结果进行映射的话该怎么做呢?那么这时候需要用到新的注解叫做@Results,那么我们来举个例子

@Results({
        @Result(property = "id", column = "id"),
        @Result(property = "name", column = "name"),
        @Result(property = "email", column = "email")
    })

它的名字和它的用法很像,指的就是多个result的集合。那么它的一个样例代码如下

import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Result;

public interface UserMapper {
    @Select("SELECT id, name, email FROM users")
    @Results({
        @Result(property = "id", column = "id"),
        @Result(property = "name", column = "name"),
        @Result(property = "email", column = "email")
    })
    List<User> getAllUsers();
}

XML的方式

除了使用上述注解的方式之外我们还可以使用XML的方式,那么XML的方式该怎么实现呢?我们首先要先对前面的一个知识点做一个说明那就是我们在配置文件中的下面的这个属性我们可以根据意思去揣测出来这个意思是指路径

  mapper-locations: classpath:mybatis/**Mapper.xml

那么这个路径其实就是我们的xml文件所配置的路径,那么接下来我们来写一下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.example.spring_mybaits.mapper.UserInfoMapper">
</mapper>

那么我们来讲解一下这个配置首先第一个mapper,他是一个标签,我们接下来写的所有标签都是在这个标签内部进行写的,其次就是namespace这个英文的直译就是命名空间,也就是我们这个xml文件是对那一个java文件所进行的连接,那么接下里我们来用几个例子来写一下吧

<?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.spring_mybaits.mapper.UserInfoMapper">    
    <update id="updateUser">
        UPDATE  userinfo set username=#{username},id=#{id1},age=#{age} WHERE id=#{id};
    </update>
</mapper>
    Integer updateUser(Integer id,String username,Integer id1,Integer age);

然后我们用上面写的知识首先在方法的声明这里鼠标右键点击一下
在这里插入图片描述
在弹出的页面中选择Generate
在这里插入图片描述
然后选择test
然后在生成的test方法中实现我们的测试方法。

 @Test
    void updateUser() {
        UserInfo userInfo=new UserInfo();
        userInfo.id=11;
        userInfo.age=21;
        userInfo.phone="520134";
        userInfo.username="zyficl";
        int d= userInfoMapper.updateUser(2, userInfo.username,userInfo.id, userInfo.age );
        System.out.println(d);
    }

通过上面我们来回答一下上面代码中可能出现的部分疑问

update标签

首先就是update标签,通过这标签的内容我们可以指导这个标签中需要有一个参数那就是id这个id的值就是我们具体要实现的一个方法的名称,然后我们以此作为类推我们可以知道,其实我们的select标签也是同样的用法。
那么我们有了上面的了解后相信就可以写出比较简单的一些数据库sql语言的操作了,那么这些操作包括但不限于增删查改,但是接下来还有一些比较复杂的操作也是需要我们学习的比如说复杂查询,排序,等,包括一些动态的添加,动态的查找等,那么我们来一起学习一下这些该怎么进行那么接下来我们来讲一下本节重点知识那就是#和$符号的区别。

#{} 和 ${}符号的区别

那么在讨论区别之前我们需要先讨论一下他们的作用,那么他们的作用是什么呢?他们的作用其实都是对sql语句加上参数也就是一个占位符,但是他们在实现上又有区别,我们下面可以来看一下分别使用这两个符号的话会有什么不同

#{}占位

这是一个安全的占位当我们使用这个占位的时候我们发现我们打印出的日志中对于占位的内容并没有补充,也就是说此时的占位并不是直接补充的。我们输⼊的参数并没有在后⾯拼接,id的值是使⽤ ? 进⾏占位. 这种SQL 我们称之为预编译SQL
在这里插入图片描述

${}占位

当我们把占位符更改一下更改为${}占位后我们再来看一下此时我们的代码会变成什么样子的呢?
在这里插入图片描述
这时候我们发现我们的代码变成了占位符的直接拼接,不像上面的那种使用占位符进行拼接那么这种方式我们叫做即时SQL。这也就是这两个的区别

${}占位的危险性(SQL注入)

$ 占位符用于直接替换字符串,这种方式不进行参数转义,因此存在SQL注入的风险。它通常用于传递表名、列名等SQL片段,但绝不应该用于传递用户输入的数据。那么什么时sql注入呢?比如说下面的这个语句

SELECT * FROM userinfo where id=?;

这里的问号是我们需要填写的内容那么既然如此假如说我们使用的时$占位符的话我们是不是也就是可以传进去这样一个内容呢?

SELECT * FROM userinfo where id=1;DELETE userinfo;

因为那个?表示并不是一个单一的字符因此我们完全可以将这个内容改成这个样子也正因此当我们执行的时候我们就会发现完了,sql语句被注入了,因此这样就会导致我们发生一个难以想象的一个损失。比如说被删库等操作。因此我们在实际开发中会尽量避开使用$符号。但是话又说回来了,为什么我们要保留这个符号呢?其实原因也很简单因为有些地方我们不可避免的要使用这个符号就比如说排序查询
使用 ${sort} 可以实现排序查询, ⽽使⽤ #{sort} 就不能实现排序查询了
除此之外还有别的吗?当然还有,也就是我们的模糊查询(like查询)

@Select("select id, username, age, gender, phone, delete_flag, create_time, 
update_time " +
 "from userinfo where username like '%#{key}%' ")
List<UserInfo> queryAllUserByLike(String key);

但是这里我们会陷入一个非常纠结的地方那就是如果我们使用$符号会有sql注入的风险可是不适用的话又不能达到我们的需求,那这个该怎么办呢?我们需要借助一个方法来进行实现这个方法就是concat方法,这个方法的作用是什么呢这个方法的作用是进行字符串的拼接,也就是说我们可以使用字符串拼接的方式来避免这个风险那么样例如下

@Select("select id, username, age, gender, phone, delete_flag, create_time, 
update_time " +
 "from userinfo where username like concat('%',#{key},'%')")
List<UserInfo> queryAllUserByLike(String key);

数据库连接池

池化技术相信我们都已经了解过了池化技术相当于一个中间商一样我们对有无池化技术来用一张图来说明一下
在这里插入图片描述
这张图可以有效的说明有无池化技术的区别。
没有使⽤数据库连接池的情况: 每次执⾏SQL语句, 要先创建⼀个新的连接对象, 然后执⾏SQL语句, SQL
语句执⾏完, 再关闭连接对象释放资源. 这种重复的创建连接, 销毁连接⽐较消耗资源
使⽤数据库连接池的情况: 程序启动时, 会在数据库连接池中创建⼀定数量的Connection对象, 当客⼾
请求数据库连接池, 会从数据库连接池中获取Connection对象, 然后执⾏SQL, SQL语句执⾏完, 再把
Connection归还给连接池
那么我们的连接池有哪些呢?如下
常⻅的数据库连接池:
• C3P0
• DBCP
• Druid
• Hikari
我们来看一下我们的Mybaits的日志信息我们是可以发现的
在这里插入图片描述
在这里我们发现我们的Mybaits使用的一个数据库连接池是一个hikari,那么这其实也是可以更改的。
如果我们想把默认的数据库连接池切换为Druid数据库连接池, 只需要引⼊相关依赖即可

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

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

相关文章

Ps:调整画笔工具

调整画笔工具 Adjustment Brush Tool可以将选区、创建蒙版和应用调整的传统工作流程合并为一个步骤&#xff0c;简化了对图像进行非破坏性局部调整的操作。 快捷键&#xff1a;B 调整画笔工具是 Photoshop 2024 年 5 月版&#xff08;25.9 版&#xff09;新增的工具。 ◆ ◆ …

Stable Diffusion生成图片的参数查看与抹除方法

前几天分享了几张Stable Diffusion生成的艺术二维码&#xff0c;有同学反映不知道怎么查看图片的参数信息&#xff0c;还有的同学问怎么保护自己的图片生成参数不会泄露&#xff0c;这篇文章就来专门分享如何查看和抹除图片的参数。 查看图片的生成参数 1、打开Stable Diffus…

Redis常用命令——List篇

提到List&#xff0c;我们第一时间想到的就是链表。但是在Redis中&#xff0c;List更像是一种双端队列&#xff0c;例如C中的deque。它可以快速高效的对头部和尾部进行插入和删除操作。本片文章主要对List列表的相关命令进行详解&#xff0c;希望本篇文章会对你有所帮助。 文章…

vscode常用插件及插件安装方式

一、常用插件 Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code 说明&#xff1a;中文语言包扩展&#xff08;简体&#xff09; open in browser 说明&#xff1a;可以在默认浏览器或应用程序中打开当前文件 Auto Rename Tag 说明&#xff1a;自动重…

pyqt 进度条QProgressBar

pyqt 进度条 QProgressBar效果代码 QProgressBar 在 PyQt 应用程序中&#xff0c;进度条&#xff08;通常称为 QProgressBar&#xff09;是一个用于显示任务进度的控件。它可以显示一个水平或垂直的条形图&#xff0c;条形图的长度会随着进度的增加而增加。 QProgressBar 的主…

C语言---文件操作

【C语言详解】——文件操作&#xff08;建议收藏&#xff09;_c语言 写文件原理-CSDN博客 一、文件的读取 # define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<errno.h> #include<string.h>int main() {FILE * pffopen("C:\\Users\\zhw\\De…

【电路笔记】-带阻滤波器

带阻滤波器 文章目录 带阻滤波器1、概述2、典型带阻滤波器配置3、带阻滤波器示例14、陷波滤波器5、带阻滤波器示例26、总结带阻滤波器也称为陷波滤波器,阻止并拒绝位于其两个截止频率点之间的频率,并传递该范围两侧的所有这些频率。 1、概述 通过将基本 RC 低通滤波器与 RC …

Python自动实时查询预约网站的剩余名额并在有余额时发邮件提示

本文介绍基于Python语言&#xff0c;自动、定时监测某体检预约网站中指定日期的体检余额&#xff0c;并在有体检余额时自动给自己发送邮件提醒的方法。 来到春招末期&#xff0c;很多单位进入了体检流程。其中&#xff0c;银行&#xff08;尤其是四大行&#xff09;喜欢“海检”…

springboot基础及上传组件封装

简介 本文主要以文件上传为demo&#xff0c;介绍了一些 springboot web 开发的入门的技术栈。 对应刚接触 springboot 的可以参考下。 主要包括文件md5比对、生成图片缩略图、数据库迁移、文件记录持久化、请求全局异常处理等功能。 准备工作 在 idea 中创建项目&#xff…

十大排序 —— 快速排序

十大排序 —— 快速排序 快速排序一些坑快速排序的性能优点&#xff1a;缺点&#xff1a;性能优化&#xff1a; 我们今天来看看十大排序中很出名的一个算法——快速排序&#xff1a; 快速排序 快速排序&#xff08;Quick Sort&#xff09;是一种经典的、高效的排序算法&#…

centos8stream 编译安装 php-rabbit-mq模块

官方GitHub&#xff1a;https://github.com/php-amqp/php-amqp 环境依赖安装 dnf install cmake make -y 1.安装rabbitmq-c cd /usr/local/src/ wget https://github.com/alanxz/rabbitmq-c/archive/refs/tags/v0.14.0.tar.gz tar xvf v0.14.0.tar.gz cd rabbitmq-c-0.14.0/…

Linux下多线程的相关概念

&#x1f916;个人主页&#xff1a;晚风相伴-CSDN博客 &#x1f496;如果觉得内容对你有帮助的话&#xff0c;还请给博主一键三连&#xff08;点赞&#x1f49c;、收藏&#x1f9e1;、关注&#x1f49a;&#xff09;吧 &#x1f64f;如果内容有误或者有写的不好的地方的话&…

php反序列化入门

一&#xff0c;php面向对象。 1.面向对象&#xff1a; 以“对象”伪中心的编程思想&#xff0c;把要解决的问题分解成对象&#xff0c;简单理解为套用模版&#xff0c;注重结果。 2.面向过程&#xff1a; 以“整体事件”为中心的编程思想&#xff0c;把解决问题的步骤分析出…

实时监控电脑屏幕的软件是什么?三款超受欢迎的电脑监控软件

实时监控电脑屏幕的软件在现代企业管理中扮演着至关重要的角色&#xff0c;它们不仅帮助管理者实时监控员工的工作状态&#xff0c;提高工作效率&#xff0c;还通过数据分析和报告功能&#xff0c;为企业提供了优化管理流程和决策支持的依据。以下将介绍几款市面上广泛使用的实…

Redis过期策略数据淘汰策略

过期策略 一、设置过期时间 redis有四种命令可以用于设置键的生存时间和过期时间&#xff1a; EXPIRE : 将键的生存时间设为 ttl 秒 PEXPIRE :将键的生存时间设为 ttl 毫秒 EXPIREAT :将键的过期时间设为 timestamp 所指定的秒数时间戳 PEXPIREAT : 将键的过期时间设为 times…

GNU Radio创建qt time plot python OOT块

文章目录 前言一、创建自定义的 OOT 块1、安装相应依赖2、创建 OOT 块3、修改相关4、编译及安装 OOT 块 二、测试1、grc 图2、运行结果 三、资源自取 前言 官方提供的绘制时域波形的 block 名字叫做 QT GUI Time Sink&#xff0c;其底层实现是用 C 写的&#xff0c;但是我发现…

virtualbox中ubuntu22.04网络配置

第一&#xff1a;添加两个网卡&#xff0c;网卡1是NAT方式&#xff0c;网卡2是仅主机模式&#xff08;两个顺序不能颠倒&#xff09; 第二步&#xff1a;启动ifconfig查看网络

『 Linux 』文件系统

文章目录 磁盘构造磁盘抽象化 磁盘的寻址方式磁盘控制器磁盘数据传输文件系统Inode数据块(Data Blocks)超级块(SuperBlock)块组描述符(Group Descriptor) 磁盘构造 磁盘内部构造由磁头臂,磁头,主轴,盘片,盘面,磁道,柱面,扇区构成; 磁头臂&#xff1a;控制磁头的移动,可以精确地…

Exce 两列一组对齐呈现,缺失补 0

Excel 里有 多 组数据&#xff0c;每组 2 列&#xff0c;每组长度不同。第 1 列是编号&#xff0c;列之间的编号有重复。 ABCDEFGH1Mass10Mass11Mass12Mass132802200581309088146532802225938133306824779282975598142002482273148413154988335698822331305832720485110460842…

go解析yaml

go解析yaml文件关键就是结构体的创建 初学go tag字段要和yaml文件中的key对应起来&#xff0c;每个层级都要创建对应的结构体&#xff0c;有点烦 package configimport ("gopkg.in/yaml.v3""os" )type Config struct {MysqlConfig MysqlConfig yaml:&q…