JDBC学习

DBC 是一套用于Java程序访问数据库的API,它提供了连接数据库、执行SQL查询和处理结果的标准方法。通过JDBC,Java程序可以连接到多种数据库,包括MySQL、PostgreSQL、Oracle、SQL Server等。JDBC的主要组成部分包括:

  • JDBC Driver:驱动程序,用于与特定的数据库进行通信。每个数据库都有自己的JDBC驱动程序。
  • Connection:连接对象,用于连接数据库。
  • Statement:用于执行SQL查询的对象。
  • ResultSet:结果集对象,用于存储查询结果。
  • PreparedStatement:预编译的SQL语句对象,防止SQL注入攻击,提高查询效率。
  • CallableStatement:用于执行存储过程的对象。
java 复制代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class JDBCDemo {
    public static void main(String[] args) {
        try {
            // 加载驱动程序
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 建立连接
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password");
            // 创建Statement对象
            Statement statement = connection.createStatement();
            // 执行查询
            ResultSet resultSet = statement.executeQuery("SELECT * FROM mytable");
            // 处理结果
            while (resultSet.next()) {
                System.out.println("Column1: " + resultSet.getString("column1"));
                System.out.println("Column2: " + resultSet.getString("column2"));
            }
            // 关闭资源
            resultSet.close();
            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Connection

在JDBC中,Connection 对象是一个非常重要的接口,它代表了Java应用程序和数据库之间的一个连接会话。通过 Connection 对象,可以执行SQL语句、管理事务和处理数据库的连接和释放。以下是 Connection 接口的一些关键功能:

  • 创建 Statement 对象
    • createStatement():创建一个 Statement 对象来执行静态SQL语句。
    • prepareStatement(String sql):创建一个 PreparedStatement 对象来执行预编译的SQL语句。这种方式可以提高性能并防止SQL注入。
    • prepareCall(String sql):创建一个 CallableStatement 对象来调用数据库中的存储过程。
  • 事务管理
    • setAutoCommit(boolean autoCommit):设置此连接的事务是否自动提交。设置为 false 时,可以手动控制事务的提交或回滚。
    • commit():在事务中执行了多个操作后,使用此方法提交事务,确保所有操作都被保存到数据库中。
    • rollback():如果事务中的某个操作失败,可以调用此方法回滚事务,取消所有未提交的操作。
  • 连接管理
    • close():关闭此 Connection 对象和其所有相关的资源。一旦连接被关闭,就不能再使用它来执行任何操作。
    • isClosed():检查此连接是否已被关闭。
  • 元数据获取
    • getMetaData():获取与此数据库连接相关的元数据。这可以提供关于数据库的结构信息,如表、列、索引等。
  • 配置连接属性
    • setReadOnly(boolean readOnly):设置此连接的只读状态。只读连接意味着通过这个连接只能查询数据,不能执行插入、更新或删除操作。
    • setTransactionIsolation(int level):设置此连接的事务隔离级别,这影响了不同事务间的可见性和互相干扰的程度。

在实际开发中,建立 Connection 通常需要通过 DriverManager 类来完成,如下例所示:

java 复制代码
Connection conn = DriverManager.getConnection(url, username, password);

这里,url 是数据库的URL,username 是数据库用户名称,password 是对应的密码。正确管理 Connection 对象对于维护数据库性能和数据一致性至关重要。

Statement

在JDBC中,Statement 接口是用于执行静态SQL语句并返回它所生成结果的一种机制。通过 Connection 对象创建 Statement 对象,可以用来执行基本的SQL命令。

主要方法

  • 执行SQL语句
    • executeQuery(String sql): 执行给定的SQL语句,该语句返回一个单一的 ResultSet 对象(通常用于查询)。
    • executeUpdate(String sql): 执行给定的SQL语句(如INSERT、UPDATE、DELETE、DDL等),返回一个整数,表示受影响的行数。
    • execute(String sql): 可用于执行返回多个结果集、多个更新计数或二者组合的语句。
  • 资源管理 :
    • close(): 释放 Statement 对象的数据库和JDBC资源。注意,与之关联的任何 ResultSet 对象也将被关闭。
  • 批处理执行 :
    • addBatch(String sql): 将多个SQL语句添加到批处理中,这些语句一起执行可以减少通信开销,提高性能。
    • executeBatch(): 执行批量更新。
  • 设置查询超时 :
    • setQueryTimeout(int seconds): 设置在抛出异常前 Statement 等待数据库回应的秒数。
java 复制代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class StatementExample {
    public static void main(String[] args) {
        try {
            // 建立连接
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password");
            // 创建Statement对象
            Statement statement = connection.createStatement();

            // 执行查询
            ResultSet resultSet = statement.executeQuery("SELECT * FROM employees");
            while (resultSet.next()) {
                System.out.println(resultSet.getString("name") + ", " + resultSet.getInt("age"));
            }

            // 执行更新
            int rowsAffected = statement.executeUpdate("UPDATE employees SET age = age + 1 WHERE id = 1");
            System.out.println("Updated rows: " + rowsAffected);

            // 关闭资源
            resultSet.close();
            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

注意事项

  • SQL注入:直接使用 Statement 执行SQL语句容易受到SQL注入的攻击,特别是当SQL语句包含来自不可靠源的数据时。在这种情况下,更推荐使用 PreparedStatement,因为它支持参数化查询,可以有效防止SQL注入。
  • 性能:频繁地创建和销毁 Statement 对象可能导致性能问题,特别是在大量操作数据库的应用中。预编译的 PreparedStatement 对象通常提供更好的性能,因为它们可以重复使用。

通过适当使用 Statement 和管理其生命周期,可以有效地在Java应用程序中管理数据库操作。

ResultSet

在JDBC中,ResultSet 接口代表从数据库查询返回的数据集。当执行查询数据库的SQL语句(通常是SELECT语句)时,Statement 或 PreparedStatement 对象的 executeQuery 方法会返回一个 ResultSet 对象。这个对象可以用来逐行访问查询结果。

主要方法和功能

  • 数据访问 :
    • next(): 将光标从当前位置向前移动一行。初次调用 next 方法将光标置于第一行。如果行存在,则返回 true;如果没有更多行,则返回 false。
    • getString(int columnIndex) 或 getString(String columnLabel): 获取当前行中指定列的值作为字符串。
    • 类似地,getInt, getDouble, getDate 等方法可用于获取其它数据类型的列值。
  • 遍历
    • ResultSet 对象最初位于第一行之前。next() 方法用于逐行遍历数据,通常在循环中使用。
  • 更新数据 :
    • 如果 ResultSet 是可更新的(依赖于如何创建 Statement 对象),可以修改其数据并反映回数据库。
    • updateString, updateInt 等方法修改列值,updateRow 提交修改。
  • 关闭 ResultSet :
    • close(): 关闭 ResultSet 对象并释放相关资源。注意,一旦 Statement 对象被关闭,其生成的所有 ResultSet 对象也将自动关闭。
java 复制代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class ResultSetExample {
    public static void main(String[] args) {
        try {
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password");
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery("SELECT id, name, age FROM employees");

            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");

                System.out.println("ID: " + id + ", Name: " + name + ", Age: " + age);
            }

            resultSet.close();
            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

JDBC工具类编写

首先,我们需要创建一个工具类,提供数据库连接和资源关闭的方法。这个类通常会包含获取连接、关闭 ResultSet、关闭 Statement 和 PreparedStatement、以及关闭 Connection 的静态方法。

java 复制代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCUtils {

    private static final String JDBC_URL = "jdbc:mysql://localhost:3306/mydatabase";
    private static final String JDBC_USER = "username";
    private static final String JDBC_PASSWORD = "password";

    static {
        try {
            // 加载数据库驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 获取数据库连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD);
    }

    // 关闭连接和语句
    public static void close(Statement stmt, Connection conn) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // 关闭所有资源
    public static void close(ResultSet rs, Statement stmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        close(stmt, conn);
    }
}

使用 JDBC 工具类

java 复制代码
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UseJDBCUtils {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;

        try {
            conn = JDBCUtils.getConnection(); // 使用工具类获取数据库连接
            String sql = "SELECT * FROM employees WHERE department_id = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, 10); // 设置参数

            rs = pstmt.executeQuery();
            while (rs.next()) {
                System.out.println("Employee Name: " + rs.getString("name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs, pstmt, conn); // 使用工具类关闭资源
        }
    }
}
  • 集中管理:JDBC 工具类有助于集中管理数据库连接和关闭操作,避免代码冗余。
  • 异常处理:通过在工具类中统一处理异常,可以简化错误处理。
  • 改进安全性:确保所有数据库连接和相关资源在使用后都被正确关闭,避免资源泄露。
相关推荐
极客先躯14 分钟前
高级java每日一道面试题-2024年10月3日-分布式篇-分布式系统中的容错策略都有哪些?
java·分布式·版本控制·共识算法·超时重试·心跳检测·容错策略
夜月行者35 分钟前
如何使用ssm实现基于SSM的宠物服务平台的设计与实现+vue
java·后端·ssm
程序猿小D39 分钟前
第二百六十七节 JPA教程 - JPA查询AND条件示例
java·开发语言·前端·数据库·windows·python·jpa
潘多编程1 小时前
Java中的状态机实现:使用Spring State Machine管理复杂状态流转
java·开发语言·spring
_阿伟_1 小时前
SpringMVC
java·spring
鲨鱼辣椒丶D1 小时前
「漏洞复现」用友U8 CRM config/fillbacksettingedit.php SQL注入漏洞
web安全
代码在改了1 小时前
springboot厨房达人美食分享平台(源码+文档+调试+答疑)
java·spring boot
wclass-zhengge2 小时前
数据结构篇(绪论)
java·数据结构·算法
何事驚慌2 小时前
2024/10/5 数据结构打卡
java·数据结构·算法
结衣结衣.2 小时前
C++ 类和对象的初步介绍
java·开发语言·数据结构·c++·笔记·学习·算法