MySQLJDBC入门与SQL注入

news2024/11/24 9:48:10

MySQL-JDBC入门与SQL注入

一.JDBC概述

1.JDBC

  • 在Java语言中提供对数据库访问的支持
  • Sun公司于1996年提供了一套访问数据库的标准Java类库JDBC
  • JDBC的全称是Java数据库连接(Java Database Connectivity)它是一套用于执行 SQL语句的Java API
  • 应用程序可通过这套API连接到关系数据库完成对数据库中数据的査询、更新和删除等操作

2.JDBC与数据库驱动的关系

在这里插入图片描述

  • Sun公司在JDBC中定义数据库操作的相关接口而各数据库厂商在其数据库驱动中实现了这些接口
  • Sun公司并没有提供Java语言与各数据打交道的具体API;而是制定了相关的标准和规范;各数据库厂商(比如MySQL,Oracle,DB2等)在其数据库驱动中实现了这些接口(规范)。
  • JDBC屏蔽了Java与不同数据库打交道的细节问题

二.JDBC操作步骤

1.添加jar包

  • 添加MySQL所需jar包,如:mysql-connector-java-5.1.7-bin.jar 到 Java项目lib文件夹中并执行Build Path

(1)eclipse

在这里插入图片描述

(2)idea

在这里插入图片描述

2.加载驱动

(1)加载方式1

  • 利用java.sql.DriverManager.registerDriver( )方法加载驱动
  • 该方式不但强烈依赖数据库的驱动jar而且会导致驱动被重复注册2次
DriverManager.registerDriver(new com.mysql.jdbc.Driver());

(2)加载方式2(推荐)

  • 反射的方式加载数据库驱动
Class.forName(“com.mysql.jdbc.Driver”);

3.创建链接

  • java.sql.Drivermanager类中的getConnection()方法与数据库建立连接。

(1)语法

DriverManager.getConnection(“jdbc:mysql://数据库地址:端口号/数据库名”,”用户名”, “密码”);

(2)示例

Connection connection = DriverManager.getConnection(“jdbc:mysql://localhost:3306/mydb”,”root”, “test”);
  • jdbc: 表示协议
  • mysql: 表示子协议
  • localhost: 代表数据库地址
  • 3306: 表示端口号: 表示要连接的数据库
  • root: 表示用户名
  • test: 表示密码
  • java.sql.Connection:接口,用于与数据库交互;各数据库驱动中均实现了该接口

4.创建Statement对象

  • 利用java.sql.Connection创建用于执行SQL语句的Statement

(1)使用

Statement statement = connection.createStatement();
  • java.sql.Statement:接口用于操作SQL语句并返回相应的结果集;各数据库驱动中均实现了该接口

5.执行SQL语句

  • 利用java.sql.Statement执行SQL语句

(1)常用方法

方法方法描述
execute(String sql )该方法可以执行任意SQL语句。当且仅当执行select语句且有返回结果时该方法返回true, 其他情况下该方法返回false
executeUpdate(String sql )该方法常用于执行DML( INSERT、UPDATE或DELETE)和DDL语句。执行DML语句时返回受SQL语句影响的行数,执行DDL语句时返回0
executeQuery( String sql)该方法通常执行査询语句,执行后返回代表结果集的ResultSet对象

(2)示例

ResultSet  resultSet = statement.executeQuery(sql);
  • statement.executeQuery( )方法:返回的是实现java.sql.ResultSet接口的对象

6.获得结果集

  • 利用利用java.sql.Statement接口方法

(1)示例

ResultSet  resultSet = statement.executeQuery(sql);
  • java.sql.ResultSet:用于保存执行SQL语句之后得到的结果集;各数据库驱动中均实现了该接口。
  • ResultSet:对外暴露一个游标,该游标默认指向结果集第一行之前。

(2)ResultSet常用方法

方法方法描述
boolean next()将游标从当前位置向下移动一行
boolean previous()将游标从当前位置向上移动一行
void afterLast()将光标移动到末尾,正好位于最后一行之后
void beforeFirst()将光标移动到开头,正好位于第一行之前
Object getObject(int columnIndex)根据序号取值,索引从1开始
Object getObject(String ColomnName)根据列名取值
int getInt(int colIndex)以int形式获取ResultSet结果集当前行指定列号值
int getInt(String colLabel)以int形式获取ResultSet结果集当前行指定列名值
float getFloat(int colIndex)以float形式获取ResultSet结果集当前行指定列号值
float getFloat(String colLabel)以float形式获取ResultSet结果集当前行指定列名值
String getString(int colIndex)以String形式获取ResultSet结果集当前行指定列号值
String getString(String colLabel)以String形式获取ResultSet结果集当前行指定列名值
Date getDate(int columnIndex)以Date形式获取ResultSet结果集当前行指定列号值
Date getDate(String columnName)以Date形式获取ResultSet结果集当前行指定列号值
void close()关闭ResultSet对象

7.处理结果

  • 从ResultSet中获取到数据库中数据后,我们就将这些数据封装到JavaBean中
  • 注意Java的数据类型与数据库的数据类型的对应关系
Java数据类型数据库的数据类型
bytetityint
intint
shortsmallint
longbigint
floatfloat
doubledouble
Stringchar/varchar
Datedate

8.关闭资源

  • 数据库资源非常宝贵,数据库允许的并发访问连接数量有限。
  • 当数据库资源用完后切记释放资源。
  • 为了保证资源的释放,常在finally代码块中关闭与数据库操作相关的资源。

三.JDBC示例

1.建表

  • 在数据库test中建立student表并存入数据
-- 若存在数据库test则删除
DROP DATABASE IF EXISTS test;
-- 创建数据库test
CREATE DATABASE test;
-- 选择数据库test
USE test;

-- 创建学生表
CREATE TABLE student (
	 studentid INT,
   studentname VARCHAR(50)
);

-- 向学生表插入数据
INSERT INTO student (studentid,studentname) VALUES (1,"lili");
INSERT INTO student (studentid,studentname) VALUES (2,"dodo");
INSERT INTO student (studentid,studentname) VALUES (3,"tutu");
INSERT INTO student (studentid,studentname) VALUES (4,"mqmq");
INSERT INTO student (studentid,studentname) VALUES (5,"pmpm");

2.编写Javabean(实体类)

package cn.com.demo1;
public class Student {
	private int studentID;
	private String studentName;
	public Student() {
		
	}
	public Student(int studentID, String studentName) {
		this.studentID = studentID;
		this.studentName = studentName;
	}
	public int getStudentID() {
		return studentID;
	}
	public void setStudentID(int studentID) {
		this.studentID = studentID;
	}
	public String getStudentName() {
		return studentName;
	}
	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}
	@Override
	public String toString() {
		return "Student [studentID=" + studentID + ", studentName=" + studentName + "]";
	}
	
}

3.使用JDBC操作数据库

package cn.com.demo1;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestJDBC {
	public static void main(String[] args) {
		Connection connection = null;
		Statement statement = null;
		ResultSet resultSet = null;
		try {
			//加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//建立连接
			connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
			//创建Statement
			statement = connection.createStatement();
			String sql = "select * from student";
			//执行SQL
			resultSet = statement.executeQuery(sql);
			//处理结果
			while (resultSet.next()) {
				Student student = new Student();
				int id = resultSet.getInt("studentid");
				String name = resultSet.getString("studentname");
				student.setStudentID(id);
				student.setStudentName(name);
				System.out.println(student);
			}
		} catch (Exception e) {
			e.printStackTrace();
		//关闭资源
		} finally {
			if (resultSet != null) {
				try {
					resultSet.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				resultSet = null;
			}

			if (statement != null) {
				try {
					statement.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				statement = null;
			}

			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				connection = null;
			}
		}
	}
}

SQL注入

1.SQL注入示例

(1)依据姓名查询学生信息

package cn.com.demo2;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestJDBC {
	public static void main(String[] args) {
		Connection connection = null;
		Statement statement = null;
		ResultSet resultSet = null;
		try {
			//加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//建立连接
			connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
			//创建Statement
			statement = connection.createStatement();
			//依据姓名查找学生信息
			String studentname="lili";
			String sql = "select * from student where studentname="+"'"+studentname+"'";
			System.out.println(sql);
			//执行SQL
			resultSet = statement.executeQuery(sql);
			//处理结果
			while (resultSet.next()) {
				Student student = new Student();
				int id = resultSet.getInt("studentid");
				String name = resultSet.getString("studentname");
				student.setStudentID(id);
				student.setStudentName(name);
				System.out.println(student);
			}
		} catch (Exception e) {
			e.printStackTrace();
		//关闭资源
		} finally {
			if (resultSet != null) {
				try {
					resultSet.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				resultSet = null;
			}

			if (statement != null) {
				try {
					statement.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				statement = null;
			}

			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				connection = null;
			}
		}
	}
}

(2)修改studentname的值

String studentname="abc' or '1=1";
  • 没有传入正确的学生姓名居然查询出来所有学生的信息
  • 我们使用Statement来执行SQL语句,在该过程中遭受到了SQL注入攻击。为了防止该类问题的发生,推荐使用PreparedStatement替代Statement。
  • PreparedStatement是Statement的子类,它可防止SQL注入攻

preparedStatement

1.PreparedStatement概述

  • PreparedStatement是Statement的子接口,它可以预编译 SQL 语句并将预编译后的SQL语句存储在PreparedStatement对象中
  • 由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement对象

2.PreparedStatement使用步骤

  1. 编写带有?占位符的SQL语句
  2. 使用Connection的prepareStatement( )方法和包含了?占位符的SQL字符串创建PreparedStatement对象并对SQL语句进行预编译
  3. 使用PreparedStatement的setXXX(index , value)方法传入实参取代之前的?占位符
  4. 使用PreparedStatement的execute( )、 executeUpdate( ) 、 executeQuery( )方法执行 SQL 语句

3.PreparedStatement示例

package cn.com.demo3;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestJDBC {
	public static void main(String[] args) {
		TestJDBC jdbcDemo=new TestJDBC();
		jdbcDemo.addStudent();
		jdbcDemo.deleteStudent();
		jdbcDemo.updateStudent();
		jdbcDemo.findStudent();
	}
	
	//添加学生
	private void addStudent() {
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		try {
			//加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//建立连接
			connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
			Student student=new Student(6, "zczc");
			String sql = "insert into student values (?,?)";
			//创建PrepareStatement
			preparedStatement = connection.prepareStatement(sql);
			preparedStatement.setInt(1, student.getStudentID());
			preparedStatement.setString(2, student.getStudentName());
			//执行SQL
			preparedStatement.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		//关闭资源
		} finally {
			if (preparedStatement != null) {
				try {
					preparedStatement.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				preparedStatement = null;
			}

			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				connection = null;
			}
		}
	}
	
	//删除学生
	public void deleteStudent() {
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		try {
			//加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//建立连接
			connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
			String studentname="zczc";
			String sql = "delete from student where studentname=?";
			//创建PrepareStatement
			preparedStatement = connection.prepareStatement(sql);
			preparedStatement.setString(1, studentname);
			//执行SQL
			preparedStatement.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		//关闭资源
		} finally {
			if (preparedStatement != null) {
				try {
					preparedStatement.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				preparedStatement = null;
			}

			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				connection = null;
			}
		}
	}
	
	//修改学生
	private void updateStudent() {
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		try {
			//加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//建立连接
			connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
			int studentid=1;
			String studentname="hoho";
			String sql = "update student set studentname=? where studentid=?";
			//创建PrepareStatement
			preparedStatement = connection.prepareStatement(sql);
			preparedStatement.setString(1, studentname);
			preparedStatement.setInt(2, studentid);
			//执行SQL
			preparedStatement.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		//关闭资源
		} finally {
			if (preparedStatement != null) {
				try {
					preparedStatement.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				preparedStatement = null;
			}

			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				connection = null;
			}
		}
	}
	
	//查找学生
	private void findStudent() {
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		try {
			//加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//建立连接
			connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
			//依据姓名查找学生信息
			String studentname="lili";
			String sql = "select * from student where studentname=?";
			//创建PrepareStatement
			preparedStatement = connection.prepareStatement(sql);
			preparedStatement.setString(1, studentname);
			//执行SQL
			resultSet = preparedStatement.executeQuery();
			//处理结果
			while (resultSet.next()) {
				Student student = new Student();
				int id = resultSet.getInt("studentid");
				String name = resultSet.getString("studentname");
				student.setStudentID(id);
				student.setStudentName(name);
				System.out.println(student);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		//关闭资源
		} finally {
			if (resultSet != null) {
				try {
					resultSet.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				resultSet = null;
			}

			if (preparedStatement != null) {
				try {
					preparedStatement.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				preparedStatement = null;
			}

			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				connection = null;
			}
		}
	}
}

atch (Exception e) {
e.printStackTrace();
//关闭资源
} finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
resultSet = null;
}

		if (preparedStatement != null) {
			try {
				preparedStatement.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			preparedStatement = null;
		}

		if (connection != null) {
			try {
				connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			connection = null;
		}
	}
}

}


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

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

相关文章

Python中的List

一、List(列表) 1、什么是 List (列表) List (列表)是 Python 内置的一种数据类型。 它是一种有序的集合,可以随时添加和删除其中的元素。 那为什么要有 List (列表)呢? 我们用一个例子来说明。 现在有一个团队要出去玩,要先报名。如果用我们之前学过的知识,那…

太强了!三种方案优化 2000w 数据大表!

目录 评估表数据体量 表容量: 磁盘空间 实例容量 出现问题的原因 如何解决单表数据量太大,查询变慢的问题 方案一:数据表分区 方案二:数据库分表 水平分表 垂直分表 1.取模方案: 2.range 范围方案 3.hash…

儿童口腔卫生:建立健康微笑的基石

引言 儿童口腔卫生是维护健康的关键部分,它不仅影响口腔健康,还对全身健康产生必然影响。本文将探讨一些儿童口腔卫生的重要性以及儿童的关键注意事项,以帮助家长和监护人确保儿童拥有健康的口腔。 第一部分:儿童口腔卫生的重要性…

Hudi第四章:集成Hive

系列文章目录 Hudi第一章:编译安装 Hudi第二章:集成Spark Hudi第二章:集成Spark(二) Hudi第三章:集成Flink Hudi第四章:集成Hive 文章目录 系列文章目录前言一、环境准备1.拷贝jar包 二、Flink集成hive1.配置模版2.案…

优雅而高效的JavaScript——Proxy 和 Reflect

🤔博主:小猫娃来啦 文章核心:优雅而高效的JavaScript——Proxy 和 Reflect 文章目录 Proxy 和 Reflect是什么Proxy创建 Proxy 对象拦截器方法拦截器示例:属性拦截拦截器示例:方法拦截 ReflectReflect 的静态方法Reflec…

ORACLE内存结构

内存体系结构 数据库由磁盘文件构成,当数据库启动时,相关实例将被启动,而实例由内存结构和进程组成。数据库及其运行的程序存放在分配给内存的不同结构当中。我们只讨论单实例的内存体系结构。内存跟磁盘空间分配一样,一般情况下…

Golang 面向对象编程 多态

基本介绍 变量(实例)具有多种形态。面向对象的第三大特征,在Go语言,多态特征是通过接口实现的(接口能够体现多态的特征)。可以按照统一的接口来调用不同的实现。这时接口变量就呈现不同的形态。 在前面的Usb接口案例,u…

金融行业的CFA、CPA和FRM你了解吗?中国人民大学与加拿大女王大学金融硕士需要吗?

CFA、CPA和FRM是金融行业中非常重要的专业资格认证,它们分别代表着不同领域的专业知识和技能。在当下越来越多的高校在把关金融硕士的申请过程中,拥有CFA、CPA和FRM都属于强大的加分项,中国人民大学与加拿大女王大学金融硕士也不例外&#xf…

软件工程与计算总结(十六)详细设计的设计模式

一.设计模式基础 某种意义上来说,设计模式就是设计经验的总结~ 设计模式不是简单的经验总结,更不是无中生有,它是经过实践反复检验、能解决关键技术难题、有广泛应用前景和能够显著提高软件质量的有效的经验总结。 每个模式都不是独立的&a…

Word保存后内容丢失?4个方法,有效找回数据!

“我利用Word文档写了一份重要的工作报告。明明已经保存了,但是里面的内容却莫名其妙丢失了。这可怎么办呢?有什么方法可以找回丢失的Word内容吗?” Word作为一个常用的办公工具,为我们的工作提供了很多的便利。但在使用Word时&am…

uniapp+vue3+ts开发微信小程序+抖音小程序等跨平台应用入门,环境搭建

使用之前需要安装hbuilder和微信开发者工具,hbuilder是uniapp的开发工具,微信开发者工具是微信官方的小程序开发平台: hbuilder下载地址:HBuilderX-高效极客技巧 微信开发者工具:微信开发者工具下载地址与更新日志 |…

模块电源(四):可调DC-DC

一、DC-DC典型应用 以DC-DC转换器SCT2432数据手册为例,典型应用电路如下图所示: 其中,输出电压为: , DC-DC转换器中, 反馈电压是指反馈回路中的信号电压,用于控制输出电压与设定电压之间的误差&…

LeetCode 137. 只出现一次的数字 II【哈希表;位运算;数字逻辑;DFA】中等

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…

【Linux基础】Linux 发展史

转载于 https://blog.csdn.net/weixin_45031801/article/details/133551510 文章目录 1、前言2、Linux 发展史2.1 UNIX 发展史2.1.1 C 语言对 UNIX 的影响 2.2 Linux 的诞生2.2.1 概述2.2.2 开源的优势2.3.3 系统结构内核层Shell层应用层 3、Linux 应用领域3.1 服务器领域3.2 …

Python算法练习 10.16

leetcode 437 路径总和III 给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。 路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的&#xff…

SpringBoot集成Dubbo

1. 构建SpringBoot环境 1.1 创建一个duubo-spring-boot-demo项目 duubo-spring-boot-demo:是父工程,方便依赖管理duubo-spring-boot-demo-consumer:是服务消费方,继承父工程duubo-spring-boot-demo-provider:是服务提…

数据结构 2 第二章 线性结构 代码实现

头文件 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdlib.h>//malloc函数头文件 #include <time.h> #include <string.h> #include <limits.h> #include <ctype.h> #include <math.h> # include <stdio.h> 一、单链表 1.单链…

Segment Anything(论文解析)

Segment Anything 摘要1.介绍2 SAM任务SAM模型 摘要 我们介绍了“Segment Anything” (SA) 项目&#xff1a;这是一个新的任务、模型和数据集对于图像分割。使用我们高效的模型进行数据收集&#xff0c;我们构建了迄今为止最大的分割数据集&#xff08;远远超过其他数据集&…

C语言进行实验:通过程序实现线算图取值【支持VC++ 6.0编辑器环境运行】

背景&#xff1a; 一、实验目的和要求 1、能描述数据基本类型及其常量的表示方法&#xff1b; 2、会对变量进行定义及初始化&#xff1b; 3、能使用运算符与表达式对变量赋值&#xff1b; 4、会描述C语句的概念及种类、C语言常用的输入/出方式&#xff1b; 5、会设计顺序…

typora主题切换与推荐主题

在这篇博文中&#xff0c;我将向你展示如何给typora更换主题&#xff0c;并推荐几款出色的主题。通过这些主题的使用&#xff0c;你可以为你的typora编辑器增添一抹别样的风采&#xff0c;让你的写作体验更加美好、舒适。 typora替换主题的步骤非常简单&#xff0c;只需按照以…