上一篇Java for the Web With Servlets, JSP, and EJB(Part1-Chapter3)jakarta.servlet.http
- Windows 10
- tomcat 10.1.19
- jdk-11.0.20
- MySQL Server version: 8.0.32
一、Java Database Connectivity (JDBC)——java.sql
java.sql文档https://docs.oracle.com/javase/8/docs/api/java/sql/package-summary.html
1.1 指定驱动类型
java程序通过数据库驱动和数据库进行对话,数据库驱动由各个数据库厂商提供,DriverManager类就是用来管理各个数据库的驱动。
1.1.1 DriverManager类和各种数据库驱动
数据库 | DriverClass | 驱动jar包 |
---|---|---|
MySQL | com.mysql.cj.jdbc.Driver | mysql-connector-java-8.0.30.jar |
Oracle | oracle.jdbc.driver.OracleDriver | |
PostgreSQL | org.postgresql.Driver | |
SQL Server | com.microsoft.sqlserver.jdbc.SQLServerDriver |
就是要写在配置文件里的那个DriverClass,比如mysql数据库的配置:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/starter?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&useSSL=false&useInformationSchema=true
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
1.1.2 指明驱动类
// 设定mysql驱动类
Class.forName("com.mysql.cj.jdbc.Driver");
1.2 注册驱动——将对应的Driver在DriverManager中注册后可使用
查看com.mysql.cj.jdbc.Driver的源码
package com.mysql.cj.jdbc;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
用静态块,Driver类一加载就注册进DriverManager了
// 静态块
static {
}
1.3 建立连接——DriverManager类的getConnection方法
根据给定的URL,比如MySQLspring.datasource.url=jdbc:mysql://127.0.0.1:3306/starter
,连接到指定的数据库。
// 创建一个连接 public static Connection getConnection(String url, String user, String password)
Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/starter", "xxx", "xxx");
1.4 执行SQL——编写SQL Statement并执行,返回结果
String sql = "SELECT * FROM user";
Statement s = con.createStatement();
ResultSet rs = s.executeQuery(sql);
1.5 关闭资源——操作数据库用到的各种资源
// ResultSet实例 返回的结果集
rs.close();
// Statement实例 SQL Statement
s.close();
// Connection实例 数据库链接实例
con.close();
二、JDBC MySQL实操
2.1 驱动
下载https://www.mysql.com/products/connector/
有各种语言的驱动程序诶!这里选择JDBC,就是Java Database Connector!
点击Download,选择Platform Independent,选择下载zip。
选择不登录直接下载
2.1.1 mysql-connector-j-8.3.0
解压后,使用这个jar包就可以啦
来看看README,JDBC Type 4 driver,说明是纯粹用JAVA写的,根据数据库协议,和数据库进行直连,其他Type都需要经过中间一层的中转,所以Type 4速度更快、效率更高。
各种Type的JDBC,详情可以参考https://en.wikipedia.org/wiki/JDBC_driver
2.1.2 放到tomcat中
2.2 代码
2.2.1 SQL注入
注意!拼接SQL字符串,有SQL注入的风险,本例子只做最简单的数据库查询演示,默认用户没有输入非法字符。
SQL注入https://blog.csdn.net/Gherbirthday0916/article/details/134953282
boolean login(String userName, String password) {
try {
// mysql驱动类
Class.forName("com.mysql.cj.jdbc.Driver");
// 创建一个连接 public static Connection getConnection(String url, String user, String password)
Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/starter", "xxx", "xxx");
System.out.println("got connection");
Statement s = con.createStatement();
String sql = "SELECT UserName FROM user" +
" WHERE NAME='" + userName + "'" +
" AND PASSWORD='" + password + "'";
ResultSet rs = s.executeQuery(sql);
if (rs.next()) {
rs.close();
s.close();
con.close();
return true;
}
rs.close();
s.close();
con.close();
}
catch (ClassNotFoundException e) {
System.out.println(e);
}
catch (SQLException e) {
System.out.println(e);
}
catch (Exception e) {
System.out.println(e);
}
return false;
}
如图,可以构造恶意的SQL,就可以绕过用户密码验证,登录任意用户。
2.2.2 构造SQL语句时,对用户传入的参数进行预处理PreparedStatement
使用preparedStatement,会对参数进行预处理,可以有效阻挡SQL注入
boolean login(String userName, String password) {
try {
// mysql
Class.forName("com.mysql.cj.jdbc.Driver");
// public static Connection getConnection(String url, String user, String password)
Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/starter", "xxx", "xxx");
System.out.println("got connection");
String sql = "SELECT NAME FROM core_user" +
" WHERE NAME=? AND PASSWORD=?";
PreparedStatement s = con.prepareStatement(sql);
s.setString(1, userName);
s.setString(2, password);
ResultSet rs = s.executeQuery();
if (rs.next()) {
rs.close();
s.close();
con.close();
return true;
}
rs.close();
s.close();
con.close();
}
catch (ClassNotFoundException e) {
System.out.println(e);
}
catch (SQLException e) {
System.out.println(e);
}
catch (Exception e) {
System.out.println(e);
}
return false;
}
2.3 编译运行访问
参照第一篇Java for the Web With Servlets, JSP, and EJB——PART1-First Servlet(Tomcat10.1.19)超原始手工编译并部署servlet程序