【MyBatis】什么是MyBatis?

news2024/12/24 21:39:05

MyBatis 是一款优秀的持久层框架,用于简化JDBC的开发。
说人话就是连接数据库并执行SQL的框架。
在这里插入图片描述

文章目录

  • 0 JDBC简介及流程
      • 0.1 DriverManager / Connection
      • 0.2 ResultSet
      • 0.3 PreparedStatement
        • 1 SQL注入
        • 2 流程
  • 1 MyBatis通过注解执行SQL语句
    • 1.1 MyBatis入门:select
      • Lombok
    • 1.2 依葫芦画瓢:删除
    • 1.3 插入
    • 1.4 更新
  • 2 通过XML映射文件配置SQL语句
      • 小插件
  • 3 动态SQL
    • if
    • foreach
    • sql
  • 4 文件设置总结

0 JDBC简介及流程

【这一节完全可以跳过,理解它是一个连接数据库 & 执行sql的jar包就好,因为后面基本在用MyBatis,基本上不咋直接使JDBC】

Java DataBase Connectivity,JDBC就是使用Java语言操作关系型数据库的一套API:

  • 官方定义的一套操作所有关系型数据库的规则,即接口
  • 各个数据库厂商实现这套接口,提供数据库驱动jar包
  • 我们可以使用这套JDBC接口编程,真正执行的代码是驱动jar包的实现类。

使用的步骤:首先导入驱动jar包。

我的MySQL驱动jar包:F:\MySQL\Program Files (x86)\MySQL\Connector J 8.0\mysql-connector-j-8.0.32.jar

将驱动jar包放入项目下的lib文件夹,并设置add as library。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZFN9MBLK-1686806551629)(【MyBatis】什么是MyBatis?/image-20230615131749568.png)]

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

// 1 注册驱动
// sql 5之后可以不写这一条
Class.ForName("com.mysql.cj.jdbc.Driver");

// 2 连接数据库
url = "jdbc:mysql://127.0.0.1:3306/askcourse";
Connection conn = DriverManager.getConnection(url, username, password);

// 3 定义SQL语句
sql = "";

// 4 获取执行SQL的对象
Statement stmt = conn.createStatement();

// 5 执行SQL
stmt.executeUpdate(sql);

// 6 处理返回结果
// 7 释放资源
stmt.close();
conn.close();

0.1 DriverManager / Connection

1、注册驱动

Class.ForName("com.mysql.cj.jdbc.Driver");

Driver类源码中,这句话对应着:

DriverManager.registerDriver(new Driver())

2、从DriverManger类得到数据库连接。

Connection conn = DriverManger.getConnection('jdbc:mysql://127.0.0.1:3306/数据库名', 用户名, 密码)

0.2 ResultSet

结果集对象,封装了查询语句的结果。

ResultSet res = stmt.executeQuery(sql);

获取查询结果:

boolean next(): 将光标从当前位置移动一行,判断该行是否为有效行
xxx getXxx(): 获取数据

0.3 PreparedStatement

1 SQL注入

SQL注入例子:无论何时,这样拼起来都是true

String name ="hfkjsfhskj";
String pwd = " or '1' ='1"
String sql = "select * from tb_user where username = " + name + " and password = " + pwd;
System.out.printIn(sql);
select * from tb_user where username = 'hfkjsfhskj' and password = '' or '1' = '1'

2 流程

1、获取Connection。

String url = "jdbc:mysql://127.0.0.1:3306/askcourse?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT";
String user = "root";
String password = "********";
Connection conn = DriverManager.getConnection(url, user, password);

2、预编译SQL并填入参数。

String DNO = "C10";
String sql = "SELECT * FROM employee WHERE DNO = ?";

PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, DNO);

3、执行SQL语句。

ResultSet rs = pstmt.executeQuery();

while (rs.next()) {
    System.out.println(rs.getString("DNO"));
}

4、关掉所有的东西。

rs.close();
pstmt.close();
conn.close();

1 MyBatis通过注解执行SQL语句

1.1 MyBatis入门:select

加入Maven依赖,配置连接信息,创建相应实体,创建Mapper及查询方法,添加相应注解。

1、小tips:连接数据库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qx8W8eXS-1686806551629)(【MyBatis】什么是MyBatis?/image-20230614221722305.png)]

2、在pom.xml中加入maven依赖,前者为mybatis的bootstarter,后者为mysql的驱动连接包。

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

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

3、在Springboot项目中的application.properties中配置Mybatis数据库连接信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KY3J7aga-1686806551630)(【MyBatis】什么是MyBatis?/image-20230614222934825.png)]

3、创建一个实体类User,用于和数据库中的表属性相关联

4、创建UserMapper,一开始的报错Missing method body, or declare abstract是因为,这实际上是个Interface,误写为了Class,改一下就好。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JdvLpRTY-1686806551630)(【MyBatis】什么是MyBatis?/image-20230614225315951.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wHY5P6iH-1686806551630)(【MyBatis】什么是MyBatis?/image-20230614230602501.png)]

5、在test文件夹中的HelloworldApplicationTests应用中,实例化一个UserMapper,并新建testListUser测试。

@SpringBootTest
class HelloworldApplicationTests {

    @Autowired
    private UserMapper userMapper;

    @Test
    void testListUser() {
        List<User> userList = userMapper.list();
        userList.stream().forEach(System.out::println);
    }

}

Lombok

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5dGaMtqr-1686806551631)(【MyBatis】什么是MyBatis?/image-20230614232536349.png)]

maven依赖:

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

1.2 依葫芦画瓢:删除

1、新建一个FinishProblemMapper,用于对finishProblem表进行操作。@Mapper注解和@Delete注解。使用#{param}在SQL语句中写入参数。根据主键删除元素

package com.example.helloworld.mapper;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface FinishProblemMapper {

    /**
     * 根据wid与problemId删除指定的做题记录
     * @param wid
     * @param problemId
     */
    @Delete("delete from finished where wid = #{wid} and problemId = #{problemId}")
    public void deleteById(Integer wid, Integer problemId);
}

2、在配置文件中设置mybatis日志

# the log of mybatis
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

3、在test中新建Test

@SpringBootTest
class HelloworldApplicationTests {

    @Autowired
    private FinishProblemMapper finishProblemMapper;


    @Test
    void testDeleteFinishProblem() {
        finishProblemMapper.deleteById(72, 21);
    }

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RWBdKGED-1686806551631)(【MyBatis】什么是MyBatis?/image-20230614234515523.png)]

1.3 插入

传入的参数可以是一个实体。

@Options注解会自动将生成的主键值,赋值给problem的problemId属性。(自动生成主键值

@Mapper
public interface ProblemMapper {

    /**
     * 向Problem表中插入一行problem数据
     * @param problem
     */
    @Insert("insert into problem(problemId, name, url, day) VALUE (#{problemId}, #{name}, #{url}, #{day})")
    public void insert(Problem problem);
}

测试:

    void testProblemInsert() {
        problemMapper.insert(new Problem(202, "快乐数", "https://leetcode.cn/problems/happy-number/", 6));
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bVVYoWOX-1686806551631)(【MyBatis】什么是MyBatis?/image-20230615000054676.png)]

可以设置主键自增,但要先在数据库中进行相应设置。

@Options(keyProperty = "wid", useGeneratedKeys = true)

1.4 更新

类似地,传入的参数可以是一个实体。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZyCSgk6z-1686806551631)(【MyBatis】什么是MyBatis?/image-20230615003445036.png)]

2 通过XML映射文件配置SQL语句

核心:通过xml文件的配置,确定项目中某个Mapper的某个方法对应的SQL语句。

动机:使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java注解不仅力不从心,还会让本就复杂的SQL语句显得更加混乱不堪。选择何种方式来配置映射,以及是否要统一映射语句的形式,完全取决于你和你的团队。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wXajNPB0-1686806551632)(【MyBatis】什么是MyBatis?/image-20230615114025986.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SJRXMuXQ-1686806551632)(【MyBatis】什么是MyBatis?/image-20230615113702009.png)]

当调用ProblemMapper中的selectByDay方法时,Mybatis框架首先会找到相应的xml配置文件,然后找到xml配置文件中的对应方法,并执行对应的SQL语句。

<?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.helloworld.mapper.ProblemMapper">

    <select id="selectByDay" resultType="com.example.helloworld.model.Problem">
        select * from problem where day = #{day} order by problemId
    </select>

</mapper>

执行test:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2OkkUP4h-1686806551632)(【MyBatis】什么是MyBatis?/image-20230615113803764.png)]

小插件

MyBatisX:安装后点击Mapper中的方法就可以自动定位到xml文件中的SQL语句位置。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D12ks412-1686806551633)(【MyBatis】什么是MyBatis?/image-20230615115123794.png)]

3 动态SQL

if

随着用户的输入或者外部条件的变化而变化的SQL语句。

情景1:希望查询参数为空时select *,不为空时按条件查询,使用<where><if>

情景2:更新时仅更新部分属性,使用<set><if>

<where>可以自动地生成WHERE语句,当语句中没有内容时不会显示,并且可以自动地去掉多余的and或者or。

<set>可以自动地生成set语句,当语句中没有内容时不会显示,并且可以自动地去掉多余的逗号。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wJ6h67NG-1686806551633)(【MyBatis】什么是MyBatis?/image-20230615122509724.png)]

foreach

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mBt4eoFo-1686806551633)(【MyBatis】什么是MyBatis?/image-20230615130451173.png)]

<!-- 批量删除做题记录 -->
    <delete id="deleteByIds">
        delete from finished where wid in
        <!--集合名,元素名,分隔符,开始拼接符号,结束拼接符号-->
        <foreach collection="idList" item="wid" separator="," open="(" close=")">
            #{wid}
        </foreach>
    </delete>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HX7Wu55v-1686806551633)(【MyBatis】什么是MyBatis?/image-20230615130322888.png)]

sql

实现重复sql代码的复用。

如下,通过<sql><include>,实现了commonSelect的复用。

<?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.helloworld.mapper.ProblemMapper">

    <sql id="commonSelect">
        select problemId, name, url, day from problem
    </sql>

    <select id="selectByDay" resultType="com.example.helloworld.model.Problem">
        <include refid="commonSelect"/> 
        where day = #{day} order by problemId
    </select>

    <select id="list" resultType="com.example.helloworld.model.Problem">
        <include refid="commonSelect"/>
        <where>
            <if test="problemId != null"> problemId = #{problemId}</if>
            <if test="name != null"> and name = #{name}</if>
            <if test="day != null"> and day = #{day} </if>
        </where>
    </select>

</mapper>

4 文件设置总结

application.properties

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/problem_tiktok
spring.datasource.username=root
spring.datasource.password=********

# the log of mybatis
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

pom.xml

	<dependencies>

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

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

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

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

相关文章

简要介绍 | 神经辐射场(NeRF):原理、挑战与未来展望

神经辐射场(NeRF)&#xff1a;原理、挑战与未来展望 1. 背景介绍 随着深度学习和计算机图形学的不断发展&#xff0c;人工智能和图形学领域的交叉研究越来越多地受到关注。神经辐射场(NeRF)是其中一个极具潜力的研究方向&#xff0c;它结合了计算机图形学和深度学习&#xff0…

STM32驱动INMP441麦克风实现左右通道声音采集

一、参考原理图 1、INMP441 2、STM32 注意INMP441的第4引脚&#xff0c;用来选择左声道还是右声道。 二、代码生成 代码使用cubemx生成 1、iis设置 2、DMA设置 3、生成代码 三、代码修改 1、首先定义一个数组 #define BUFFER_SIZE (4)static uint32_t simpleBuf[BUFFER_S…

金属表面缺陷检测类的实践项目

【说明】&#xff1a;下面仅以Pytorch CNN Transfer Learning: Image Classifier 关于金属表面缺陷检测类的实践项目为例介绍如何创建虚拟环境以及在JuypterLab中使用对应的内核 项目已开源在https://github.com/astudent2020/Metal_Surface_Defects 提供数据集及相关代码 …

【IMDB】IMDB数据集导入PostgreSQL和join order benchmark(JOB)查询生成

目录 简述join order benchmark(JOB)查询获取IMDB导入数据到PG 简述 IMDB数据库是一个很大的&#xff0c;被广泛使用的电影&#xff0c;电视节目和演员信息的数据库&#xff0c;它包括了有关电影、电视节目、演员、制作公司、编剧、导演等信息。IMDB数据集可以为电影评论、分类…

【源码分析】Mybatis 的配置解析过程

博主介绍&#xff1a; ✌博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家✌ Java知识图谱点击链接&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; &#x1f495;&#x1f495; 感兴趣的同学可以收…

Hadoop(CentOS)安装及MapReduce实现数据去重

Hadoop&#xff08;CentOS&#xff09;安装及MapReduce实现数据去重 1. JDK安装 1.1 资源下载&#xff1a; 下载地址&#xff1a;https://pan.quark.cn/s/17d7266205f9 hadoop的安装 包 java jdk安装包 eclipse连接hadoop工具 所学其他工具可自行在官网下载 centos下载地…

Verilog 高级知识点

目录 Verilog 高级知识点 1、阻塞赋值&#xff08;Blocking&#xff09; 2、非阻塞赋值&#xff08;Non-Blocking&#xff09; 3 、assign 和 always 区别 4、什么是 latch Verilog 高级知识点 本节给大家介绍一些高级的知识点。高级知识点包括阻塞赋值和非阻塞赋值、assi…

合宙Air724UG Cat.1模块硬件设计指南--ADC接口

ADC接口 简介 ADC(Analog-to-Digital Converter) 指模数转换器。是指将连续变化的模拟信号转换为离散的数字信号的器件。 合宙Cat.1模块ADC接口主要用来检测模拟电压信号量&#xff0c;用于电池电压检测&#xff0c;温湿度检测&#xff0c;TDS检测等应用。 特性 ADC精度&#…

华为OD机试真题 JavaScript 实现【素数之积】【2022Q4 100分】

一、题目描述 RSA加密算法在网络安全世界中无处不在&#xff0c;它利用了极大整数因数分解的困难度&#xff0c;数据越大&#xff0c;安全系数越高。 给定一个32位正整数&#xff0c;请对其进行因数分解&#xff0c;找出是哪两个素数的乘积。 二、输入描述 一个正整数num …

【自动文摘】BART实现finetune及evaluate

文章目录 BART介绍下游任务 fine tune BART介绍 我最近在看自动文摘相关的预训练模型&#xff0c;BART模型是2019-2020左右提出来的&#xff0c;首先介绍下它的基本情况。 论文&#xff1a;https://arxiv.org/abs/1910.13461 github&#xff1a; fairseq例子&#xff1a;http…

Efficient Global 2D-3D Matching for Camera Localization in a Large-Scale 3D Map

文章目录 Efficient Global 2D-3D Matching for Camera Localization in a Large-Scale 3D Map1. 相似源码choose_solution.pyeight_point.pyepipolar_match.py Efficient Global 2D-3D Matching for Camera Localization in a Large-Scale 3D Map 1. 相似源码 由于paper并没…

ChatGPT带火的提示工程师,构造自己的提示语

ChatGPT是一个大语言模型&#xff0c;学过全球几乎公开的大部分有效知识库&#xff0c;它什么都懂。 ChatGPT的风靡&#xff0c;爆火了一个年薪百万的提示工程师这个新就业岗位。 提示工程师&#xff0c;也就是AI训练师&#xff0c;即通过与AI交互写出相关提示&#xff0c;以帮…

Spring Boot进阶(48):SpringBoot之集成WebSocket及使用说明 | 超级详细,建议收藏

1. 前言&#x1f525; 对于很多小伙伴来说&#xff0c;项目现在都普遍前后端分离&#xff0c;各干各的事儿&#xff0c;在前后端进行服务调用才会有大面积的碰头&#xff0c;后端接口数据格式发生变更要通知前端&#xff0c;相反&#xff0c;前端有变化要告诉后端&#xff0c;这…

【这小文章绝了!】一文看穿,MATLAB | 数组与矩阵超详细入门进阶必须看

目录 介绍 一、数组的创建和操作 通过 : 创建一维数组 通过logspace函数创建一维数组 通过linspace函数创建一维数组 二、数组的运算 数组的关系运算 数组的逻辑运算 三、矩阵 矩阵的构造 矩阵的下标引用 矩阵大小 四、矩阵元素的运算 矩阵的差分 矩阵运算 矩阵…

Spring Boot进阶(50):Spring Boot如何全局统一处理异常?| 超级详细,建议收藏

1. 前言&#x1f525; 今天和大家讨论的是Spring Boot如何统一处理异常。这里先说一下我们为什么需要全局统一处理异常&#xff1f;其实理由很简单&#xff0c;因为程序在运行的过程中&#xff0c;不可避免会产生各种各样的错误。比如说用户传过来的参数不正确&#xff0c;无法…

4端到端协议-4.2【实验】【计算机网络】

4端到端协议-4.2【实验】【计算机网络】 前言推荐4端到端协议4.2 TCP协议流捕获与TCP协议分析实验目的实验内容及实验环境实验原理实验过程实验过程演示 4.2.1实验章节测验一.单选题&#xff08;共5题,25.0分&#xff09;二.阅读理解&#xff08;共1题,70.0分&#xff09;三.填…

xxl-job核心源码解析

xxl-job源码解析 如何自研一个xxljob 注册服务调度服务RPC组件(基建&#xff0c;底层严重依赖)日志服务告警服务 系统架构 执行流程 各大调度中心对比 1&#xff09;服务端启动流程 首先找到配置类 XxlJobAdminConfig 可以发现该类实现 InitializingBean接口&#xff0c;…

openpose保姆级教程代码详细解析——训练部分

一&#xff1a;前言 OpenPose是一个基于深度学习的人体姿势估计库&#xff0c;它可以从图像或视频中准确地检测和估计人体的关键点和姿势信息。OpenPose的目标是将人体姿势估计变成一个实时、多人、准确的任务。它的原理部分已经在上一篇非常详细的讲解了——本节介绍训…

Dynamic .NET TWAIN 8.3.3 for NetCore Crack

用于 WinForms 和 WPF 应用程序的扫描仪和网络摄像头捕获 SDK 适用于 .NET 应用程序的简单高效的扫描和网络摄像头 SDK Dynamsoft 的 Dynamic .NET TWAIN 是一个基于 TWAIN 和 DirectShow 标准的 .NET 文档成像 SDK。它为扫描仪和网络摄像头软件开发提供了丰富、高效且…

修改依赖包下的子依赖版本,前端项目安全扫描出来的漏洞——解决过程

为什么要升级&#xff0c;如图云桌面&#xff08;相当于堡垒机-远程桌面&#xff09;的项目审查是大概基于node16版本进行扫描的&#xff0c;本来我方是通过降版本从14到12绕过大范围更新&#xff0c;但现在躲得过初一躲不过十五&#xff0c;如何更新 package-lock.json 中的一…