PreparedStatement接口与调用存储过程

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介:

PreparedStatement相对于Statement最重要的一个优点就是可以进行SQL预处理,以此防止SQL语句的注入问题。

所谓SQL注入,就是通过把SQL命令插入到用户输入的文本中,最终达到欺骗数据库服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。

使用PreparedStatement就可以防止一些SQL注入的问题,保证了一定的安全性,而且PreparedStatement能够使用提供参数的方式来避免拼错SQL语句,在调用PreparedStatement里的setStringsetInt等方法的时候,会自动把你提供的参数转换成数据库里的数据类型。

就算没有被恶意的被SQL注入攻击,也可能会出现用户输入的内容碰巧转换成了SQL语句,或者在程序运行过程中出现符号转换的问题,这些都会导致数据库误以为是SQL命令而去执行。

下面我们使用Statement写几句简单的代码模拟一下用户的登录操作:

1a42cd7b63be44b794bbcde6287f50fb.png


运行结果:

582cf6079d4c254b7e3862d654b0d5a0.png


接着做个简单的小实验,模拟利用简单的SQL注入原理来达到不输入用户和密码也能登录的情况:

  代码示例:

2d8c43432a4477fc7764bb0b6057fc10.png


运行结果:

db9cf3898ed621a57b1a99d369989d96.png

从结果可以看到没有输入用户和密码也登录成功了,如果这种漏洞问题出现真正的程序,想想也知道会有多严重。而且这仅仅是一个很简单的例子,借助SQL注入能做到的事情可不止这一点。

 


现在换成PreparedStatement来进行同样的试验:

代码示例:

1e032888be39ca369cba53f6b96a55d5.png


运行结果:

5e954a6f3efa2baba2e9f217fa0ee651.png

从结果可以看到不会因为用户输入的内容是SQL命令或符号,而出现SQL注入的问题了。


 

Statement一样PreparedStatement也能够执行数据库的两大类语句,更新语句(DML)和查询语句(DQL),并且也支持批量SQL语句执行。

  insert语句代码示例:

51bde168e10d4abcbb086a1fecb06023.png


运行结果:

a4ee0b6aeb65e3a984e1116e323161c8.png


数据库:

af87f1215d64fdd7b030ced9a3151431.png


update语句代码示例:

b84c9e81120f144cf04fa35372e79af8.png


运行结果:

854ce930000e8080775c603d2bc55b51.png


数据库:

918b19992b6537af67fe036b0e455e39.png


delete语句代码示例:

85e10cd6afcc1e9cedcc6d9a39dd064e.png


运行结果:

b41e52dc270cc170766d482d903c8103.png


数据库:

a0224f8764dd723272685dbd97b0ca61.png


批量SQL语句执行代码示例:

daf92c6da6efe32568f9a7504c10f480.png


运行结果:

f7857a3a5985e6c138307c6e12b10748.png


数据库:

021830f8507d8bc09c4b6dc406cc5a3f.png



PreparedStatement里设置值的时候可以调用setObject方法,此方法能够自动将你提供的参数转换成相对应的数据库数据类型,也就是说即便你懒得写具体的类型或者不知道提供的值是什么类型的话均可使用这个方法。

  代码示例:

87f326f5dbba7a0d332e89610fef50bf.png


运行结果:

737883c00536a99a5c424e89ef6cdf33.png



我们看一下这个方法的实现代码,就知道此方法是如何实现的和支持哪些类型了:

6f81687c177064d3379aa21a804cf375.png

2fd7826cf18fd9a2c7101f8bf17f05e4.png







从数据库中进行文件上传/下载:

我们可以上传文件到数据库中,相对也能从数据库中下载文件,不过很少人会这么做,这种骚操作了解一下记得有这个操作就可以了,一般情况下用不上。

因为把文件存放在数据库要面临以下几个问题:

· 1.对数据库的读/写的速度永远都赶不上文件系统处理的速度

· 2.数据库备份变的巨大,越来越耗时间

· 3.对文件的访问需要穿越你的应用层和数据库层

这后两个是真正的杀手。把图片缩略图存到数据库里?很好,那你就不能使用nginx或其它类型的轻量级服务器来处理它们了。

So给自己行个方便吧,在数据库里只简单的存放一个磁盘上你的文件的相对路径,或者使用S3或CDN之类的服务。

虽然把文件存到数据库中不是什么好的操作,但是为了预防万一或应急情况还是需要了解一下这个操作的:

  1.首先创建一张表格使用blob作为文件的数据类型,当然也可以使用其他可以存储文件的类型:

465d6db885d35515f8c6eb27784c5925.png



3.查看一下数据库能接收多大的数据,如果要存放的文件大小大于数据库能接收的大小就会报错,使用以下SQL命令查看,单位是字节:

  SHOW VARIABLES LIKE '%max_allowed_packet%';

86c6b04d50676d00d9c1f873163b5387.png


如果要改变mysql数据库的数据接收大小,需要去配置my.ini文件,写上这句代码:

max_allowed_packet = 20M

53a06739ba844607d5380fc9220721fa.png




修改方法

1) 方法1

可以编辑my.ini来修改(Linuxmy.cnf,在[mysqld]段或者mysql的server配置段进行修改。

max_allowed_packet = 20M

Linux系统中如果找不到my.ini可以通过

mysql --help | grep my.ini

命令去寻找my.ini文件。

 

2) 方法2

(很妥协,很纠结的办法)

进入mysql server

mysql 命令行中运行

set global max_allowed_packet = 2*1024*1024*10

然后关闭掉这此mysql server链接,再进入。

show VARIABLES like '%max_allowed_packet%';

查看下max_allowed_packet是否编辑成功

编写Java代码通过JDBC将文件上传到数据库中:

f2ef63031596643a1febf0bce92ac9a9.png


运行结果:

aa8c1981b8153da2e015a6b17ed4877d.png


数据库:

8dbdba5c13a25f0c2fb25875d07f398e.png



接下来我们从数据库中把这个文件下载下来,先使用查询语句先把文件查找出来,然后调用getBinaryStream方法得到一个InputStream 对象,这个方法需要传递一个列的序号,接着使用FileOutputStream把文件写入到磁盘里。

  代码示例:

5644c7e2a3020618e5b0a31aadae7d9b.png


运行结果:

97ec95eb7717ac8bfe04c453aa335a0e.png


文件:

9cb84daf5222f5e043052bc00b27f8e3.png


27ceb25bf5b803b10dfce88d9d36605b.png








调用存储过程:

使用CallableStatement 接口可以调用数据库中的存储过程,需要先使用Connection 对象调用prepareCall方法并提供调用存储过程的SQL语句来获得CallableStatement 对象,不过语法和数据库中的调用存储过程的SQL语句有点不一样,需要加上大括号括起来。使用CallableStatement 对象调用registerOutParameter方法并且提供存储过程带出值的类型,就可以获得存储过程的带出值。

代码示例:

7ddececa36a0837de9a6e32d41268027.png



运行结果:

323efe7d8faee968d828a1eb8e847d56.png




本文转自 ZeroOne01 51CTO博客,原文链接:http://blog.51cto.com/zero01/1977008,如需转载请自行联系原作者

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
9月前
使用PreparedStatement实现CRUD操作
使用PreparedStatement实现CRUD操作
28 0
|
11月前
|
SQL 存储 缓存
JDBC使用PreparedStatement实现CRUD操作
JDBC使用PreparedStatement实现CRUD操作
129 0
|
12月前
|
SQL 缓存 Java
数据库连接关闭工具类、Statement介绍、PreparedStatement介绍及区别
数据库连接关闭工具类、Statement介绍、PreparedStatement介绍及区别
93 0
PreparedStatement 防止 SQL 注入原理
PreparedStatement 对象可以防止 SQL 注入,而 Statement 对象不能防止 SQL 注入,接下来使用一个案例剖析原理。
PreparedStatement 防止 SQL 注入原理
|
Java 数据库连接
使用JDBC中的PreparedStatement批量插入
使用JDBC中的PreparedStatement批量插入
286 0
|
Java 关系型数据库 MySQL
JDBC学习(八):PreparedStatement实现数据的批量插入
JDBC学习(八):PreparedStatement实现数据的批量插入
219 0
|
JSON Java 数据库
简单实现数据库的PreparedStatement查询
查询一个数据库的全部记录,并且将其用java list储存起来
132 0
|
SQL Java 关系型数据库
PreparedStatement 的用法 | 学习笔记
快速学习 PreparedStatement 的用法。
244 1
|
SQL 数据库
PreparedStatement对象
PreparedStatement对象
浅析 PreparedStatement 和 Statement
PreparedStatement 和 Statement的创建方法、执行方法、返回结果和关闭连接
浅析 PreparedStatement 和 Statement