【2021Java最新学习路线,【MyBatis 1

很多情况下,我们的一条sql语句可能被反复执行,或每次执行的时候只有个别的值不同,比如query的where子句值不同,update的set子句值不同,insert的value值不同。

如果每次都需要经过上面的语法语义解析、语句优化、制定执行计划等操作,效率显而易见,很低。

所谓预编译就是将这些语句中的值用占位符替代,可以视为将sql语句模板化或者参数化,一般称这类语句叫PreparedStatement。

预编译语句的优势在于:一次编译、多次执行,省去了解析优化等繁琐过程,此外预编译语句能防止sql注入。

(二)预编译的sql语句处理


预编译语句PreparedStatement是java.sql中的一个接口,它是Statement的子接口。通过Statement对象执行sql语句时,需要将sql语句发送给DBMS,由DBMS首先进行编译后再执行。预编译语句和Statement不同,在创建PreparedStatement对象时就指定了sql语句,该语句立即发送给DBMS进行编译。当该编译语句被执行时,DBMS直接运行编译后的sql语句,而不需要像其它sql语句那样首先将其编译。预编译的sql语句处理性能稍微高于普通的传递变量的方法。

数据库管理系统(Database Management System)是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库,简称DBMS。它对数据库进行统一的管理和控制,以保证数据库的安全性和完整性。用户通过DBMS访问数据库中的数据,数据库管理员也通过DBMS进行数据库的维护工作。它可以支持多个应用程序和用户去建立,修改和访问数据库。大部分DBMS提供数据定义语言DDL和数据操作语言DML,供用户定义数据库的模式结构与权限约束,实现对数据的追加、删除等操作。

(三)预编译语句的作用


1、提高效率

当需要对数据库进行数据插入、更新或删除的时候,程序会发送整个sql语句给数据库处理和执行。数据库处理一个sql语句,需要完成解析sql语句、检查语法和语义以及生产代码,处理时间要比执行语句所需要的时间长。预编译语句在创建的时候就已经是将指定的sql语句发送给了DBMS,完成了解析、检查、编译等工作。因此,当一个sql语句需要执行多次时,使用预编译语句可以减少处理时间,提高执行效率。

2、提高安全性

例如上面的sql注入攻击实例,登录验证,根本不用,直接进,加入又在后面追加上drop table student;我靠,防不胜防,数据表直接没了,很多数据库是不会成功的,但也有很多数据库可以使用这些语句执行,而如果使用预编译语句,传入的任何内容就不会和原来的语句发生任何匹配的关系。只要全使用预编译语句,就用不着对传入的数据做任何过虑,而如果使用普通的statement,有可能要对drop,等做费尽心机的判断和过虑。

(四)预编译语句的使用


1、创建PreparedStatement对象


String sql = "insert into studentvalues(?,?,?,?)";//组织一条含有参数的SQL语句

PreparedStatement ps = conn.prepareStatement(sql);

insert into student values(?,?,?,?);//它已发送给DBMS,并为执行作好了准备。

2、传递IN参数

在执行 PreparedStatement 对象之前,必须设置每个 ? 参数的值。这可通过调用 setXXX 方法来完成,其中 XXX 是与该参数相应的类型。

(五)为什么PreparedStatement可以防止sql注入


Preparement样式为


select * from student where id=? and name=?

该SQL语句会在得到用户的输入之前先用数据库进行预编译,这样的话不管用户输入什么id和用户名的判断始终都是并的逻辑关系,防止了SQL注入。

简单总结,参数化能防注入的原因在于,语句是语句,参数是参数,参数的值并不是语句的一部分,数据库只按语句的语义跑,至于跑的时候是带一个普通背包还是一个怪物,不会影响行进路线,无非跑的快点与慢点的区别。

【2021Java最新学习路线,【MyBatis 1

===================================================================================================================================================================================================

六、mybatis与sql注入

===============


<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper

        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.guor.mapper.StudentMapper">

	<select id="queryStudentByStuNo" parameterType="int" resultType="com.entity.Student">

		select * from student where id = ${stuNo}

	</select>

	

	<insert id="addStudent" parameterType="com.entity.Student">

		insert into student(id,name,age) values (#{id},#{name},#{age})

	</insert>

</mapper>

(一)mybatis中#和$的区别


1、#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。

如:where id=#{id},如果传入的值是1,那么解析成sql时的值为where id=“1”, 如果传入的值是id,则解析成的sql为where id=“id”。

2、$将传入的数据直接显示生成在sql中。

如:where id=${id},如果传入的值是1,那么解析成sql时的值为where username=1;

如果传入的值是;drop table user;,则解析成的sql为:select * from student where id=1;drop table student;

3、#方式能够很大程序防止sql注入,$方式无法防止sql注入。

4、$方式一般用于传入数据库对象,比如表明。

5、一般能用#的就不要使用 , 若 不 得 不 使 用 ,若不得不使用 ,若不得不使用,则要做好前期校验工作,防止sql注入攻击。

6、在mybatis中,涉及到动态表名和列名时,只能使用${xxx}这样的参数形式。所以这样的参数需要我们在代码中手工进行处理来防止注入。

(二)mybatis是如何防止sql注入的


MyBatis框架作为一款半自动化的持久层框架,其SQL语句都要我们自己手动编写,这个时候当然需要防止SQL注入。其实,MyBatis的SQL是一个具有“输入+输出”的功能,类似于函数的结构,参考上面的两个例子。其中,parameterType表示了输入的参数类型,resultType表示了输出的参数类型。回应上文,如果我们想防止SQL注入,理所当然地要在输入参数上下功夫。上面代码中使用#的即输入参数在SQL中拼接的部分,传入参数后,打印出执行的SQL语句,会看到SQL是这样的:



# 最后

面试是跳槽涨薪最直接有效的方式,马上金九银十来了,各位做好面试造飞机,工作拧螺丝的准备了吗?

掌握了这些知识点,面试时在候选人中又可以夺目不少,暴击9999点。机会都是留给有准备的人,只有充足的准备,才可能让自己可以在候选人中脱颖而出。

如果你需要这份完整版的**面试笔记**,只需你多多**支持**我这篇文章。

**——对文章进行点赞+评论,关注我,[然后再点击这里免费领取](https://gitee.com/vip204888/java-p7)**

![](https://www.icode9.com/i/ll/?i=img_convert/5d69927f4f70184c79ef38a8e174fa0f.png)

中又可以夺目不少,暴击9999点。机会都是留给有准备的人,只有充足的准备,才可能让自己可以在候选人中脱颖而出。

如果你需要这份完整版的**面试笔记**,只需你多多**支持**我这篇文章。

**——对文章进行点赞+评论,关注我,[然后再点击这里免费领取](https://gitee.com/vip204888/java-p7)**

[外链图片转存中...(img-Z9JL7jFF-1628306349341)]

![](https://www.icode9.com/i/ll/?i=img_convert/e227b20ff63f4976a1429a8c3cdd7a2c.png)
上一篇:2021Java最新大厂面试真题,值得一读!


下一篇:[unknown OJ] 甲虫