博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【java】JDBC与防止sql注入
阅读量:2240 次
发布时间:2019-05-09

本文共 4758 字,大约阅读时间需要 15 分钟。

文章目录

一、JDBC概述

JDBC:JavaDataBaseConnectivity,Java数据库连接,SUN公司推出的java访问数据库的标准规范(接口)。

JDBC是一种用于执行SQL语句的 java api。
JDBC可以为多种关系数据库提供统一访问入口。
JDBC由一组Java工具类和接口组成。

二 、JDBC 原理

SUN 提供的访问数据库的规范成为JDBC,而生产厂家提供规范的实现类成为驱动。

在这里插入图片描述
JDBC 是接口,驱动是接口的实现,没有驱动将无法完成数据库的链接,从而不能操作数据库。每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成长商提供。

三、JDBC 开发步骤【myeclipse】

1、注册驱动

2、获取链接
3、获得数据库执行者
4、执行sql语句
5、处理结果
6、释放资源

##1) 导入驱动jar包

1.1) 创建lib目录,用户存放当前项目所需要的所有的jar包
1.2) 选择jar包,右键执行“build path/ add to build path”
在这里插入图片描述

2) 注册驱动

class.forname("com.mysql.jdbc.Driver");

1.jdbc 规范定义驱动接口java.sql.Driver, mysql 驱动包提供了实现类:com.mysql.jdbc.Driver

2.DriverManager 工具类,提供注册驱动类的方法registerDriver(),
方法的参数是java.sql.Driver,所以我们可以退通过下面语句进行注册DriverManager.registerDriver(new com.mysql.jdbc,Driver());
但是我们不推荐这样的方式:a)这是硬编码,不利于后期维护,b)驱动被注册了两次.
3.通常开发我们使用class.forname() 加载一个使用字符串描述的驱动类。如果使用class.forname() 将类加载到内存,该类的静态代码将自动执行。因为我们通过查com.mysql.jdbc.Driver 源码,可以发现Driver类会主动注册自己。
在这里插入图片描述

3)获取链接:

Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1","root","123");

获取链接需要方法DriverManager.getConnection(url,username,password),三个参数分表为

url:需要连接数据库的位置(网址);
user:用户名;
password:密码;
url比较复杂,下面是mysql的url。

jdbc:mysql://ocalhost:3306/mydbl

JDBC规定的格式由三部分组成,每个部分中间使用冒号分隔。
第一部分是jdbc,这是固定的;
第二部分是数据库名称,那么连接mysql数据库,第二部分当然是mysql了;
第三部分是由数据库厂商规定的,我们需要了解每个数据库厂商的要求,mysql的第三部分分别由数据库服务器的IP地址(localhost)、端口号(3306),以及DATABASE名称(mydb1)组成。

扩展url:

jdbc:mysql://localhost:3306/mydbl?useUniCode=true&characterEncoding=UTF8
1、useUnicode参数:指定这个连接数据库的过程中,使用的字节集是Unicode字节集;
2、characherEncoding参数:指定Java程序连接数据库的过程中,使用的字节集编码为UTE-8编码。
3、请注意,mysqi中指定UTF-8编码是给出的是UTF8,而不是UTF-80要小心了!

4)定义执行语句

string sql="insert into userinfo(username,password)values('root','123')";//定义statement执行对象Statement st=con.createstatement();

执行sql语句常用方法:

  • int executeUpdate(string sql); //执行insert update delete语句
  • ReusltSet executeQuery(string sql); //执行select 语句
  • boolean execute(string sql); //执行select语句返回true,执行其他语句返回false。
    如果返回true,需要使用getResultSet()获取查询结果。
    如果返回false,需要使用getupdatecount()获取影响的函数。

注意:如果有参数,需要在sql语句中进行拼接,存储sql注入问题。

5)处理结果集

ResultSet 实际上是一张二维的表格,它内部有一个“行光标”,光标默认位置在第一行的上方,我们可以调用rs对象的next()方法吧“行光标”向下移动一行,当第一次调用next()方法的时候,行光标就到了一条记录的位置,这是我们就可以 使用ResultSet提供的getXXX(int col)方法来获取制定列是数据了。

rs.next();//光标移动到第一行rs.getInt(1);//获取第一行第一列数据。

在这里插入图片描述

在ResultSet中提供的getXXX()方法中常用的有如下几种:
object getobject(int col);
string getstring(int col);
int getint(int col);
double getDouble(int col);

6) 释放资源

与IO 流一样,使用后的东西需要关闭,关闭的顺序是先得到后关闭,后得到,先关闭。

rs.close();st.close();con.close();

四、实例:

package jdbctest;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class mylogin {
public static void main(String[] args) throws SQLException{
//1、注册驱动 try {
Class.forName("com.mysql.cj.jdbc.Driver"); } catch (ClassNotFoundException e) {
// TODO Auto-generated catch block e.printStackTrace(); } //2、获取链接 Connection conn=DriverManager.getConnection("jdbc:mysql://Localhost:3306/mydb","cheng","123456"); //3、创建执行对象 Statement st=conn.createStatement(); //引入:import java.sql.Statement; //4、 sql语句 String sql="select * from user where username="+"'root' "+" and password="+"'123456';"; //5、执行语句 ResultSet rs=st.executeQuery(sql);//引入:import java.sql.ResultSet; //6、对结果集进行处理 if(rs.next()) {
System.out.print("登录成功"); } else{
System.out.print("登录失败");} //7、释放资源 if(rs!=null) rs.close(); if(st!=null) st.close(); if(conn!=null) conn.close(); }}

五、sql注入:

package jdbctest;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class mylogin {
public static void main( String[] str) throws SQLException{
// String username="root";// String password="123456"; //1、注册驱动 try {
Class.forName("com.mysql.cj.jdbc.Driver"); } catch (ClassNotFoundException e) {
// TODO Auto-generated catch block e.printStackTrace(); } //2、获取链接 Connection conn=DriverManager.getConnection("jdbc:mysql://Localhost:3306/mydb","cheng","123456"); //3、 sql语句 String sql="select * from user where username='?'"+" and password='?'"; //4、 创建预处理对象 PreparedStatement pstmt = conn.prepareStatement(sql); System.out.print(sql); //4.1 设置参数 pstmt.setString(1,"root"); pstmt.setString(2,"123456"); //5、执行语句 ResultSet rs=pstmt.executeQuery(sql);//引入:import java.sql.ResultSet; //6、对结果集进行处理 if(rs.next()) {
System.out.println("登录成功"); System.out.println(sql); } else{
System.out.print("登录失败");} //7、释放资源 if(rs!=null) rs.close(); if(pstmt!=null) pstmt.close(); if(conn!=null) conn.close(); }}

转载地址:http://uxhbb.baihongyu.com/

你可能感兴趣的文章
阿里云《云原生》公开课笔记 第七章 应用编排与管理:Job和DaemonSet
查看>>
阿里云《云原生》公开课笔记 第八章 应用配置管理
查看>>
阿里云《云原生》公开课笔记 第九章 应用存储和持久化数据卷:核心知识
查看>>
linux系统 阿里云源
查看>>
国内外helm源记录
查看>>
牛客网题目1:最大数
查看>>
散落人间知识点记录one
查看>>
Leetcode C++ 随手刷 547.朋友圈
查看>>
手抄笔记:深入理解linux内核-1
查看>>
内存堆与栈
查看>>
Leetcode C++《每日一题》20200621 124.二叉树的最大路径和
查看>>
Leetcode C++《每日一题》20200622 面试题 16.18. 模式匹配
查看>>
Leetcode C++《每日一题》20200625 139. 单词拆分
查看>>
Leetcode C++《每日一题》20200626 338. 比特位计数
查看>>
Leetcode C++ 《拓扑排序-1》20200626 207.课程表
查看>>
Go语言学习Part1:包、变量和函数
查看>>
Go语言学习Part2:流程控制语句:for、if、else、switch 和 defer
查看>>
Go语言学习Part3:struct、slice和映射
查看>>
Go语言学习Part4-1:方法和接口
查看>>
Leetcode Go 《精选TOP面试题》20200628 69.x的平方根
查看>>