课程名称:Java工程师2022版
课程章节:Java与数据库连接的桥梁
课程讲师:IT老齐 悟空 八戒猪 神思者 Leo
课程内容:JDBC第一步分
一、JDBC的API
1.什么是JDBC?
Java数据库连接-Java DataBase Connectivity。
JDBC可让Java通过程序操作关系型数据库。
JDBC基于驱动实现与数据库的连接与操作。
JDBC驱动程序,JDBCAPI(mysql驱动程序,oracle驱动程序,其他驱动程序),JDBC是一个标准,由对应的数据库厂商进行对接JDBC的统一接口。
2.JDBC的优点
提供统一的API,提供一致的开发过程。
易于学习,容易上手,代码结构稳定。
执行强大,执行效率高,可处理海量数据。
3.JDBC的流程
a:加载并注册JDBC驱动。
b:创建数据库连接。
c:创建Statement对象。
d:遍历查询结果。
e:关闭连接,释放资源。
4.创建数据库连接代码
String dbDriver = "com.mysql.cj.jdbc.Driver"; //JDBC驱动类
String dbURL = "jdbc:mysql://localhost:3306/imooc"; //连接字符串
String dbUsername = "root"; //数据库用户名
String dbPassword = "123456"; //数据库密码
//1.加载并初始化JDBC驱动
Class.forName(dbDriver);
//2.创建数据库连接
Connection connection = DriverManager.getConnection(dbURL,dbUsername,dbPassword);
Class.forName的作用就是用于加载指定的JDBC驱动类。本质上是通知JDBC注册这个驱动类。驱动数据库厂商自行开发,连接字符串也不相同。
数据库 | JDBC驱动类 | 连接字符串 |
---|---|---|
MySQL | com.mysql.jdbc.Driver | jdbc:mysql://主机ip:端口/数据库名 |
MySQL | com.mysql.cj.jdbc.Driver | jdbc:mysql://主机ip:端口/数据库名 |
Oracle | oracle.jdbc.driver.OracleDriver | jdbc:oracle:thin:@主机ip:端口:数据库名 |
SQL Server | com.mircosoft.sqlserver.jdbc.SQLServerDriver | jdbc:mircosoft:主机ip:端口;databasename=数据库名 |
5.DriverManager
DriverManager用于注册/管理JDBC驱动程序。
DriverManager.getConnection(连接字符串,用户名,密码)。
返回值Connection对象,对应数据库的物理网络连接。
6.Connection对象
Connection对象用于JDBC与数据库的网络通信对象。
java.sql.Connection是一个接口,具体由驱动厂商实现。
所有数据库的操作都建立在Connection基础上。
7.MySQL连接字符串
格式:jdbc:mysql://[主机ip][:端口]/数据库名?参数列表。
主机ip与端口号是可选设置,默认值为127.0.0.1与3306。
参数列表采用url编码,格式:参数:参数1=值1&参数2=值2&…
参数名 | 建议参数值 | 说明 |
---|---|---|
useSSL | true(生产),false(开发) | 是否禁用ssl |
useUnicode | true | 启用unicode编程传输数据 |
characterEncoding | UFT-8 | 使用UTF-8编码传输数据 |
serverTimezone | Asia/Shanghai | 使用东8区时间,UTC+8 |
allowPublicKeyRetrieval | true | 允许从客户端获取公钥加密传输 |
连接数据库的代码,以及五个参数的应用,这里最应该注意的是时区这里的Shanghai的S一定要大写,不然就会报错,找不到这个时区。
package com.imooc.jdbc.sample;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionSample {
public static void main(String[] args) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/imooc?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true";
Connection conn = DriverManager.getConnection(url,"root","1314520Gx");
System.out.println(conn);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
二、JDBC的查询操作以及SQL注入漏洞
1.实现按部门查询员工功能
该功能主要由两个类和一个接口组成
package com.imooc.jdbc.hrapp.command;
import com.mysql.cj.jdbc.Driver;
import java.sql.*;
import java.util.Scanner;
public class QueryCommand implements Command{
@Override
public void execute() {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
System.out.println("请输入部门名称:");
Scanner in = new Scanner(System.in);
String pdname = in.next();
try {
//1.加载注册JDBC驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.创建数据库连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/imooc?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true","root","1314520Gx");
//3.创建Statement对象
stmt = conn.createStatement();
//结果集
rs = stmt.executeQuery("select * from employee where dname='"+ pdname +"'");
//4.遍历查询结果
//rs.next()返回布尔值,代表是否存在下一条记录
//如果有,返回true,同时结果集提取下一条记录
//如果没有,返回false,循环就会停止
while(rs.next()){
Integer eno = rs.getInt(1); //JDBC中字段索引从1开始,而非0;
String ename = rs.getString("ename");
Float salary = rs.getFloat("salary");
String dname = rs.getString("dname");
System.out.println(dname+"-"+ eno + "-" + ename + "-" + salary );
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//5.关闭连接,释放连接
try {
if(rs != null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(stmt != null){
stmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
package com.imooc.jdbc.hrapp;
import com.imooc.jdbc.hrapp.command.Command;
import com.imooc.jdbc.hrapp.command.QueryCommand;
import java.util.Scanner;
public class HumanResourceApplication {
public static void main(String[] args) {
System.out.println("1-查询部门员工");
Scanner in = new Scanner(System.in);
Integer cmd = in.nextInt();
switch (cmd){
case 1: //查询部门员工
Command command = new QueryCommand();
command.execute();
break;
}
}
}
package com.imooc.jdbc.hrapp.command;
public interface Command {
public void execute();
}
2.SQL注入攻击
简单的说就是在输入的数据中没有对单引号’这样的字符进行特殊的处理。
SQL注入攻击是指利用SQL漏洞越权获取数据的黑客行为。
SQL注入攻击根源是未对原始SQL中的敏感字符做特殊处理。
解决方法:放弃Statement改用PreparedStatement处理SQL。
3.PreparedStatement解决SQL注入问题
PreparedStatement预编译Statement是Statement的子接口。
PreparedStatement对SQL进行参数化,预防SQL注入攻击。
PreparedStatement比Statement执行效率更高。
课程总结:
完成了今天的学习目标:
1.JDBC的API。
2.JDBC的查询操作以及SQL注入漏洞。