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_Mybaitsdatasource:url: jdbc:mysql://127.0.0.1:3308/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: ”写上自己的密码“driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:# 配置 mybatis xml 的文件路径,在 resources/mapper 创建所有表的 xml 文件mapper-locations: classpath:mybatis/**Mapper.xmlconfiguration: # 配置打印 MyBatis日志log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-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 {@AutowiredUserInfoMapper userInfoMapper;@Testvoid 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方法中实现我们的测试方法。

 @Testvoid 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数据库连接池, 只需要引⼊相关依赖即可

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

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

相关文章

latex bib引参考文献

1.bib内容 2.sn-mathphys-num是官方的参考文献格式 3.不用导cite包&#xff0c;文中这么写 4.end document前ckwx是自己命名的bib的名字

Ollama教程,本地部署大模型Ollama,docker安装方法,仅供学习使用

不可商用&#xff01;&#xff01;仅仅提供学习使用&#xff01; 先上视频教学&#xff1a; Ollama教程&#xff0c;本地部署大模型Ollama&#xff0c;docker安装方法&#xff0c;仅供学习使用&#xff01; 资料获取 &#xff1a; Ollama下载包和安装文档在这里&#xff1…

Web自动化测试-掌握selenium工具用法,使用WebDriver测试Chrome/FireFox网页(Java

目录 一、在Eclipse中构建Maven项目 1.全局配置Maven 2.配置JDK路径 3.创建Maven项目 4.引入selenium-java依赖 二、Chrome自动化脚本编写 1.创建一个ChromeTest类 2.测试ChromeDriver 3.下载chromedriver驱动 4.在脚本中通过System.setProperty方法指定chromedriver的…

vi和vim有什么不同?

vi 和 vim 都是流行的文本编辑器&#xff0c;它们之间有以下主要区别&#xff1a; 历史&#xff1a; vi 是一个非常古老的文本编辑器&#xff0c;最初由 Bill Joy 在 1976 年为 Unix 系统编写。vim&#xff08;Vi IMproved&#xff09;是 vi 的一个增强版&#xff0c;由 Bram M…

Ubuntu 20.04安装CMake 3.22.6版本

Ubuntu 20.04通过apt安装的cmake版本是3.16.3&#xff0c;默认安装到/usr/bin/cmake路径。 $ cmake Command cmake not found, but can be installed with:sudo snap install cmake # version 3.29.3, or sudo apt install cmake # version 3.16.3-1ubuntu1.20.04.1See sna…

Multer 文件上传中间件 和 Busboy表单解析

Multer 是一个node.js中间件&#xff0c;用于处理 multipart/form-data类型的表单数据&#xff0c;主要用于上传文件。只处理 multipart/form-data 类型的表单数据。 Multer是基于Busboy解析的文件参数信息&#xff0c;获取fileStream&#xff0c;并通过storage转存的file.str…

Unity + 雷达 粒子互动(待更新)

效果预览: 花海(带移动方向) VFX 实例 脚本示例 使用TouchScript,计算玩家是否移动,且计算移动方向 using System.Collections; using System.Collections.Generic; using TouchScript; using TouchScript.Pointers; using UnityEngine; using UnityEngine.VFX;public …

AI预测福彩3D采取888=3策略+和值012路一缩定乾坤测试6月1日预测第8弹

今天继续基于8883的大底&#xff0c;使用尽可能少的条件进行缩号。好了&#xff0c;直接上结果吧~ 首先&#xff0c;888定位如下&#xff1a; 百位&#xff1a;6,5,4,7,8,9,1,0 十位&#xff1a;7,8,6,5,9,3,1,0 个位&#xff1a;5,7,6,4,2,…

看广告赚金币提现小游戏app开发源码

开发一个看广告赚金币并可以提现的小游戏APP&#xff0c;源码的搭建涉及到多个方面&#xff0c;包括前端界面设计、后端逻辑处理、数据库管理以及广告平台的对接等。以下是一些建议的步骤和考虑因素&#xff1a; 前端界面设计&#xff1a; 使用HTML5、CSS3和JavaScript等技术…

第十三届蓝桥杯B组c++国赛

A - 2022&#xff1a; 题目&#xff1a; 笔记&#xff1a; 一道经典的dp题&#xff1a; &#xff08;1&#xff09;明确dp数组含义&#xff1a; dp[i][j][k]: 表示前i个数字中选择j个凑成k的方法数。 &#xff08;2&#xff09;确定状态转移方程&#xff1a; dp[i][j][k…

C++中的引用和解引用,及在Lambda中的简单使用

目录 摘要 引用&#xff08;Reference&#xff09; 定义 用法 解引用&#xff08;Dereference&#xff09; 定义 用法 Lambda表达式结合引用和解引用 引用结合Lambda表达式 解引用结合Lambda表达式 较为复杂的使用 总结 摘要 在C中&#xff0c;引用&#xff08;Re…

linux 内核哪种锁可以递归调用 ?

当数据被多线程并发访问(读/写)时&#xff0c;需要对数据加锁。linux 内核中常用的锁有两类&#xff1a;自旋锁和互斥体。在使用锁的时候&#xff0c;最常见的 bug 是死锁问题&#xff0c;死锁问题很多时候比较难定位&#xff0c;并且影响较大。本文先会介绍两种引起死锁的原因…

Java-----String类

1.String类的重要性 经过了C语言的学习&#xff0c;我们认识了字符串&#xff0c;但在C语言中&#xff0c;我们表示字符串进行操作的话需要通过字符指针或者字符数组&#xff0c;可以使用标准库中提供的一系列方法对字符串的内容进行操作&#xff0c;但这种表达和操作数据的方…

沟通程序化(1):跟着鬼谷子学沟通—“飞箝”之术

沟通的基础需要倾听&#xff0c;但如果对方听不进你的话&#xff0c;即便你说的再有道理&#xff0c;对方也很难入心。让我们看看鬼谷子的“飞箝”之术能给我们带来什么样的启发吧&#xff01; “飞箝”之术&#xff0c;源自中国古代兵法家、纵横家鼻祖鬼谷子的智慧&#xff0…

SpringBootWeb 篇-深入了解 Spring 异常处理、事务管理和配置文件参数配置化、yml 配置文件

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 配置文件 1.1 yml 配置文件 1.2 参数配置化 1.2.1 使用 Value 注解注入单个配置参数 1.2.2 使用 ConfigurationProperties 注解将一组相关配置参数注入到一个类中…

discuz论坛怎么修改备案信息

大家好&#xff0c;今天给大家分享下discuz如何填写备案信息并且展示在网站首页。大家都知道国内网站都需要备案&#xff0c;不通过备案的网站上是没办法通过域名打开的。大家也可以通过搜索网创有方&#xff0c;或者直接点击网创有方 查看悬挂备案号后的效果。 首先大家可以看…

如何在CentOS中合理划分磁盘空间以优化系统性能

目录 前言 理想的分区方案 为什么需要单独分区 安全性 性能 管理和维护 稳定性和可靠性 升级和兼容性 结论 前言 在进行CentOS系统的安装和配置时&#xff0c;合理划分磁盘空间是确保系统性能、安全性和易于管理的关键步骤。本文将探讨如何根据系统的硬件配置和预期用途…

安全测试扫描利器-Burpsuite

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

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

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

Linux 命令:awk

1. 写在前面 本文主要介绍 Linux “awk” 命令&#xff1a;“awk” 是另一个强大的文本处理工具&#xff0c;用于处理和操作结构化数据&#xff0c;如日志文件和命令输出。它可以根据需要为我们打印特定的列值。 公众号&#xff1a; 滑翔的纸飞机 2. awk 命令 我们能用 awk 做…