JDBC工具类 以及使用JDBC工具类 一般开发不可能直接使用 JDBC 了解即可

文章目录

  • JDBC工具类
    • 1 工具类的代码实现
      • 相关变量
      • 使用ResourceBundle 进行资源的绑定,主要是绑定到 jdbc.properties 文件,方便将这个配置文件里面的相关配置读取出来
      • (1)(2)加载驱动
      • 关闭资源
    • 2 工具类代码实现所有代码
      • package com.luobin.utils;
    • 3 调用工具类的代码实现
      • 创建进行数据库交互的相关变量
      • 调用静态方法进行连接的建立
      • (3)建立sql 语句,将建立的sql 语句进行预编译,得到预编译环境
      • (4)执行预编译得到处理结果
      • (5)对处理结果进行处理
      • (6)释放资源
    • 4 调用工具类的代码实现
      • package com.luobin.oa.web.action;
    • 5 sql 注入以及解决的方式
      • 怎么注入进去的
      • 怎么解决注入问题?
    • 小结

JDBC工具类

1 工具类的代码实现

相关变量

定义四个变量

  • driver

数据库的驱动,让程序可以使用数据库
com.mysql.jdbc.Driver

  • url

具体的数据库的位置

jdbc:mysql://localhost:3306/data

  • username
    可以访问数据库的用户名
  • password

使用ResourceBundle 进行资源的绑定,主要是绑定到 jdbc.properties 文件,方便将这个配置文件里面的相关配置读取出来

static { // 在类加载的时候,只需要执行一次即可
        ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
        driver = bundle.getString("driver");
        url = bundle.getString("url");
        username = bundle.getString("username");
        password = bundle.getString("password");
    }

(1)(2)加载驱动

  • 建立链接,建立链接的时候,把数据库的 url 用户名字以及密码传递进去
public static Connection getConnection() throws SQLException {
        Connection conn = null;
        try {
            Class.forName(driver);
            conn = DriverManager.getConnection(url, username, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return conn;
    }

关闭资源

public static void close(Connection conn, Statement ps, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

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

        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
- 关闭资源方法需要传递的三个参数,conn,Statement,ResultSet

2 工具类代码实现所有代码

package com.luobin.utils;

/**
 * @author Doraemon
 * @date 2021/12/12 12:08 下午
 * @version 1.0
 */

import java.sql.*;
import java.util.ResourceBundle;

/**
 * JDBC 工具类,用来简化 JDBC 编程
 */
public class DBUtil {
    /**
     * 工具类中的属性、方法都是私有的,
     * 因为工具类中的方法都是静态的,不需要直接的new 对象,直接使用类名字进行调用即可;
     */

    //私有变量
    private static String driver;
    private static String url;
    private static String username;
    private static String password;


    static { // 在类加载的时候,只需要执行一次即可
        ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
        driver = bundle.getString("driver");
        url = bundle.getString("url");
        username = bundle.getString("username");
        password = bundle.getString("password");
    }

    public static Connection getConnection() throws SQLException {
        Connection conn = null;
        try {
            Class.forName(driver);
            conn = DriverManager.getConnection(url, username, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 关闭资源
     * @param conn 连接对象
     * @param ps 数据库操作对象
     * @param rs 结果集
     */
    public static void close(Connection conn, Statement ps, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

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

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

3 调用工具类的代码实现

创建进行数据库交互的相关变量

  • Connection
  • PrepareStatement
  • ResultSet

调用静态方法进行连接的建立

  • conn = DBUtil.getConnection();

(3)建立sql 语句,将建立的sql 语句进行预编译,得到预编译环境

  • String sql = “select deptno,dname,loc from dept”;
    ps = conn.prepareStatement(sql);

(4)执行预编译得到处理结果

  • PrepareStatement是SQL语句预编译对象,当我们执行:preparedStatement = connection.prepareStatement(sql);这一行代码获取PrepareStatement对象的时候就会把传进去的sql语句进行编译并且加载进如内存中,在接下来的操作中我们只需要对sql语句中的占位符:?进行赋值,这样sql语句就不需要再次重新编译,这是与statement对象的最主要的差别

    • rs = ps.executeQuery();

(5)对处理结果进行处理

while (rs.next()) {
                String deptno = rs.getString("deptno");
                String dname = rs.getString("dname");
                String loc = rs.getString("loc");
                }

(6)释放资源

  • DBUtil.close(conn, ps, rs);

4 调用工具类的代码实现

package com.luobin.oa.web.action;

 /**
 * @author Doraemon
 * @date 2021/12/12 2:19 下午
 * @version 1.0
 */

import com.luobin.utils.DBUtil;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DeptListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null; 

        try {
            // 获取连接
            conn = DBUtil.getConnection(); // 加载驱动,获取连接,完成 1 2 步 getConnection方法里面有两步
           
            String sql = "select deptno,dname,loc from dept";
            ps = conn.prepareStatement(sql); // 获取预编译数据库操作对象,完成第 3 步
         
            rs = ps.executeQuery(); // 执行 sql 完成 4 步

            int i = 0;
            // 处理查询结果集合 完成第 5 步
            while (rs.next()) { // rs 里面的东西就是查询到的表格里面的东西,没有表头的一个表的部分数据
                String deptno = rs.getString("deptno");
                String dname = rs.getString("dname");
                String loc = rs.getString("loc");

                // 下面的界面进行动态的展示
  
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally { // 资源释放完成第 6 步
            DBUtil.close(conn, ps, rs);
        }
    }
}

5 sql 注入以及解决的方式

怎么注入进去的

  • 客户端在自己电脑操作时候,有一定的输入操作,这个输入操作中可能会有一些特殊符号的输入,把特殊的符号输入进去之后,会编译到SQL语句中,进而破坏正常的SQL语句的结构,导致安全漏洞问题,攻击者就可以执行计划外的命令或访问未被授权的数据
String sql = "select * from user_table where username=
' "+userName+" ' and password=' "+password+" '";

–当输入了上面的用户名和密码,上面的SQL语句变成:

SELECT * FROM user_table WHERE username='’or 1 = 1 -- and password='
--分析SQL语句:
--条件后面username=”or 1=1 用户名等于 ” 或1=1 那么这个条件一定会成功;

--然后后面加两个-,这意味着注释,它将后面的语句注释,让他们不起作用,这样语句永远都--能正确执行,用户轻易骗过系统,获取合法身份。
--这还是比较温柔的,如果是执行
SELECT * FROM user_table WHERE
username='' ;DROP DATABASE (DB Name) --' and password=''
--其后果可想而知…

怎么解决注入问题?

  • 参数化查询,使用了预编译的数据库操作对象,提前将SQL语句编译好,里面设置变量集,用户输入的部分作为变量的赋值,不参与到SQL语句的编译,没有破坏SQL语句结构,抵御了SQL注入

小结

1、通过了工具类在进行连接的时候,进行资源释放的时候,会简化代码

2、在工具类里面是没有写 sql 语句和解析的,因为在工具类里面不执行语句

你可能感兴趣的:(Java,数据库,mysql,java)