首页 > 其他分享 >MyBatis学习笔记第一天

MyBatis学习笔记第一天

时间:2024-08-05 20:53:40浏览次数:14  
标签:第一天 数据库 笔记 参数 SQL MyBatis id staff

引言

数据持久化是将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中数据模型的统称。例如,文件的存储、数据的读取以及对数据表的增删改查等都是数据持久化操作。

MyBatis 支持定制化 SQL、存储过程以及高级映射,可以在实体类和 SQL 语句之间建立映射关系,是一种半自动化的 ORM 实现。其封装性低于 Hibernate,但性能优秀、小巧、简单易学、应用广泛。

ORM(Object Relational Mapping,对象关系映射)是一种数据持久化技术,它在对象模型和关系型数据库之间建立起对应关系,并且提供了一种机制,通过 JavaBean 对象去操作数据库表中的数据。
MyBatis 前身为 IBatis,2002 年由 Clinton Begin 发布。2010 年从 Apache 迁移到 Google,并改名为 MyBatis,2013 年又迁移到了 Github。

MyBatis 的主要思想是将程序中的大量 SQL 语句剥离出来,使用 XML 文件或注解的方式实现 SQL 的灵活配置,将 SQL 语句与程序代码分离,在不修改程序代码的情况下,直接在配置文件中修改 SQL 语句。

MyBatis 与其它持久性框架最大的不同是,MyBatis 强调使用 SQL,而其它框架(例如 Hibernate)通常使用自定义查询语言,即 HQL(Hibernate查询语言)或 EJB QL(Enterprise JavaBeans查询语言)

第一个MyBatis程序(对数据库数据的增删改操作)

添加依赖

在pom.xml中添加mybatis和数据库连接的依赖

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

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.26</version>
        </dependency>

配置数据源

作用是将数据库和java程序连接,需要设置数据库的用户名,密码,驱动名和要操作的数据库名字
同时,配置Mapper文件路径和别名以及日志级别

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

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

logging:
  level:
    org.example.dao: debug

三种接收数据方式

在使用MyBatis进行数据库操作时,接收和传递数据的方法需要谨慎选择,以确保安全性和可维护性。接收数据的方式主要有三种:通过Mapper直接接收,通过简单的字符串传递,以及通过封装类传递。

  1. Mapper直接接收参数(不推荐)
    Mapper直接接收参数虽然简单,但是存在潜在的安全隐患,特别是当传递参数直接拼接到SQL语句中的时候,会导致SQL注入
    缺点:
    容易引起SQL注入。
    代码维护性差,特别是当参数增多时

  2. 通过简单字符串传递参数(不推荐)
    将参数拼接成字符串传递,虽然能够避免一些简单场景下的拼接问题,但如果参数量较多或者包含特殊字符,就不太适用了
    缺点:
    当参数较多时,字符串拼接会变得不堪重负。
    维护和阅读性差。

  3. 封装类接收参数(推荐)–有效防止SQL注入
    通过使用封装类(POJO,Plain Old Java Object),可以将多个参数封装到一个对象中传递。这种方法不仅能提高代码的可读性和可维护性,还能有效防止SQL注入。

所以我们编写封装类

编写封装类

salary薪资,在数据库中建议使用Decimal定义,用于精确计算金额

import java.math.BigDecimal;

public class Staff {
    private int id;
    private String code;
    private String name;
    private BigDecimal salary;
    private String username;
    private String userpass;

定义mapper

${…} 和 #{…}区别

  1. ${…}
    . . . 是字符串替换,将表达式的结果直接拼接到 S Q L 中,不进行预编译处理。作用: {...} 是字符串替换,将表达式的结果直接拼接到 SQL 中,不进行预编译处理。 作用: ...是字符串替换,将表达式的结果直接拼接到SQL中,不进行预编译处理。作用:{…} 用于替换变量,可以是字段名、表名、条件等,不进行类型转换或预处理。

示例:

<select id="getUserById" resultType="User">
  SELECT * FROM users WHERE id = ${userId}
</select>

如果 userId 是 1,则实际执行的 SQL 是 SELECT * FROM users WHERE id = 1。

注意事项:
${…} 可能导致 SQL 注入攻击,因为它直接将内容替换到 SQL 中,不会对输入进行处理和验证。

  1. #{…}
    #{…} 是参数占位符,MyBatis 会将该参数预编译成 JDBC 可以识别的格式,可以防止 SQL 注入攻击。
    作用:#{…} 用于传递参数,MyBatis 会将参数转换为对应的 JDBC 类型,并进行预编译处理,以防止 SQL 注入。

示例:

<select id="getUserById" resultType="User">
  SELECT * FROM users WHERE id = #{userId}
</select>

如果 userId 是 1,MyBatis 会预处理成 PreparedStatement,然后执行查询。

优势:
安全性更高:预编译参数可以防止 SQL 注入攻击,因为输入参数不会直接拼接到 SQL 语句中。
支持多种数据库的类型转换:MyBatis 会根据数据库的类型自动转换参数。

区别总结:
${…} 是简单的字符串替换,用于动态拼接 SQL 中的字段名、表名或条件等。
#{…} 是参数化的占位符,用于传递参数并且可以防止 SQL 注入,适合用于传递参数值。

在使用 MyBatis 时,推荐使用 #{…} 来传递参数,以确保安全性和数据库类型的正确转换,避免可能的 SQL 注入问题。

SQL 注入(SQL Injection)

是一种常见的安全漏洞,指的是攻击者通过向应用程序的输入字段插入恶意的 SQL 语句,从而利用应用程序对数据库的访问权限执行未经授权的操作。具体来说,SQL 注入是利用应用程序没有正确过滤或转义用户输入的情况下,将恶意的 SQL 代码插入到查询语句中的一种攻击方式。

SQL 注入通常发生在以下情况下:
未正确过滤用户输入:如果应用程序在构建 SQL 查询时,直接将用户提供的数据插入到 SQL 查询中,而没有对输入进行充分验证和过滤,攻击者可以通过输入特定的字符或结构改变原始查询的意图。
动态拼接 SQL 语句:如果应用程序使用字符串拼接的方式构建 SQL 查询,而不是使用参数化查询(Prepared Statement),攻击者可以在输入中插入 SQL 片段,从而改变查询的行为。

攻击方法:
绕过身份验证和授权:通过注入恶意的 SQL 查询,攻击者可以绕过登录认证或者获取未授权的访问权限。
窃取敏感信息:攻击者可以利用注入来获取数据库中的敏感信息,如用户凭据、个人数据等。
修改数据:攻击者可以修改数据库中的数据,包括插入新数据、更新或删除现有数据,甚至是完全删除表格。
执行管理操作:攻击者可以执行数据库管理操作,如创建、删除表格或者数据库。

定义mapper

<?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="org.example.dao.IStaffDao">
    <!--SQL语句-->
    
    <insert id="addStaff">
        insert into staff(code,name,salary,username,userpass)
        value(#{code},#{name},#{salary},#{username},#{userpass})
    </insert>

    <delete id="delStaff">
        delete from staff where id=#{id}
    </delete>

    <update id="editStaff">
        update staff set name=#{name},salary=#{salary},
        username=#{username},userpass=#{userpass} where id=#{id}
    </update>
</mapper>

定义数据访问层接口

import org.apache.ibatis.annotations.Mapper;
import org.example.bean.Staff;

@Mapper
public interface IStaffDao {
    String getNow();
    int addStaff(Staff staff);
    int delStaff(int id);
    int editStaff(Staff staff);
}

编写业务层

@RestController
public class EasyController {
    @Autowired
    IStaffDao dao;
    @GetMapping("now")
    public String now(){
        return dao.getNow();
    }
    @PostMapping("staff")
    public String addStaff(Staff staff){
        dao.addStaff(staff);
        return "success";
    }
    @DeleteMapping("staff/{id}")
    public String delStaff(@PathVariable int id){
        dao.delStaff(id);
        return "success";
    }
    @PutMapping("staff")
    public String editStaff(Staff staff){
        dao.editStaff(staff);
        return "success";
    }
}

编写启动类

@SpringBootApplication
public class EasySpringMybatis {
    public static void main(String[] args) {
        SpringApplication.run(EasySpringMybatis.class,args);
    }
}

程序运行

程序运行后,搭配使用java编程程序(idea或其他),数据库管理程序(navicat或其他)和Apipost检验程序是否运行正常

标签:第一天,数据库,笔记,参数,SQL,MyBatis,id,staff
From: https://blog.csdn.net/Word_seeker/article/details/140936168

相关文章

  • 【笔记】非传统题选讲 2024.8.5
    今天睡着了。发了只是为了完整性。[CF1672E]notepad.exe先二分得到总长度\(\suml_i+n-1\)记为\(w_1\),然后考虑其它行数\(h\),最优的情况只能是每一行都用换行顶替一个空格,此时面积为\(w_h\cdoth=w_1-h+1\),所以\(w_h=\left\lfloorw_1/h\right\rfloor\)为唯一可能更新答......
  • Tpora学习笔记
    Markdown学习标题一级标题:#+空格二级标题:##+空格三级标题:###+空格字体字体加粗用:**字体变为斜体用:*既是斜体又是粗体:***划线:~~引用引用的别人的用:>分割线分割线用:—图片图片用:!+[]+()注意:中间没有加号,我家了空格是为了看效果,如下图超链接超......
  • 南京大学计算机基础(四)踩坑笔记
    第六周缓冲区溢出章节bang问题:每次输入的id将影响getbuf中的堆栈位置,用-u12的ebp和-u123的ebp位置就不一样。注意汇编代码中不能出现a0(代表换行符),如果地址有a0就将它随便改改就行了(a0改为a8-0x8)。注意gdb如果不能重定向,可能是因为你修改了gdbinit:https://stackoverflo......
  • Spring Cloud微服务项目集成MyBatis
            在现代软件开发中,微服务架构已经成为一种流行的解决方案,它能够将应用程序拆分成多个小的、独立的服务。每个服务负责一个特定的业务功能,并可以独立部署和扩展。SpringCloud是一个提供各种工具和框架以支持微服务开发的开源框架,而MyBatis是一个流行的持久层......
  • 【做题笔记】板刷 AtCoder
    [ABC364D]K-thNearest很好想的题目。首先可以考虑到答案具有单调性,所以对于每一次询问用二分处理即可。然后考虑如何判合法。我们需要找到所有\(a_i-b\)中\(\lex\)且\(\ge-x\)的个数。可以现将\(a_i\)排好序,最后用两个二分统计个数看是否\(\gek\)即可。时间复......
  • 线程相关个人笔记总结
    什么是线程和进程进程是一个程序的实例,线程是进程中的实体,一个进程有多个线程线程的创建方式1.继承Thread类重写run() 创建一个类继承自Thread类,并重写run()方法来定义线程执行的任务。通过创建该类的实例并调用start()方法来启动线程。classMyThreadextends......
  • 学习笔记 韩顺平 零基础30天学会Java(2024.8.5)
    P460八大Wrapper类     黄色的父类是number,黑色的是自己独立的P461装箱和拆箱     手动装箱示例:                             intn1=100;                Intergerinterger=newInterger(n1);//......
  • 加固三防笔记本电脑:保护数据安全的首选设备
    随着信息技术的飞速发展,笔记本电脑早已成为现代生活中不可或缺的工具。然而,普通的笔记本电脑无法适应一些特殊的环境,在数据安全保护方面也有着一定的风险。加固三防笔记本电脑则是保护数据安全的首选设备。下面将介绍加固三防笔记本电脑的特点及应用。一、加固三防笔记本电脑......
  • 【Python学习手册(第四版)】学习笔记14-迭代器和列表解析(一)
    个人总结难免疏漏,请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。本文主要以通俗易懂的语言介绍迭代器(文件迭代、手动迭代iter和next等),列表解析式包括基础知识包括写法、文件上使用列表解析、扩展列表解析语法等,对列表解析不懂的同学着重推荐......
  • HCIE学习笔记(持续补充更新):OSPF 五种报文、LSA
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、OSPF基础1、OSPF三张表2、OSPF建立邻接关系的过程2.1建立邻居关系2.2主/从关系协商、DD报文交换2.3、LSDB同步(LSA请求、LSA传输、LSA应答)二、OSPF报文OSPF报头1、OSPFHello报文(选DR、B......