JDBC基础

重生之我在CSDN学java 第三天(JDBC)

在这里插入图片描述

一、概要

JDBC(Java Database Connectivity)是Java语言中用于数据库连接的一套API。它提供了一种标准的方法来访问各种关系型数据库管理系统(RDBMS),如MySQL、Oracle、SQL Server等。JDBC API允许Java程序执行SQL语句,从而实现对数据库的查询、更新、插入和删除等操作。

JDBC驱动管理器: 负责加载和管理JDBC驱动程序。当应用程序需要连接数据库时,它会加载相应的JDBC驱动程序。
JDBC驱动程序: 实现了JDBC接口的具体实现类,负责与数据库进行通信。不同的数据库厂商会提供不同的JDBC驱动程序。
JDBC接口: 定义了Java程序与数据库交互的标准方法,如Connection、Statement、PreparedStatement、ResultSet等。
JDBC工具类: 如DriverManager、DataSource等,用于简化数据库连接和管理。

二、JDBC的基本步骤

1.基本数据

 // 数据库URL、用户名和密码
String url = "jdbc:mysql://localhost:3306/wzry";
String user = "root";
String password = "123456";

2.加载JDBC驱动程序

Class.forName("com.mysql.cj.jdbc.Driver");

3.建立数据库连接

Connection conn = DriverManager.getConnection(url, user, password);

4.创建Statement或PreparedStatement对象

Statement stmt = conn.createStatement();

5.执行SQL语句

ResultSet rs = stmt.executeQuery("SELECT * FROM user")

6.处理查询结果

// 处理查询结果
   while (rs.next()) {
   // 假设your_table有一个名为column_name的列
     String columnValue = rs.getString("name");
     System.out.println(columnValue);
}

7.关闭数据库连接

stmt.close();
// 关闭连接
conn.close();

8.实例

JDBC连接到MySQL数据库并执行一个查询:

/**
* @BelongsProject: java_JDBC
* @BelongsPackage: PACKAGE_NAME
* @Author: liwenfei
* @CreateTime: 2024-07-02  09:50
* @Description: TODO
* @Version: 1.0
*/
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) {
        // 数据库URL、用户名和密码
        String url = "jdbc:mysql://localhost:3306/wzry";
        String user = "root";
        String password = "123456";


        // 加载JDBC驱动程序
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return;
        }


        // 建立数据库连接
        try (Connection conn = DriverManager.getConnection(url, user, password);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM user")) {
            // 处理查询结果
            while (rs.next()) {
                // 假设your_table有一个名为column_name的列
                String columnValue = rs.getString("name");
                System.out.println(columnValue);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

第一步必须导入jar包,不然会报错的,就像下面这样
在这里插入图片描述
官网下载 : 下载
直接下载 : 下载
绿色路径 : 下载

下载好的安装包解压缩后,把jar包导入到项目里面,同事加入到项目中:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
启动main
在这里插入图片描述

三、JDBC各个功能类详解

DriverManager 是Java JDBC API 中的一个类,它负责管理 JDBC 驱动程序,并为应用程序提供数据库连接。DriverManager 类是 JDBC 1.0 规范的一部分,它通过加载数据库驱动程序来实现与数据库的连接。在 JDBC 4.0 及以后的版本中,驱动程序 的注册和加载过程变得更加自动化,但 DriverManager 仍然扮演着重要的角色。
主要功能

1.加载驱动程序

DriverManager 类通过 DriverManager.registerDriver() 方法注册 JDBC 驱动程序。在 JDBC 4.0 之前,开发者需要手动加载驱动程序,例如通过 Class.forName("com.mysql.jdbc.Driver")。从 JDBC 4.0 开始,如果驱动程序的 JAR 文件在类路径中,JVM 会自动加载实现了 java.sql.Driver 接口的类。

2.建立连接

DriverManager.getConnection() 方法用于获取数据库连接。它接受数据库的 URL、用户名和密码作为参数,并返回一个 Connection 对象例如:

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password");

3.管理连接

DriverManager 类还负责管理数据库连接池,尽管在实际应用中,通常会使用第三方库(如 Apache DBCP 或 C3P0)来实现连接池。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DriverManagerExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydatabase";
        String user = "username";
        String password = "password";
        try {
            Connection conn = DriverManager.getConnection(url, user, password);
            System.out.println("Connected to the database!");
            // 使用 conn 进行数据库操作...
            conn.close(); // 关闭连接
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
1.Connection

Connection 是 Java JDBC API 中的一个接口,代表与数据库的连接。通过 Connection 对象,可以执行 SQL 语句、管理事务以及创建 Statement、PreparedStatement 和 CallableStatement 对象。它是与数据库交互的起点,提供了执行数据库操作所需的所有方法。

1.创建 Connection 对象

要获取 Connection 对象,通常使用 DriverManager.getConnection() 方法,传入数据库的 URL、用户名和密码。例如:

String url = "jdbc:mysql://localhost:3306/mydatabase";
String user = "username";
String password = "password";
Connection conn = DriverManager.getConnection(url, user, password);
2.Connection 接口的主要方法
1.执行 SQL 语句

Statement createStatement():创建一个 Statement 对象用于执行静态 SQL 语句。
PreparedStatement prepareStatement(String sql):创建一个 PreparedStatement 对象用于执行预编译的 SQL 语句。
CallableStatement prepareCall(String sql):创建一个 CallableStatement 对象用于执行 SQL 存储过程。

2.管理事务

void setAutoCommit(boolean autoCommit):设置是否自动提交事务。
void commit():提交当前事务。
void rollback():回滚当前事务。

3.关闭连接:

void close():关闭与数据库的连接。

4.其他:

DatabaseMetaData getMetaData():获取数据库的元数据。
void setReadOnly(boolean readOnly):设置连接为只读模式。
void setTransactionIsolation(int level):设置事务隔离级别。

实例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydatabase";
        String user = "username";
        String password = "password";
        try {
            // 获取数据库连接
            Connection conn = DriverManager.getConnection(url, user, password);
            // 设置自动提交为 false,开始一个事务
            conn.setAutoCommit(false);
            // 创建 Statement 对象
            Statement stmt = conn.createStatement();
            // 执行 SQL 语句
            stmt.executeUpdate("INSERT INTO mytable (column1, column2) VALUES ('value1', 'value2')");
            // 提交事务
            conn.commit();
            // 关闭 Statement 对象
            stmt.close();
            // 关闭连接
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
2.Statement

Statement 是 Java JDBC API 中的一个接口,用于执行静态 SQL 语句并返回它所生成结果的对象。Statement 对象用于执行不带参数的 SQL 语句,如 SELECT、INSERT、UPDATE 和 DELETE 等。它是最基本的执行 SQL 语句的方式,但不推荐用于执行带参数的 SQL 语句,因为这可能会导致 SQL 注入攻击。

1.创建 Statement 对象

创建 Statement 对象要创建 Statement 对象,你需要先有一个 Connection 对象。然后,使用 Connection 对象的 createStatement() 方法来创建 Statement 对象。

Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
2.执行 SQL 语句
1.查询语句

executeQuery(String sql):用于执行返回单个 ResultSet 的 SQL 查询语句。返回的 ResultSet 包含了查询结果。

2.INSERT、UPDATE、DELETE

executeUpdate(String sql):用于执行 INSERT、UPDATE、DELETE 等不返回结果集的 SQL 语句。返回一个整数,表示受影响的行数。

3.返回一个布尔值

execute(String sql)用于执行任何类型的 SQL 语句。返回一个布尔值,表示是否返回了ResultSet

3.ResultSet

ResultSet 是 Java JDBC API 中的一个接口,它代表了数据库查询操作返回的结果集。ResultSet 对象包含了执行 SQL 查询后从数据库中检索到的数据。通过 ResultSet,你可以遍历查询结果中的每一行数据,并访问每一行中的各个列。

public static void main(String[] args) {
        // 数据库连接信息
        String url = "jdbc:mysql://localhost:3306/mydatabase"; // 数据库URL
        String user = "username"; // 数据库用户名
        String password = "password"; // 数据库密码
        // 用于存储查询结果的变量
        int id;
        String name;
        double salary;
        try {
            // 加载数据库驱动程序
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 建立数据库连接
            Connection conn = DriverManager.getConnection(url, user, password);
            // 创建Statement对象
            Statement stmt = conn.createStatement();
            // 执行SQL查询
            String sql = "SELECT id, name, salary FROM employees"; // 查询员工表
            ResultSet rs = stmt.executeQuery(sql);
            // 遍历结果集
            while (rs.next()) {
                // 从结果集中获取数据
                id = rs.getInt("id"); // 获取id列的值
                name = rs.getString("name"); // 获取name列的值
                salary = rs.getDouble("salary"); // 获取salary列的值
                // 打印结果
                System.out.println("ID: " + id + ", Name: " + name + ", Salary: " + salary);
            }
            // 关闭ResultSet
            rs.close();
            // 关闭Statement
            stmt.close();
            // 关闭数据库连接
            conn.close();
        } catch (Exception e) {
            // 打印异常信息
            e.printStackTrace();
        }
    }

定义了数据库的连接信息,包括数据库的URL、用户名和密码。然后,我们使用 Class.forName() 方法加载了数据库驱动程序。接着,我们通过 DriverManager.getConnection() 方法建立了与数据库的连接,并创建了一个 Statement 对象来执行 SQL 查询。
执行查询后,我们使用 ResultSet 对象来遍历查询结果。在 while 循环中,我们使用 getInt(), getString(), 和 getDouble() 方法从 ResultSet 中获取每一行的数据,并将其打印出来。最后,我们按照顺序关闭了 ResultSet、Statement 和 Connection 对象。

四、工具类(Utility Class)

工具类(Utility Class)通常用于封装数据库连接的创建和关闭等重复性代码,以简化数据库操作。下面是一个简单的JDBC工具类示例,它包含了获取数据库连接、关闭连接、关闭结果集和关闭语句的方法。

1.JDBC工具类示例

1.创建工具类

创建一个名为 DBUtil.java 的工具类,用于管理数据库连接。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBUtil {
    private static final String URL = "jdbc:mysql://localhost:3306/mydatabase";
    private static final String USER = "username";
    private static final String PASSWORD = "password";
    private static final String DRIVER_CLASS = "com.mysql.cj.jdbc.Driver";
    static {
        try {
            Class.forName(DRIVER_CLASS);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(URL, USER, PASSWORD);
    }
}
2.创建 User 类
public class User {
    private long id;
    private int heroId;
    private String name;
    private String phone;
    private String sex;
    private String idNumber;
    private String avatar;
    private int status;
    // Getters and Setters
3.创建 CRUD 操作类
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class UserDao {
    public void insertUser(User user) {
        String sql = "INSERT INTO user (hero_id, name, phone, sex, id_number, avatar, status) VALUES (?, ?, ?, ?, ?, ?, ?)";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, user.getHeroId());
            pstmt.setString(2, user.getName());
            pstmt.setString(3, user.getPhone());
            pstmt.setString(4, user.getSex());
            pstmt.setString(5, user.getIdNumber());
            pstmt.setString(6, user.getAvatar());
            pstmt.setInt(7, user.getStatus());
            pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public User getUserById(long id) {
        User user = null;
        String sql = "SELECT * FROM user WHERE id = ?";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setLong(1, id);
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()) {
                user = new User();
                user.setId(rs.getLong("id"));
                user.setHeroId(rs.getInt("hero_id"));
                user.setName(rs.getString("name"));
                user.setPhone(rs.getString("phone"));
                user.setSex(rs.getString("sex"));
                user.setIdNumber(rs.getString("id_number"));
                user.setAvatar(rs.getString("avatar"));
                user.setStatus(rs.getInt("status"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return user;
    }
    public void updateUser(User user) {
        String sql = "UPDATE user SET hero_id = ?, name = ?, phone = ?, sex = ?, id_number = ?, avatar = ?, status = ? WHERE id = ?";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, user.getHeroId());
            pstmt.setString(2, user.getName());
            pstmt.setString(3, user.getPhone());
            pstmt.setString(4, user.getSex());
            pstmt.setString(5, user.getIdNumber());
            pstmt.setString(6, user.getAvatar());
            pstmt.setInt(7, user.getStatus());
            pstmt.setLong(8, user.getId());
            pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void deleteUser(long id) {
        String sql = "DELETE FROM user WHERE id = ?";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setLong(1, id);
            pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public List<User> getAllUsers() {
        List<User> users = new ArrayList<>();
        String sql = "SELECT * FROM user";
        try (Connection conn = DBUtil.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {
            while (rs.next()) {
                User user = new User();
                user.setId(rs.getLong("id"));
                user.setHeroId(rs.getInt("hero_id"));
                user.setName(rs.getString("name"));
                user.setPhone(rs.getString("phone"));
                user.setSex(rs.getString("sex"));
                user.setIdNumber(rs.getString("id_number"));
                user.setAvatar(rs.getString("avatar"));
                user.setStatus(rs.getInt("status"));
                users.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return users;
    }
}

4.创建 CRUD 测试类
public class TestJDBC {
    public static void main(String[] args) {
        UserDao userDao = new UserDao();
        // 插入用户
        User newUser = new User();
        newUser.setHeroId(1001);
        newUser.setName("张三");
        newUser.setPhone("13800138000");
        newUser.setSex("男");
        newUser.setIdNumber("110101199003071234");
        newUser.setAvatar("http://example.com/avatar.jpg");
        newUser.setStatus(1);
        userDao.insertUser(newUser);
        // 查询用户
        User user = userDao.getUserById(1);
        System.out.println("User: " + user);
        // 更新用户
        user.setPhone("13800138001");
        userDao.updateUser(user);
        // 删除用户
        userDao.deleteUser(1);
        // 获取所有用户
        List<User> users = userDao.getAllUsers();
        for (User u : users) {
            System.out.println(u);
        }
    }
}
4.配置文件配置JDBC

使用配置文件来管理数据库连接信息是一种常见的做法,这样可以使得数据库连接信息与代码分离,便于维护和修改。下面是一个简单的示例,展示如何使用配置文件来配置JDBC连接。
在这里插入图片描述

1.配置文件

创建一个db.properties文件

# 数据库连接配置
db.url=jdbc:mysql://localhost:3306/your_database
db.user=your_username
db.password=your_password
db.driver=com.mysql.cj.jdbc.Driver
2.加载配置文件
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class DbConfig {
    private static final String DB_CONFIG_FILE = "db.properties";
    public static Properties loadDbProperties() {
        Properties properties = new Properties();
        try (InputStream input = DbConfig.class.getClassLoader().getResourceAsStream(DB_CONFIG_FILE)) {
            if (input == null) {
                throw new IOException("Sorry, unable to find " + DB_CONFIG_FILE);
            }
            properties.load(input);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return properties;
    }
}
1.使用配置文件中的属性
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JdbcUtil {
    public static Connection getConnection() throws SQLException {
        Properties dbProperties = DbConfig.loadDbProperties();
        String url = dbProperties.getProperty("db.url");
        String user = dbProperties.getProperty("db.user");
        String password = dbProperties.getProperty("db.password");
        String driver = dbProperties.getProperty("db.driver");
        // 加载数据库驱动
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            throw new SQLException("Driver not found", e);
        }
        // 获取数据库连接
        return DriverManager.getConnection(url, user, password);
    }
    // 其他方法保持不变...
}
4.使用JdbcUtil类
import java.sql.Connection;
import java.sql.Statement;
public class Example {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = JdbcUtil.getConnection();
            stmt = conn.createStatement();
            // 执行SQL操作...
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源...
        }
    }
}

五、JDBC事务

管理事务是通过Connection对象来实现的。事务是数据库操作的一个单元,它由一系列的操作组成,这些操作要么全部成功,要么全部失败。在JDBC中,事务管理是通过设置连接的自动提交模式和使用commit()与rollback()方法来完成的。

1.自动提交模式

默认情况下,JDBC连接是处于自动提交模式的。这意味着每个单独的SQL语句执行完毕后,都会自动提交到数据库,成为不可回滚的事务。要关闭自动提交模式,可以调用Connection对象的setAutoCommit(false)方法。

2.手动提交事务

关闭自动提交模式后,你可以手动控制事务的提交。在执行一系列的数据库操作后,如果所有操作都成功,你可以调用commit()方法来提交事务。如果在事务执行过程中发生错误,你可以调用rollback()方法来回滚事务,撤销所有未提交的操作。

示例代码

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TransactionExample {
public static void main(String[] args) {
// 数据库连接信息
String url = “jdbc:mysql://localhost:3306/your_database”;
String user = “your_username”;
String password = “your_password”;
Connection conn = null;
Statement stmt = null;
try {
// 加载数据库驱动
Class.forName(“com.mysql.cj.jdbc.Driver”);
// 建立数据库连接
conn = DriverManager.getConnection(url, user, password);
// 关闭自动提交模式
conn.setAutoCommit(false);
// 创建Statement对象
stmt = conn.createStatement();
// 执行一系列的数据库操作
stmt.executeUpdate(“INSERT INTO your_table (column1, column2) VALUES (‘value1’, ‘value2’)”);
stmt.executeUpdate(“UPDATE your_table SET column1 = ‘new_value’ WHERE column2 = ‘value2’”);
// 如果所有操作都成功,提交事务
conn.commit();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
try {
// 如果发生异常,回滚事务
if (conn != null) {
conn.rollback();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
// 关闭资源
try {
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

在上面的示例中,我们首先关闭了自动提交模式,然后执行了两个SQL语句。如果两个语句都成功执行,我们调用commit()方法提交事务。如果在执行过程中发生异常,我们捕获异常并调用rollback()方法回滚事务,然后关闭所有资源。

六、数据库连接池

数据库连接池是一种用于管理数据库连接的技术,它通过预先创建一定数量的数据库连接,并将这些连接保存在池中,以供应用程序重复使用。这样可以减少频繁创建和销毁数据库连接的开销,提高数据库操作的性能和效率。

1.为什么需要数据库连接池

数据库连接的创建和销毁是一个相对耗时的操作,特别是在高并发的应用场景中,频繁地创建和关闭连接会显著降低应用程序的性能。数据库连接池通过重用连接来避免这种开销,从而提高性能。

2.为数据库连接池的工作原理

数据库连接池通常包含以下几个关键组件:
连接池: 存储数据库连接的容器。
连接工厂: 用于创建新的数据库连接。
连接池管理器: 负责管理连接池中的连接,包括分配连接、回收连接、维护连接池的大小等。
连接池配置: 配置连接池的参数,如初始连接数、最大连接数、连接超时时间等。常见的数据库连接池实现
C3P0: 一个开源的JDBC连接池库,提供了对JDBC的扩展,支持自动化的配置和管理。
Apache DBCP: Apache软件基金会提供的一个数据库连接池实现,支持JDBC 4.0的自动加载驱动程序。
HikariCP: 一个高性能的数据库连接池,以其快速和轻量级而闻名。
Druid: 阿里巴巴开源的一个数据库连接池实现,除了提供连接池的基本功能外,还提供了强大的监控和扩展功能。使用数据库连接池的好处
性能提升: 通过重用连接,减少了连接的创建和销毁时间,提高了数据库操作的性能。
资源管理: 连接池管理连接的生命周期,确保连接资源的有效利用。
配置灵活: 可以配置连接池的大小、超时时间等参数,以适应不同的应用场景。
故障恢复: 连接池可以处理连接的异常情况,如连接超时或数据库不可达,从而提高系统的健壮性。

3.为如何使用数据库连接池

1.C3P0

C3P0 是一个开源的 JDBC 连接池库,它提供了对 JDBC 的扩展,支持自动化的配置和管理。以下是一个使用 C3P0 连接池的示例代码,演示如何配置和使用 C3P0 连接池。

C3P0jar包:下载

1. 添加 C3P0 依赖

如果你使用 Maven,可以在 pom.xml 文件中添加 C3P0 的依赖:

<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.5</version>
</dependency>
2. 配置 C3P0

创建一个名为 c3p0-config.xml 的配置文件,并将其放置在项目的 src/main/resources 目录下

<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/your_database</property>
        <property name="user">your_username</property>
        <property name="password">your_password</property>
        
        <!-- 连接池参数 -->
        <property name="initialPoolSize">3</property>
        <property name="minPoolSize">3</property>
        <property name="maxPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxStatements">50</property>
    </default-config>
</c3p0-config>
3. 使用 C3P0 连接池

创建一个名为 C3P0Example.java 的类,并使用 C3P0 连接池来获取数据库连接:


import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class C3P0Example {
    public static void main(String[] args) {
        // 创建 C3P0 数据源
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        try {
            // 获取数据库连接
            Connection conn = dataSource.getConnection();
            // 执行数据库操作
            // ...
            // 关闭连接
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

在上面的代码中,我们首先创建了一个 ComboPooledDataSource 对象,这是 C3P0 提供的用于管理数据库连接池的类。然后,我们通过调用 dataSource.getConnection() 方法获取数据库连接。执行完数据库操作后,我们调用 conn.close() 方法将连接归还给连接池。

2. Druid
1. 添加 Druid 依赖

driuid.jar包: 下载
如果你使用 Maven,可以在 pom.xml 文件中添加 Druid 的依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.6</version>
</dependency>
2. 配置 Druid

创建一个名为 druid.properties 的配置文件,并将其放置在项目的 src/main/resources 目录下

# 数据库连接信息
druid.url=jdbc:mysql://localhost:3306/your_database
druid.username=your_username
druid.password=your_password
# 初始化大小,最小,最大
druid.initialSize=5
druid.minIdle=5
druid.maxActive=20
# 配置获取连接等待超时的时间
druid.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
druid.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
druid.minEvictableIdleTimeMillis=300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
druid.maxEvictableIdleTimeMillis=900000
# 配置检测连接是否有效的 SQL
druid.validationQuery=SELECT 'x'
druid.testWhileIdle=true
druid.testOnBorrow=false
druid.testOnReturn=false
# 打开 PSCache,并且指定每个连接上 PSCache 的大小
druid.poolPreparedStatements=true
druid.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的 filters
druid.filters=stat,wall,log4j
3. 使用 Druid 连接池
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class DruidExample {
    public static void main(String[] args) {
        // 加载配置文件
        Properties properties = new Properties();
        try {
            properties.load(DruidExample.class.getClassLoader().getResourceAsStream("druid.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 创建 Druid 数据源
        DataSource dataSource = null;
        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 获取数据库连接
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            // 执行数据库操作
            // ...
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭连接
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

在上面的代码中,我们首先加载了 druid.properties 配置文件,然后使用 DruidDataSourceFactory.createDataSource() 方法创建了一个 DataSource 对象。接着,我们通过调用 dataSource.getConnection() 方法获取数据库连接。执行完数据库操作后,我们调用 conn.close() 方法将连接归还给连接池。

七、防止SQL注入

PreparedStatement可以有效预防SQL注入攻击。PreparedStatement是在数据库中预编译并存储的SQL语句,它使用参数值而不是将用户输入直接嵌入SQL语句中。这样,即使用户输入被认为是恶意的或格式错误的数据,它也不会改变预编译语句的结构,从而防止了SQL注入攻击。

PreparedStatement

PreparedStatement 是 Java JDBC API 中的一个接口,它继承自 Statement 接口。PreparedStatement 用于执行预编译的 SQL 语句,它提供了比 Statement 更多的功能和优势,特别是在执行带有参数的 SQL 语句时。
####预编译 SQL 语句的优势
性能提升: 预编译的 SQL 语句在执行前已经由数据库编译过,因此在执行时不需要再次编译,这可以显著提高执行效率。
性能提升: 预编译的 SQL 语句在执行前已经由数据库编译过,因此在执行时不需要再次编译,这可以显著提高执行效率。
代码可读性和可维护性: 使用 PreparedStatement 可以使代码更加清晰和易于维护,特别是当 SQL 语句中包含多个参数时。

1.创建 PreparedStatement 对象

要创建 PreparedStatement 对象,通常使用 Connection 对象的 prepareStatement() 方法,并传入一个 SQL 语句模板。SQL 语句模板中可以包含占位符(通常是问号 ?),用于后续设置参数。

String sql = "INSERT INTO mytable (column1, column2) VALUES (?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql);
2.设置参数

使用 setXXX() 方法系列来设置 SQL 语句中的参数,其中 XXX 是参数的数据类型。

pstmt.setString(1, "value1"); pstmt.setInt(2, 123);

在上面的代码中,setString(1, “value1”) 表示将第一个参数设置为字符串 “value1”,setInt(2, 123) 表示将第二个参数设置为整数 123。参数的索引从 1 开始。

3.执行 SQL 语句

用于执行任何类型的 SQL 语句。返回一个布尔值,表示是否返回了ResultSet
PreparedStatement 提供了 executeUpdate() 和 executeQuery() 方法来执行 SQL 语句。executeUpdate() 用于执行 INSERT、UPDATE、DELETE 等操作,返回受影响的行数。executeQuery() 用于执行 SELECT 语句,返回一个 ResultSet 对象。

// 执行 INSERT 语句
int affectedRows = pstmt.executeUpdate();
System.out.println("Affected rows: " + affectedRows);
// 执行 SELECT 语句
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
    // 处理结果集
}

关闭 PreparedStatement
使用完毕后,应关闭 PreparedStatement 对象以释放数据库资源。

pstmt.close();

实例:

```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class PreparedStatementExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydatabase";
        String user = "username";
        String password = "password";
        try {
            Connection conn = DriverManager.getConnection(url, user, password);
            String sql = "INSERT INTO mytable (column1, column2) VALUES (?, ?)";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, "value1");
            pstmt.setInt(2, 123);
            int affectedRows = pstmt.executeUpdate();
            System.out.println("Affected rows: " + affectedRows);
            pstmt.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值