一起学Java——JDBC

Posted 专业bug开发

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一起学Java——JDBC相关的知识,希望对你有一定的参考价值。

前言

学习Java的对于JDBC肯定不会陌生。Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。

学习内容

测试使用JDBC

相关操作建议参照!!!
参考文章链接

  1. 新建项目结构如下,引入jar包到lib文件下;

  2. 设置jar包到项目环境;

  3. 数据库新建study数据库,并在该数据库下新建student表;

  4. 编写测试类代码如下;


import java.sql.*;

/**
 * Description:
 *
 * @Author: kk(专业bug开发)
 * DateTime: 2022-01-07 16:29
 */
public class JdbcExample 
//    mysql 8.0 以下版本 - JDBC 驱动名及数据库 URL
//    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
//    static final String DB_URL = "jdbc:mysql://localhost:3306/RUNOOB";

//     MySQL 8.0 以上版本 - JDBC 驱动名及数据库 URL
    static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://localhost:3306/study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";


    // 数据库的用户名与密码,需要根据自己的设置
    static final String USER = "root";
    static final String PASS = "123456";

    public static void main(String[] args) 
        Connection conn = null;
        Statement stmt = null;
        try 
            // 注册 JDBC 驱动
            Class.forName(JDBC_DRIVER);

            // 打开链接
            System.out.println("连接数据库...");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);

            // 执行查询
            System.out.println(" 实例化Statement对象...");
            stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT * FROM student");

            // 展开结果集数据库
            while (rs.next()) 
            //rs.next()返回布尔值,代表是否存在下一条记录
            //如果有,返回true。继续提取下一条记录
            //如果没有,返回false,结束循环
                // 通过字段检索
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String classname = rs.getString("classname");

                // 输出数据
                System.out.print("ID: " + id);
                System.out.print(", 姓名: " + name);
                System.out.print(", 班级: " + classname);
                System.out.print("\\n");
            
            // 完成后关闭
            rs.close();
            stmt.close();
            conn.close();
         catch (SQLException se) 
            // 处理 JDBC 错误
            se.printStackTrace();
         catch (Exception e) 
            // 处理 Class.forName 错误
            e.printStackTrace();
         finally 
            // 关闭资源
            try 
                if (stmt != null) stmt.close();
             catch (SQLException se2) 
            // 什么都不做
            try 
                if (conn != null)
                    conn.close();
             catch (SQLException se) 
                se.printStackTrace();
            
        
        System.out.println("Goodbye!");
    


  1. 测试代码运行结果如下;

预编译语句集防止SQL注入

  1. 首先我们明确一下什么是SQL注入。百度百科的解释如下:

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

  1. SQL注入测试,在查询语句后面拼接1=1,例如;
# 原本查询语句
SELECT * FROM student where classname = '" + cname + "'

# SQL注入后的语句
cname = ' or 1=1 or 1='

SELECT * FROM student where classname = '' or 1=1 or 1=''

  1. 使用预编译语句集防止SQL注入,实现逻辑如下;

import java.sql.*;
import java.util.Scanner;

/**
 * Description:
 *
 * @Author: kk(专业bug开发)
 * DateTime: 2022-01-07 16:29
 */
public class JdbcExample 
//    MySQL 8.0 以下版本 - JDBC 驱动名及数据库 URL
//    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
//    static final String DB_URL = "jdbc:mysql://localhost:3306/RUNOOB";

//     MySQL 8.0 以上版本 - JDBC 驱动名及数据库 URL
    static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://localhost:3306/study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";


    // 数据库的用户名与密码,需要根据自己的设置
    static final String USER = "root";
    static final String PASS = "123456";

    public static void main(String[] args) 
        Connection conn = null;
//        Statement stmt = null;
        PreparedStatement pstmt = null;
        try 
            // 注册 JDBC 驱动
            Class.forName(JDBC_DRIVER);

            // 打开链接
            System.out.println("连接数据库...");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);

            // 执行查询
            System.out.println(" 实例化Statement对象...");
            System.out.println("请输入待查询的班级:");

//            仔细看这部分代码,prepareStatement对sql进行了预编译
            Scanner in = new Scanner(System.in);
            String cname = in.next();
            String sql= "SELECT * FROM student where classname = ?";
            pstmt= conn.prepareStatement(sql);
            
            // 使用setString()设置参数
            pstmt.setString(1, cname);
            ResultSet rs = pstmt.executeQuery();
            
            
            
            // 展开结果集数据库
            while (rs.next()) 
                // 通过字段检索
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String classname = rs.getString("classname");

                // 输出数据
                System.out.print("ID: " + id);
                System.out.print(", 姓名: " + name);
                System.out.print(", 班级: " + classname);
                System.out.print("\\n");
            
            // 完成后关闭
            rs.close();
            pstmt.close();
            conn.close();
         catch (SQLException se) 
            // 处理 JDBC 错误
            se.printStackTrace();
         catch (Exception e) 
            // 处理 Class.forName 错误
            e.printStackTrace();
         finally 
            // 关闭资源
            try 
                if (pstmt != null) pstmt.close();
             catch (SQLException se2) 
            // 什么都不做
            try 
                if (conn != null)
                    conn.close();
             catch (SQLException se) 
                se.printStackTrace();
            
        
        System.out.println("Goodbye!");
    


封装使用DbUtils工具类

  1. 为什么需要封装这么一个类?

观察上面的代码,我们每进行一次数据库的操作就需要进行数据库的五项操作,代码内聚度不够高,当我们对这一段相同作用的代码进行封装,形成一个工具类,就可以完美解决代码多次重复的问题。

  1. 在我们的项目下新建一个包,存放公共类;
  2. 工具类代码编写如下,详细原理参见注释;
package com.five.jdbc.common;

import java.sql.*;

/**
 * Description:
 *
 * @Author: kk(专业bug开发)
 * DateTime: 2022-01-08 10:52
 */
public class DbUtils 
    //MySQL 8.0 以上版本-JDBC 驱动名及数据库 URL
    static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://localhost:3306/study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
    //数据库的用户名与密码
    static final String USER = "root";
    static final String PASS = "123456";

    /**
     * @Description: 创建数据库连接
     * @Param:
     * @return: 返回连接
     */
    public static Connection getConnection() throws ClassNotFoundException, SQLException 
        // 注册 JDBC 驱动
        Class.forName(JDBC_DRIVER);
        // 打开链接
        Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
        return conn;
    

    /**
     * @Description: 关闭连接,释放资源
     * @Param: rs-结果集对象, stmt-Statement对象,  conn-Connection对象
     */
    public static void closeConnection(ResultSet rs, Statement stmt, Connection conn) throws SQLException 
        // 关闭rs-结果集对象
        try 
            if (rs != null) 
                rs.close();
            
         catch (Exception e) 
            e.printStackTrace();
        
        // 关闭stmt-Statement对象
        try 
            if (stmt != null) 
                stmt.close();
            
         catch (Exception e) 
            e.printStackTrace();
        
        // 关闭conn-Connection对象
        try 
            if (conn != null && !conn.isClosed()) 
                conn.close();
            
         catch (Exception e) 
            e.printStackTrace();
        
    


  1. 使用工具类操作数据,新建类如下,原理参照注释;
  • 新增数据
package com.five.jdbc.example;

import com.five.jdbc.common.DbUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

/**
 * Description:
 *
 * @Author: kk(专业bug开发)
 * DateTime: 2022-01-08 13:06
 */
public class InsertExample
    public static void main(String[] args) throws SQLException 
        Scanner in = new Scanner(System.in);
        System.out.println("请输入学生编号:");
        int id = in.nextInt();
        System.out.println("请输入学生姓名:");
        String name = in.next();
        System.out.println("请输入学生班级:");
        String cname = in.next();

        Connection conn = null;
        PreparedStatement pstmt = null;
        try 
            conn = DbUtils.getConnection();
            String sql = "insert into student(id,name,classname) values(?,?,?)";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, id);
            pstmt.setString(2, name);
            pstmt.setString(3, cname);
            int cnt  = pstmt.executeUpdate();   //写操作影响的行数
            System.out.println("cnt" + cnt);
            System.out.println(name = "添加成功啦!");
         catch (ClassNotFoundException | SQLException e) 
            e.printStackTrace();
        finally 
            DbUtils.closeConnection(null, pstmt, conn);
        
    


  • 更新数据
package com.five.jdbc.example;

import com.five.jdbc.common.DbUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

/**
 * Description:
 *
 * @Author: kk(专业bug开发)
 * DateTime: 2022-01-08 13:27
 */
public class UpdateExample 
    public static void main(String[] args) throws SQLException 
        Scanner in = new Scanner(System.in);
        System.out.println("请输入学生编号:");
        int id = in.nextInt();
        System.out.println("请输入学生班级:");
        String cname = in.next();

        Connection conn = null;
        PreparedStatement pstmt = null;
        try 
            conn = DbUtils.getConnection();
            String sql = "update student set classname=? where id=?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, cname);
            pstmt.setInt(2, id);

            int cnt  = pstmt.executeUpdate();   //写操作影响的行数

            if(cnt == 1)
                System.out.println("学生班级调整完毕!");
            else
                System.out.println("没有找到对应编号学生!");
            
         catch (ClassNotFoundException | SQLException e) 
            e.printStackTrace();
        finally 
            DbUtils.closeConnection(null, pstmt, conn);
        
    


  • 删除数据
package com.five.jdbc.example;

import com.five.jdbc.common.DbUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

/**
 * Description:
 *
 * @Author: kk(专业bug开发)
 * DateTime: 2022-01-08 13:37
 */
public class DeleteExample 
    public static void main(String[] args) throws SQLException 
        Scanner in = new Scanner(System.in);
        System.out.println("请输入学生编号:");
        int id = in.nextInt();

        Connection conn = null;
        PreparedStatement pstmt = null;
        try 
            conn = DbUtils.getConnection();
            String sql = "delete from student where id=?";
            pstmt = c

以上是关于一起学Java——JDBC的主要内容,如果未能解决你的问题,请参考以下文章

跟着阿里p7一起学java高并发 - 第18天:玩转java线程池,这一篇就够了

跟我一起学mybatis

java学习之JDBC

Java学习之JDBC

java学习之jdbc的封装

Java学习之JDBC