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

 

目录

引言

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

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 userLIMIT #{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;}@Overridepublic 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;@Beforepublic void setUp() throws Exception {System.out.println("初始换方法。。。");//工具类中获取session对象sqlSession = SessionUtil.openSession();//从session对象中获取mapper对象BookMapper mapper = sqlSession.getMapper(BookMapper.class);bookBiz.setBookMapper(mapper);}@Afterpublic void tearDown() throws Exception {System.out.println("方法测试结束。。");sqlSession.commit();}@Testpublic 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 

 @Testpublic 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.hqwc.cn/news/81350.html

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

相关文章

BDA初级分析——可视化基础

一、可视化的作用 数据可视化——利用各种图形方式更加直观地呈现数据的过程 可视化的作用 1、更快地理解数据&#xff0c;找出数据的规律和异常 2、讲出数据背后的故事&#xff0c;辅助做出业务决策 3、给非专业人士提供数据探索的能力 数据分析问题如何通过可视化呈现&am…

使用css实现点击切换active效果

不使用js&#xff0c;纯css实现点击切换active样式 一个父盒子中嵌套小标签,横向排列 html <div class"box"><a href"#">选项1</a><a href"#">选项2</a><a href"#">选项3</a><a href&…

Bootstrap的类container与类container-fluid有什么区别?

阅读本文前建议先阅读下面两篇博文&#xff1a; 怎么样通过Bootstrap已经编译好(压缩好)的源码去查看符合阅读习惯的源码【通过Source Map(源映射)文件实现】 在CSS中&#xff0c;盒模型中的padding、border、margin是什么意思&#xff1f; 以下是Bootstrap的类 container 的盒…

vue离线缓存资源文件

本文章主要是解决大文件,实时请求资源浪费网络资源的问题 从而有效的将解决用户体验的问题 话不多说上才艺 ⬇️⬇️⬇️⬇️⬇️⬇️⬇️ 找到项目中的 index.html 文件,并在 html 标签中加入 manifest"manifest.appcache" 安装 appcache-manifest 包 npm ins…

Maven 一键部署到 SSH 服务器

简介 利用 Maven Mojo 功能一键部署 jar 包或 war 包到远程服务器上。 配置 在 maven 的setting.xml 配置服务器 SSH 账号密码。虽然可以在工程的 pom.xml 直接配置&#xff0c;但那样不太安全。 <servers><server><id>iq</id><configuration&…

5、Spring_DI注解开发

DI 注解开发 1.目前面临问题 建立 mapper public interface EmployeeMapper {void save(); }建立 mapper 实现类 Repository public class EmployeeMapperImpl implements EmployeeMapper {public void save(){System.out.println("保存员工信息");} }建立 service …

人机对抗智能-部分可观测异步智能体协同(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…

CTFshow——web入门——反序列化web254-web278 详细Writeup

前言 在做题之前先简要总结一下知识点 private变量会被序列化为&#xff1a;\x00类名\x00变量名 protected变量会被序列化为: \x00\*\x00变量名 public变量会被序列化为&#xff1a;变量名__sleep() &#xff1a;//在对象被序列化之前运行__wakeup() //将在反序列化之后立即…

日志搞不定?手把手教你如何使用Log4j2

系列文章目录 从零开始&#xff0c;手把手教你搭建Spring Boot后台工程并说明 Spring框架与SpringBoot的关联与区别 SpringBean生成流程详解 —— 由浅入深(附超精细流程图) Spring监听器用法与原理详解 Spring事务畅谈 —— 由浅入深彻底弄懂 Transactional注解 面试热点详解…

Java实现一个简单的图书管理系统(内有源码)

简介 哈喽哈喽大家好啊&#xff0c;之前作者也是讲了Java不少的知识点了&#xff0c;为了巩固之前的知识点再为了让我们深入Java面向对象这一基本特性&#xff0c;就让我们完成一个图书管理系统的小项目吧。 项目简介&#xff1a;通过管理员和普通用户的两种操作界面&#xff0…

SQL注入之延时注入

文章目录 延时注入是什么&#xff1f;延时注入获取数据库版本号 延时注入是什么&#xff1f; 延时注入就是利用sleep()函数通过if语句判断所写的语句真假&#xff0c;如果为真返回我们想要的东西&#xff08;例如&#xff1a;数据库的长度&#xff0c;数据库的名字等&#xff0…

视频汇聚/视频云存储/视频监控管理平台EasyCVR提升网络稳定小tips来啦!

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…