MyBatis进阶:告别SQL注入!MyBatis分页与特殊字符的正确使用方式

news2024/11/26 2:40:59

 

目录

引言

一、使用正确的方式实现分页

1.1.什么是分页

1.2.MyBatis中的分页实现方式

1.3.避免SQL注入的技巧

二、特殊字符的正确使用方式

2.1.什么是特殊字符

2.2.特殊字符在SQL查询中的作用

2.3.如何避免特殊字符引起的问题

2.3.1.使用CDATA区段 

2.3.2.使用实体引用

三、总结和展望 

3.1.MyBatis的优点和不足 

优点

不足之处

3.2.未来发展趋势和应用场景


引言

SQL注入是一种常见的数据库攻击手段,它利用了程序员在编写代码时疏忽,通过SQL语句,实现无账号登录,甚至篡改数据库。举个例子,如果一个网站没有对用户输入的字符串进行过滤、转义、限制或处理不严谨,那么攻击者就可以通过输入精心构造的字符串去非法获取到数据库中的数据  。

SQL注入的坏处包括但不限于:窃取敏感信息、破坏数据、影响系统稳定性等  。

SQL注入案例:

当用户输入的数据直接拼接到SQL语句中时,如果用户输入恶意数据,例如 ' OR '1'='1,那么整个SQL语句会变成:

SELECT * FROM users WHERE name = '' OR '1'='1';

由于1=1 永远为真,所以这个SQL语句会返回所有用户记录。这就是一个典型的SQL注入攻击。如果使用MyBatis的动态SQL功能,用户可以在查询语句中直接输入变量名,而MyBatis会将这些变量替换为对应的值。如果用户输入的值包含恶意代码,那么就会导致SQL注入问题。

下面来看看我们怎么解决的吧!!👇👇

一、使用正确的方式实现分页

1.1.什么是分页

分页是一种操作系统里存储器管理的一种技术,可以使电脑的主存可以使用存储在辅助存储器中的数据。操作系统会将辅助存储器(通常是磁盘)中的数据分区成固定大小的区块,称为“页”。当不需要时,将当前访问的页从内存中换出,放入磁盘中,以便下次访问时再将其读入内存。这样,每次只需要读取所需的那一页数据,就可以避免一次性读取大量数据导致内存不足的问题。

举个例子,如果我们需要在一个网站上查看文章列表,但是每篇文章都有很多内容,如果我们一次性将所有文章全部加载到浏览器中,那么可能会导致浏览器崩溃。而如果我们使用分页技术,每次只加载一篇文章的内容,这样就可以避免这个问题。

MyBatis分页插件提供了多种分页方式,可以满足不同场景下的需求。例如,可以使用物理分页和逻辑分页两种方式来实现分页查询。物理分页是指将数据分成固定大小的块进行查询,而逻辑分页则是根据用户需求进行查询。使用MyBatis分页插件可以方便地实现这些功能,并且可以避免SQL注入等安全问题。

1.2.MyBatis中的分页实现方式

MyBatis中有多种分页实现方式,其中比较常用的有以下几种:

        1.物理分页:将数据分成固定大小的块进行查询。这种方式的优点是速度快,但是缺点是占用内存大,不适用于数据量大的情况。

<select id="selectUsersByPage" parameterType="map" resultType="User">
    SELECT * FROM user
    LIMIT #{start}, #{size}
</select>

        2.逻辑分页:根据用户需求进行查询。这种方式的优点是可以根据用户需求进行查询,灵活性高,但是缺点是需要手动编写SQL语句,维护成本高。

public List<User> selectUsersByPage(int pageNum, int pageSize) {
    int start = (pageNum - 1) * pageSize;
    int end = start + pageSize;
    List<User> users = userMapper.selectAllUsers();
    if (start < users.size()) {
        users = users.subList(start, end);
    }
    return users;
}

        3.MyBatis分页插件:提供了多种分页方式,可以满足不同场景下的需求。例如,可以使用物理分页和逻辑分页两种方式来实现分页查询。使用MyBatis分页插件可以方便地实现这些功能,并且可以避免SQL注入等安全问题。

我接下来要介绍的是第三种方式MyBatis分页插件,利用插件完成分页共有以下四步:

①导入pom依赖

 <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.1.2</version>
    </dependency>

②Mybatis.cfg.xml配置拦截器

<plugins>
    <!-- 配置分页插件PageHelper, 4.0.0以后的版本支持自动识别使用的数据库 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
    </plugin>
</plugins>

注意事项:该标签不能写在<environments>后面,因为该文件的DTD约束了每个标签的先后顺序

③使用PageHelper进行分页

BookMapper.xml

<select id="listPager" resultType="com.csdn.xw.model.Book" parameterType="java.lang.String">
  select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%')
</select>

BookMapper

 List<Book> listPager(@Param("bname") String bname);

BookBiz

List<Book> listPager(String bname);

BookBizImpl

package com.csdn.xw.biz.Impl;

import com.csdn.xw.biz.BookBiz;
import com.csdn.xw.mapper.BookMapper;
import com.csdn.xw.model.Book;

import java.util.List;

/**
 * @author Java方文山
 * @compay csdn_Java方文山
 * @create 2023-08-19-13:41
 */
public class BookBizImpl implements BookBiz {
    private BookMapper bookMapper;

    public BookMapper getBookMapper() {
        return bookMapper;
    }

    public void setBookMapper(BookMapper bookMapper) {
        this.bookMapper = bookMapper;
    }


    @Override
    public List<Book> listPager(String bname) {
        return bookMapper.listPager(bname);
    }
}

BookBizImplTest

package demo;

import com.csdn.xw.biz.Impl.BookBizImpl;
import com.csdn.xw.mapper.BookMapper;
import com.csdn.xw.util.SessionUtil;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

/**
 * @author Java方文山
 * @compay csdn_Java方文山
 * @create 2023-08-19-13:46
 */
public class demo1 {

    private BookBizImpl bookBiz = new BookBizImpl();
    SqlSession sqlSession;

    @Before
    public void setUp() throws Exception {
        System.out.println("初始换方法。。。");
        //工具类中获取session对象
        sqlSession = SessionUtil.openSession();
        //从session对象中获取mapper对象
        BookMapper mapper = sqlSession.getMapper(BookMapper.class);
        bookBiz.setBookMapper(mapper);
    }

    @After
    public void tearDown() throws Exception {
        System.out.println("方法测试结束。。");
        sqlSession.commit();
    }


    @Test
    public void listPager() {
        System.out.println("测试的mybatis的分页插件方法");
        PageHelper.startPage(1, 10); // 第1页,每页10条数据
        System.out.println("当前页数:"+PageHelper.getLocalPage().getPageNum()+"当前页展示数:"+PageHelper.getLocalPage().getEndRow());
        bookBiz.listPager("圣墟").forEach(System.out::println);
    }


}

④处理分页结果

 

1.3.避免SQL注入的技巧

  1. 使用参数化查询:使用参数化查询是防止SQL注入的最有效方法之一。通过将查询参数化,将用户提供的输入值作为参数传递给查询,而不是将输入值直接拼接到SQL语句中。这样可以确保输入值被正确地转义和处理,减少SQL注入的风险。

  2. 使用存储过程:存储过程是一种在数据库中预编译的SQL代码块,可以通过调用存储过程来执行SQL操作。使用存储过程可以避免SQL注入,因为它们不允许用户直接输入数据,而是使用预先定义好的参数来传递数据。

  3. 过滤用户输入:对用户输入进行过滤和验证,确保输入数据的合法性。例如,可以使用正则表达式或白名单来限制用户输入的字符集,或者限制输入长度等。

二、特殊字符的正确使用方式

2.1.什么是特殊字符

在Mybatis中,特殊字符是指在XML文件中需要转义的字符。这些字符包括:&、<、>、"、'、/等。为了避免这些字符对XML文件造成影响,我们需要对它们进行转义。

2.2.特殊字符在SQL查询中的作用

在SQL查询中,特殊字符可以用来进行模糊查询。其中,%表示任何字符出现任意次数(可以是0次),而_表示一个字符。除此之外,还有一些其他的字符,比如[]^\\等等,它们也可以用来进行模糊查询。

例如,假设有一个名为"users"的表,其中包含一个名为"name"的列,我们可以使用以下语句来查找名字以字母"A"开头的所有用户:

SELECT * FROM users WHERE name LIKE 'A%';

这将返回所有名字以字母"A"开头的用户。另外,如果我们想要查找名字中包含两个字母"A"的用户,我们可以使用以下语句:

SELECT * FROM users WHERE name LIKE '%A%A%';

2.3.如何避免特殊字符引起的问题

先来一个没有特殊处理过的

BookMapper.xml

<select id="listPagerS" resultType="com.csdn.xw.model.Book" parameterType="java.util.Map">
  select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%') and price < #{max}
</select>

BookBizImplTest 

 @Test
    public void listPagerS() {
        System.out.println("没有处理特殊字符之前");
        Map map=new HashMap();
        map.put("dname","圣墟");
        map.put("max",20);
        bookBiz.listPagerS(map).forEach(System.out::println);
    }

测试结果:

直接报红了,因为有些特殊字符是需要处理的,下面我来给大家介绍两种处理方案:

2.3.1.使用CDATA区段 

CDATA区段是XML中的一个元素,它包含了不会被解析器解析的文本。一个CDATA区段中的标签不会被视为标记,同时实体也不会被展开。主要的目的是为了包含诸如XML片段之类的材料,而无需转义所有的分隔符 。

我们只需在需要有特殊字符的地方加上<![CDATA[ "含带特殊字符"]]>即可

BookMapper.xml

  <select id="listPagerS" resultType="com.csdn.xw.model.Book" parameterType="java.util.Map">
  select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%') and <![CDATA[  price <#{max}]]>
</select>

这时候再来看看效果:

2.3.2.使用实体引用

在XML中,一些字符具有特殊的意义,比如<>&等符号。如果我们需要在文本中使用这些符号,就需要将它们转义为对应的实体引用。例如,<应该被转义为&lt;>应该被转义为&gt;&应该被转义为&amp;

BookMapper.xml

 <select id="listPagerS" resultType="com.csdn.xw.model.Book" parameterType="java.util.Map">
  select * from t_mvc_book where bname like concat(concat('%',#{bname}),'%') and   price &gt; #{max}
</select>

测试效果:

以下是一些常见的需要转义的XML特殊字符及其对应的实体引用: 

特殊字符实体引用
<&lt;
>&gt;
&&amp;
"&quot;
'&apos;
/&#x2F;
\&#x5C;
"&quot;
'&apos;

 

三、总结和展望 

3.1.MyBatis的优点和不足 

优点

  1. 灵活:MyBatis提供了高度可配置的选项来满足不同需求,支持多种数据库和数据源。
  2. 易于使用:MyBatis提供了简单直观的SQL映射文件和接口,使得开发人员能够快速上手并编写高效的SQL语句。
  3. 解耦性高:MyBatis将SQL语句与Java代码分离,使得开发人员可以专注于业务逻辑的开发,而不需要关心底层的数据访问细节。
  4. 缓存支持:MyBatis提供了一级缓存和二级缓存的支持,可以提高查询性能。
  5. 动态SQL:MyBatis支持动态SQL,可以根据不同的条件生成不同的SQL语句,提高了SQL语句的灵活性。

不足之处

  1. 学习曲线较陡峭:相对于其他持久层框架,MyBatis的学习曲线较为陡峭,需要一定的时间来熟悉其配置和使用方式。
  2. XML配置文件复杂:MyBatis使用XML配置文件来定义SQL映射关系,对于复杂的SQL语句和大量的映射关系,XML配置文件可能会变得冗长且难以维护。
  3. SQL语句优化困难:由于MyBatis将SQL语句与Java代码分离,对于复杂的SQL语句优化可能需要额外的工作。

3.2.未来发展趋势和应用场景

  1. 自动化生成:随着AI技术的发展,MyBatis有望通过自动化生成技术减少手动编写SQL语句的工作量,提高开发效率。
  2. 插件化扩展:MyBatis可以通过插件化的方式扩展其功能,满足不同场景的需求,如分页插件、缓存插件等。
  3. 云原生支持:随着云计算的普及,MyBatis可以进一步提供云原生的支持,如容器化部署、微服务架构等。
  4. 多租户支持:随着多租户应用的兴起,MyBatis可以提供更好的多租户支持,如数据隔离、权限控制等。
  5. 大数据处理:MyBatis可以结合大数据处理框架(如Spark、Flink)进行大规模数据的处理和分析。
  6. 低代码开发平台:随着低代码开发平台的兴起,MyBatis可以作为其核心组件之一,提供快速搭建数据模型和数据访问的能力。

综上所述,MyBatis作为一种优秀的持久层框架,在未来将继续发挥重要作用。虽然存在一些不足之处,但随着技术的不断发展和创新,相信MyBatis将会不断改进和完善,为开发者提供更多便利和支持。

到这里我的分享就结束了,欢迎到评论区探讨交流!!

如果觉得有用的话还请点个赞吧 ♥  ♥

 

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

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

相关文章

微服务中间件--MQ服务异步通信

MQ服务异步通信 MQ服务异步通信a.消息可靠性1) 生产者消息确认2) 消息持久化3) 消费者消息确认4) 消费者失败重试4.a) 本地重试4.b) 失败策略 b.死信交换机1) 初识死信交换机2) TTL3) 延迟队列a) 安装延迟队列插件b) SpringAMQP使用延迟队列插件 c.惰性队列1) 消息堆积问题2) 惰…

redis实战-缓存三剑客穿透击穿雪崩解决方案

缓存穿透 定义 缓存穿透 &#xff1a;缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;这些请求都会打到数据库&#xff0c;造成数据库压力&#xff0c;也让缓存没有发挥出应有的作用 解决方案 缓存空对象 当我们客户端…

《Go 语言第一课》课程学习笔记(十一)

控制结构 if 的“快乐路径”原则 针对程序的分支结构&#xff0c;Go 提供了 if 和 switch-case 两种语句形式&#xff1b;而针对循环结构&#xff0c;Go 只保留了 for 这一种循环语句形式。 if 语句 if 语句是 Go 语言中提供的一种分支控制结构&#xff0c;它也是 Go 中最常…

人机对抗智能-部分可观测异步智能体协同(POAC)

环境链接&#xff1a;数据中心-人机对抗智能 (ia.ac.cn)http://turingai.ia.ac.cn/data_center/show/10 1.环境配置 Ubuntu 20.04 Anaconda python版本3.6 1.1 安装torch0.4.1失败 参考文章&#xff1a; 安装torch0.4.1的神坑_torch0.4.1_DEMO_Tian的博客-CSDN博客 co…

外卖点餐系统开发定制:数字化餐饮体验的新里程

在现代社会&#xff0c;外卖已经成为了人们日常生活的一部分。为了更好地满足消费者的需求&#xff0c;外卖点餐系统开发定制成为了餐饮业的一个重要方向。通过数字化技术&#xff0c;商家能够为消费者提供更加个性化、便捷的订餐体验。本文将深入探讨外卖点餐系统开发定制&…

《中国区块链发展报告(2023)》发布 和数集团推动区块链发展

北京区块链技术应用协会与社会科学文献出版社日前在京共同发布《区块链蓝皮书&#xff1a;中国区块链发展报告&#xff08;2023&#xff09;》。蓝皮书归纳梳理了2022年区块链产业发展现状及趋势&#xff0c;并结合行业热点Web3.0、AIGC&#xff0c;探讨我国区块链发展的热点话…

Vue脚手架安装(全网最详细)

目录 1、环境准备 1.1 安装node 1.1.2 判断你是否安装成功 1.1.3 在命令提示符中查看node版本 1.2 安装webpack 1.3 安装vue-cli3.x以上 2、创建工程 2.1 创建 2.2 选择 2.2.1 选择自定义设置&#xff1a; 2.2.2 选择Vue版本&#xff1a; 2.2.3 是否使用历史模式选择…

应用在红外遥控领域中的心率传感信号接收芯片

远程遥控技术又称为遥控技术&#xff0c;是指实现对被控目标的遥远控制&#xff0c;在工业控制、航空航天、家电领域应用广泛。红外遥控是一种无线、非接触控制技术&#xff0c;具有抗干扰能力强&#xff0c;信息传输可靠&#xff0c;功耗低&#xff0c;成本低&#xff0c;易实…

力扣HOT100.4,两个正序数组的中位数,拓展寻找第K小

题目&#xff1a;给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 输入&#xff1a;nums1 [1,3], nums2 [2] 输出&#xff1a;2.00000 解释&#xff1a;合并数组 [1,2,3] &#xff0c;中位…

不会编写正则表达式?试试“biu正则”,体验点一下就给你想要的正则表达式!

biu正则介绍 “biu正则”是一款非常实用的正则表达式生成工具。它的主要功能是帮助用户快速生成各种正则表达式&#xff0c;从而减少编写正则表达式的时间。比如&#xff0c;如果您需要编写一个匹配邮箱的正则表达式&#xff0c;只需要输入一个邮箱地址&#xff0c;点击“Clik…

横扫“盲区”、“看透”缺陷,维视智造推出短波红外相机

在可见光领域&#xff0c;工业相机的视觉应用已经十分成熟&#xff0c;但在日常的客户咨询中&#xff0c;我们也经常接到一些“超纲需求”——客户想要检测“白底上的白色缺陷”、“不透明包装内的透明物体有无”等&#xff0c;均属于可见光无法实现的检测&#xff0c;而市面上…

gPRC与SpringBoot整合教程

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

基于静态编译构建微服务应用

作者&#xff1a;饶子昊&#xff08;铖朴&#xff09; Java 的局限性 传统的一个 Java 应用从代码编写到启动运行大致可以分为如下步骤&#xff1a; 首先&#xff0c;编写 .java 源代码程序。然后&#xff0c;借助 javac 工具将 .java 文件翻译为 .class 的字节码&#xff0…

【Python】强化学习:原理与Python实战

搞懂大模型的智能基因&#xff0c;RLHF系统设计关键问答 RLHF&#xff08;Reinforcement Learning with Human Feedback&#xff0c;人类反馈强化学习&#xff09;虽是热门概念&#xff0c;并非包治百病的万用仙丹。本问答探讨RLHF的适用范围、优缺点和可能遇到的问题&#xff…

再学http-为什么文件上传要转成Base64?

1 前言 最近在开发中遇到文件上传采用Base64的方式上传&#xff0c;记得以前刚开始学http上传文件的时候&#xff0c;都是通过content-type为multipart/form-data方式直接上传二进制文件&#xff0c;我们知道都通过网络传输最终只能传输二进制流&#xff0c;所以毫无疑问他们本…

pycharm的【陷阱】,你中过招吗?

一直以来&#xff0c;也有不少初学 python 的小伙伴&#xff0c;一不小心就跳进了虚拟环境和系统环境的【陷阱】中。 本文就基于此问题&#xff0c;来说说在 pycharm 当中如何使用系统环境、虚拟环境。 pycharm 当中&#xff0c;每一个项目在运行时&#xff0c;都需要指定一个…

GIS、CAD数据为基础进行城市排水系统水力建模,水力模拟在排水防涝、海绵城市设计等应用方法,城市内涝一维二维耦合水力计算原理,利用软件工具实现城市内涝模拟

目录 专题一 数据准备 专题二 建立模型 专题三 模拟计算 专题四 海绵城市关键控制指标计算 专题五 其他功能 更多应用 随着计算机的广泛应用和各类模型软件的发展&#xff0c;将排水系统模型作为城市洪灾评价与防治的技术手段已经成为防洪防灾的重要技术途径。本次将聚焦…

事件捕获和事件冒泡

事件捕获和事件冒泡与事件流有关系。 以下代码&#xff0c;点击 aa &#xff0c;控制台会打印什么呢&#xff1f; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content&q…

文件容灾备份方案,软件容灾备份方案

信息是企业的核心资产。然而&#xff0c;信息数据丢失的风险接踵而至。事故系统异常、病毒攻击、硬件损坏和自然灾害都可能导致重要数据的丢失。这就是为什么文档灾难恢复备份计划如此重要。本文将详细介绍文档灾难恢复备份计划的必要性&#xff0c;以及如何实施有效的备份方案…

数据结构(7)

B树 B树中允许一个节点拥有多个key。设定参数M&#xff0c;构造B树 1.每个结点最多右M-1个key&#xff0c;并且以升序排列 2.每个结点最多右M个子结点 3.根节点至少右两个子结点 通过磁盘预读&#xff0c;将数据放到B树中&#xff0c;3层B树可容纳1024*1024*1024差不多10亿…