【JavaEE学习笔记】JDBC_01_Java链接数据库,封装数据,sql注入

JDBC_01

A.Java链接数据库(快速入门)

1.概述

Java DateBase Connective——Java链接数据库

使用Java代码操作数据库

JDBC其实就是一套操作数据库的规范(接口)

数据库厂商写的一套实现类,叫做数据库驱动


2.快速入门

在此主要将如何链接到数据库,后面再讲细节问题

a.导入驱动jar包

在工程目录下创建一个lib文件夹,将数据库驱动复制到文件夹下

右键该目录,选择Build Path——Add Builder Path

出现下图


b.注册驱动

使用反射机制 Class.forname("Driver的全路径名称");

加载该类时,就会自动完成注册,会执行静态代码块

	static {
		try {
			java.sql.DriverManager.registerDriver(new Driver());
		} catch (SQLException E) {
			throw new RuntimeException("Can't register driver!");
		}
	}

如果jar包是5.1以上的 加载驱动也可以省略不写(有配置文件可以自动加载)




c.创建连接对象 Connection

url连接地址:主协议:子协议://ip:端口号//数据库名

当连接本机数据库,ip可以写localhost或127.0.0.1,jar包版本高于5.1.1,ip,端口可省略

DriverManager 获取连接对象

d.定义sql

e.获取执行sql的对象 Statement

f.执行sql

excuteQuery(sql):执行DQL语句

excuteUpdate(sql):执行DML语句

g.处理结果

h.释放资源

代码如下:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class JDBCDemo01 {
	public static void main(String[] args) throws Exception {
		// 1.导入驱动jar包
		// 2.注册加载驱动
		// 如果jar包是5.1以上的 加载驱动也可以省略不写
		Class.forName("com.mysql.jdbc.Driver");
		
		// 3.获取连接对象
		// DriverManager.getConnection(url,user,password)
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb_01", "root", "root");
		
		// 4.定义sql语句
		String sql = "insert into user values(106,'helloJDBC')";
		
		// 5.获取操作对象
		// Statement 用于执行静态sql语句,并返回它所生成结果的对象
		Statement statement = conn.createStatement();
		
		// 6.执行sql语句
		int i = statement.executeUpdate(sql);// 返回的是影响数据库的行数
		
		if (i != 0) {
			System.out.println("添加成功!");
		} else {
			System.out.println("添加失败!");
		}
		
		// 7.释放资源
		statement.close();
		conn.close();
	}
}



B.封装数据

1.查询数据

executeQuery(sql):执行DQL语句

executeUpdate(sql):执行DML语句

execute(sql):执行任意sql语句

ResultSet:结果集对象,用来封装查询出来的结果

ResultSet.getInt(); ResultSet.getString(); 根据列的数据类型选择

可传递表的列名或编号(从1开始),一般传递列名

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class JDBCDemo02 {
	public static void main(String[] args) throws Exception {
		// 加载驱动
		Class.forName("com.mysql.jdbc.Driver");
		
		// 获取连接对象
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb_01", "root", "root");
		
		// 获取操作对象
		Statement statement = conn.createStatement();
		
		// 定义sql语句
		String sql = "select * from user";
		
		// 执行语句
		ResultSet resultSet = statement.executeQuery(sql);
		
		// 获取每一条数据
		while (resultSet.next()) {	// 让指针下移
			// 1)通过编号取数据,编号为列,从1开始
			// int id = resultSet.getInt(1);
			// String username = resultSet.getString(2);
			
			// 2)通过列名拿数据 常用
			int id = resultSet.getInt("id");
			String username = resultSet.getString("username");
			System.out.println(id + "---" + username);
		}
		
		// 释放资源
		resultSet.close();
		statement.close();
		conn.close();
	}

2.封装数据

我们从数据库中取数据,是想使用这些数据,而不是单纯的查看

所以,先封装到对象,再将对象放入集合中去

建立bean包存放JavaBean


创建对象存储数据(规则在代码中注释)

import java.io.Serializable;

public class User implements Serializable {

	/**
	 * JavaBean是一种规范要求
	 * 	1.所有成员变量必须私有
	 * 	2.必须提供无参构造
	 * 	3.必须提供get/set方法
	 * 	4.最好事先Serializable接口
	 * JavaBean作用:封装数据
	 */
	
	// 为了给对象打个标记,保证对象在传递的时候是同一个对象
	private static final long serialVersionUID = 1L;

	private int id;;
	private String username;

	public User() {
		super();
	}

	public User(int id, String username) {
		super();
		this.id = id;
		this.username = username;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + "]";
	}

}
改进后的查询数据代码

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;

import org.xxx.bean.User;

public class JDBCDemo02 {
	public static void main(String[] args) throws Exception {
		// 加载驱动
		Class.forName("com.mysql.jdbc.Driver");
		
		// 获取连接对象
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb_01", "root", "root");
		
		// 获取操作对象
		Statement statement = conn.createStatement();
		
		// 定义sql语句
		String sql = "select * from user";
		
		// 执行语句
		ResultSet resultSet = statement.executeQuery(sql);
		
		// 创建User对象
		User user = null;
		
		// 创建集合存储对象
		ArrayList<User> list = new ArrayList<>();
		
		// 获取每一条数据
		while (resultSet.next()) {	// 让指针下移
			// 通过列名拿数据 常用
			int id = resultSet.getInt("id");
			String username = resultSet.getString("username");
			
			// 把数据封装到对象里
			user = new User(id, username);
			
			// 把对象存储到集合里
			list.add(user);
		}
		
		// 遍历集合
		for (User u : list) {
			System.out.println(u);
		}
		
		// 释放资源
		resultSet.close();
		statement.close();
		conn.close();
	}
}

C.sql注入

1.模拟用户登录

先在数据库中创建一个用户名单

CREATE TABLE logic(
	username VARCHAR(50),
	PASSWORD VARCHAR(20)
);

INSERT INTO logic VALUES('张三','123456');
登陆程序

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class JDBCLogic {
	public static void main(String[] args) throws Exception {
		// 创建键盘录入对象
		Scanner sc = new Scanner(System.in);
		
		System.out.println("请输入用户名:");
		String username = sc.next();
		System.out.println("请输入密码:");
		String password = sc.next();
		
		// 使用JDBC
		Class.forName("com.mysql.jdbc.Driver");
		
		// 获取连接对象
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb_01", "root", "root");
		
		// 获取操作对象
		Statement statement = conn.createStatement();
		
		// 定义sql,拼接字符串
		String sql = "select * from logic where username='" + username + "' and password='" + password + "'";
		
		// 执行sql语句
		ResultSet resultSet = statement.executeQuery(sql);
		
		// 判断
		if (resultSet.next()) {
			System.out.println("登陆成功!");
		} else {
			System.out.println("登录失败!");
		}
		
		// 释放资源
		resultSet.close();
		statement.close();
		conn.close();
	}
}

2.sql注入

当在数据库查询或者在登陆程序里,输入用户名和密码都为1' or '1'='1,使拼接的sql成为下面语句时

SELECT * FROM logic WHERE username = '1' OR '1' = '1' AND PASSWORD = '1' OR '1' = '1';
发现也可以正常查询数据或者登陆成功,这种现象就叫做sql注入

一般黑客可以利用特殊字符串的拼接,绕过数据库的校验

怎么预防呢?

3.预防sql注入

引入预编译操作对象代替获取操作对象

预编译操作对象:Connection prepareStatment(sql)

该方法可以避免使用字符串的拼接,提高代码的安全性

a.定义sql使用通配符?避免字符串拼接

b.使用setString(通配符位置(从1开始), 值)给通配符赋值

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;

public class JDBCLogic {
	public static void main(String[] args) throws Exception {
		// 创建键盘录入对象
		Scanner sc = new Scanner(System.in);
		
		System.out.println("请输入用户名:");
		String username = sc.next();
		System.out.println("请输入密码:");
		String password = sc.next();
		
		// 使用JDBC
		Class.forName("com.mysql.jdbc.Driver");
		
		// 获取连接对象
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb_01", "root", "root");
		
		// 定义sql 使用通配符?代替数据
		String sql = "select * from logic where username=? and password = ?";
		
		// 获取预编译操作对象
		PreparedStatement statement = conn.prepareStatement(sql);
		
		// 给通配符?赋值,参数1为?的位置,从1开始,参数2为值
		statement.setString(1, username);
		statement.setString(2, password);
		
		// 执行sql语句
		ResultSet resultSet = statement.executeQuery();
		
		// 判断
		if (resultSet.next()) {
			System.out.println("登陆成功!");
		} else {
			System.out.println("登录失败!");
		}
		
		// 释放资源
		resultSet.close();
		statement.close();
		conn.close();
	}
}
这样,就解决了sql注入问题,可以再次验证


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值