Java for the Web With Servlets, JSP, and EJB(Part1-Chapter4)Accessing Databases with JDBC(java.sql)

上一篇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包
MySQLcom.mysql.cj.jdbc.Drivermysql-connector-java-8.0.30.jar
Oracleoracle.jdbc.driver.OracleDriver
PostgreSQLorg.postgresql.Driver
SQL Servercom.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程序

  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值