likes
comments
collection
share

Java的数据库连接

作者站长头像
站长
· 阅读数 17

JDBC,Java Database Connectivity,即 Java 数据库连接。实际上 JDBC 是 Java 中的一套和数据库进行交互的API。

因为 Java 程序员需要连接多种数据库,为了避免每一个数据库都学习一套新的API,SUN公司提出一个JDBC接口,各个数据库厂商根据接口写实现类(驱动),这样 Java 程序员只需要掌握 JDBC 接口中的一套方法,就可以访问任何数据库。

使用 JDBC 可以创建一个 Maven 工程,使用 Maven 工具便捷的下载 MySQL 驱动相关 Jar 包。使用实例如下:

    1. 创建 Maven 工程

使用 IntelliJ IDEA 新建工程,选择 Maven 工程:

Java的数据库连接

设置项目名称:

Java的数据库连接

    1. 添加 MySQL 驱动依赖 Jar 包

在 Maven 工程的 pom.xml 文件中加入 MySQL 驱动依赖,并下载 Jar 包:

Java的数据库连接

    1. 创建一个测试使用的 MySQL 数据库
// 创建名为 test_base 的数据库
CREATE DATABASE test_base;
// 使用 test_base 数据库
USE test_base;
// 创建名为 websites 的表
CREATE TABLE `websites` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` char(20) NOT NULL DEFAULT '' COMMENT '站点名称',
  `url` varchar(255) NOT NULL DEFAULT '',
  `alexa` int(11) NOT NULL DEFAULT '0' COMMENT 'Alexa 排名',
  `country` char(10) NOT NULL DEFAULT '' COMMENT '国家',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
// 在 websites 中插入数据
INSERT INTO `websites` VALUES ('1', 'Google', 'https://www.google.cm/', '1', 'USA'), 
('2', '淘宝', 'https://www.taobao.com/', '13', 'CN'), 
('3', '菜鸟教程', 'http://www.runoob.com', '5892', ''), 
('4', '微博', 'http://weibo.com/', '20', 'CN'), 
('5', 'Facebook', 'https://www.facebook.com/', '3', 'USA'),
('6', 'JueJin', 'https://www.juejin.cn/', '2213', 'CN');

Java的数据库连接

    1. 创建 Java 文件,编写 JDBC 相关代码
import java.sql.*;

/**
 * @Author:WG
 * @Package:PACKAGE_NAME
 * @Project:JDBCTest
 * @name:MySQLDemo
 * @Date:2023/5/17 21:35
 * @Filename:MySQLDemo
 */
public class MySQLDemo {

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

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


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

    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对象...");
            // 创建 Sql 执行对象
            stmt = conn.createStatement();
            // Sql 查询语句
            String sql = "SELECT id, name, url FROM websites";
            // 执行 Sql
            ResultSet rs = stmt.executeQuery(sql);

            // 展开结果集数据库,next()会判断有无下条数据,有的话返回 true
            while(rs.next()){
                // 通过字段检索
                int id  = rs.getInt("id");
                String name = rs.getString("name");
                String url = rs.getString("url");

                // 输出数据
                System.out.print("ID: " + id);
                System.out.print(", 站点名称: " + name);
                System.out.print(", 站点 URL: " + url);
                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!");
    }
}

// 程序运行结果如下:
// 连接数据库...
// 实例化Statement对象...
// ID: 1, 站点名称: Google, 站点 URL: https://www.google.cm/
// ID: 2, 站点名称: 淘宝, 站点 URL: https://www.taobao.com/
// ID: 3, 站点名称: 菜鸟教程, 站点 URL: http://www.runoob.com
// ID: 4, 站点名称: 微博, 站点 URL: http://weibo.com/
// ID: 5, 站点名称: Facebook, 站点 URL: https://www.facebook.com/
// ID: 6, 站点名称: JueJin, 站点 URL: https://www.juejin.cn/
// Goodbye!

DBCP - 数据库连接池

数据库连接池可以预先设置一定数量的初始连接,如果有业务需要使用连接,则从连接池中直接获取,如果连接池中连接用光,这些连接请求将被加入到等待队列中,等待连接归还后再获取连接。

数据库连接池避免了每一次业务都需要和数据库服务器建立一次连接,业务处理完成后再断开连接,因为频繁的开关连接非常的浪费资源,甚至造成服务器崩溃。

DBCP 使用实例

    1. 使用数据库连接池需要在 Maven 工程的 pom.xml 文件中加入依赖,并下载 Jar 包:
 <!-- dependencies标签主要用于管理项目中需要引入的其他依赖 -->
    <dependencies>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>

        <!--数据库连接池-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.1.1</version>
        </dependency>
    </dependencies>
  • 2. 创建 Java 文件,编写 JDBC 相关代码:
import org.apache.commons.dbcp2.BasicDataSource;
import java.sql.*;

/**
 * @Author:WG
 * @Package:PACKAGE_NAME
 * @Project:JDBCTest
 * @name:DBCPDemo
 * @Date:2023/5/18 15:09
 * @Filename:DBCPDemo
 */
public class DBCPDemo {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        // 获取连接池
        BasicDataSource dataSource = JdbcUtils.getDataSource();
        try {
            // 在连接池中获取连接
            conn = dataSource.getConnection();
            // 创建 Sql 执行对象
            stmt = conn.createStatement();
            // Sql 查询语句
            String sql = "SELECT id, name, url FROM websites";
            // 执行 Sql
            ResultSet rs = stmt.executeQuery(sql);
            // 展开结果集数据库,next()会判断有无下条数据,有的话返回 true
            while(rs.next()){
                // 通过字段检索
                int id  = rs.getInt("id");
                String name = rs.getString("name");
                String url = rs.getString("url");

                // 输出数据
                System.out.print("ID: " + id);
                System.out.print(", 站点名称: " + name);
                System.out.print(", 站点 URL: " + url);
                System.out.print("\n");
            }
            // 完成后关闭
            rs.close();
            stmt.close();
            conn.close();
        } catch (SQLException se) {
            // 获取连接错误
            se.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!");
    }
}

class JdbcUtils {
    // 创建连接池
    private static BasicDataSource dataSource = new BasicDataSource();
    static {
        //必须要的配置
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test_base?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        //可选配置
        dataSource.setMaxTotal(10);//连接池最大连接数
        dataSource.setMaxIdle(5);//连接池最大空闲数
        dataSource.setMinIdle(3);//连接池最小空闲数
        dataSource.setInitialSize(10);//初始化连接池时的连接数
    }
    // 获取连接池
    public static BasicDataSource getDataSource() {
        return dataSource;
    }
}

// 程序运行结果如下:
// ID: 1, 站点名称: Google, 站点 URL: https://www.google.cm/
// ID: 2, 站点名称: 淘宝, 站点 URL: https://www.taobao.com/
// ID: 3, 站点名称: 菜鸟教程, 站点 URL: http://www.runoob.com
// ID: 4, 站点名称: 微博, 站点 URL: http://weibo.com/
// ID: 5, 站点名称: Facebook, 站点 URL: https://www.facebook.com/
// ID: 6, 站点名称: JueJin, 站点 URL: https://www.juejin.cn/
// Goodbye!

使用数据库连接池也同样连接到了 MySQL 数据库,并打印了查询数据,这里并没有看出使用数据库连接池有什么优势,但如果使用 JDBC(非数据库连接池方式) 与 DBCP (数据库连接池方式)同时进行20000次数据库连接查询,消耗时间大概如下:

JDBC 耗时 40898毫秒
DBCP 耗时 3726毫秒