druid1.2.8源码阅读:第一天

本文记录了作者首次进行druid1.2.8源码阅读的过程,包括在本地启动MySQL,进行JDBC测试,以及对druid源码结构的初步了解。在JDBC测试中,详细阐述了加载驱动、创建连接、执行SQL的步骤,并展示了简单的插入和查询操作。此外,简要介绍了druid的源码结构,指出pool文件夹为核心,其他如util、wall等文件夹的功能。

druid1.2.8源码阅读:第一天

一、背景

2022年5月7日,看到秦老师在群里发消息说要组织源码活动。我之前没有源码阅读的经历,为了让自己也具备源码阅读的经验,积极的参与的这次活动。

二、在本地启动MySQL,并简单测试JDBC

2.1 在本地启动MySQL

我使用的是macOS系统,本地启动MySQL的命令如下:

/usr/local/mysql
$ ./support-files/mysql.server stop
$ ./support-files/mysql.server start
$ ./support-files/mysql.server restart

创建测试库和用户:

$ mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database druid_test_db;
Query OK, 1 row affected (0.01 sec)

mysql> create user 'druid_test' identified with mysql_native_password by 'druid_test';
Query OK, 0 rows affected (0.01 sec)

mysql> grant all privileges on druid_test_db.* to druid_test;
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

测试druid_test用户:

$ mysql -udruid_test -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| druid_test_db      |
| information_schema |
+--------------------+
2 rows in set (0.03 sec)

create table druid_test_db.t_product_item
(
  pi_id  bigint(20) primary key AUTO_INCREMENT,
  product_name  varchar(128) not null COMMENT '产品名称',
  product_version  varchar(128) not null COMMENT '产品版本'
)engine=InnoDB DEFAULT CHARSET=utf8mb4;

2.2 JDK11 之后没有jre文件夹,手动生成jre文件夹

$ sudo bin/jlink --module-path jmods --add-modules java.desktop --output jre

2.3 简单测试JDBC

JDBC的步骤如下:

  • 第一步:加载JDBC驱动

    Class.forName("com.mysql.cj.jdbc.Driver");
    
  • 第二步:创建数据库连接

    Connection con = DriverManager.getConnection(MyDBConf.URL, MyDBConf.USERNAME, MyDBConf.PASSWORD);
    
  • 第三步:获取Statement, 用于执行SQL语句

    PreparedStatement stat = con.prepareStatement("insert into druid_test_db.t_product_item(product_name, product_version) values (?, ?)");
    
  • 第四步:如果有返回值,从ResultSet取出返回值

    ResultSet resultSet = statement.executeQuery();
    

简单JDBC的代码测试

测试插入数据:

    @Override
    public void insertProductItem(ProductItem productItem) {
        Connection con=null;
        PreparedStatement stat=null;
        try {
            // 第一步:加载数据库驱动
            Class.forName(MyDBConf.DRIVER);
            // 第二步:创建数据连接
            con = DriverManager.getConnection(MyDBConf.URL, MyDBConf.USERNAME, MyDBConf.PASSWORD);
            stat = con.prepareStatement("insert into druid_test_db.t_product_item(product_name, product_version) values (?, ?)");
            stat.setString(1, productItem.getProductName());
            stat.setString(2, productItem.getProductVersion());
            stat.executeUpdate();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            if (stat!=null) {
                try {
                    stat.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }finally {
                    stat=null;
                }
            }
            if (con!=null) {
                try {
                    con.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }finally {
                    con=null;
                }
            }
        }
    }

测试查询数据:

    @Override
    public List<ProductItem> findProductItemList() {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            List<ProductItem> result = new ArrayList<>();
            Class.forName(MyDBConf.DRIVER);
            connection = DriverManager.getConnection(MyDBConf.URL, MyDBConf.USERNAME, MyDBConf.PASSWORD);
            statement = connection.prepareStatement("select pi_id,product_name,product_version from druid_test_db.t_product_item",
                    new String[]{"pi_id", "product_name", "product_version"});
            resultSet = statement.executeQuery();
            while (resultSet.next()) {
                long piId = resultSet.getLong("pi_id");
                String productName = resultSet.getString("product_name");
                String productVersion = resultSet.getString("product_version");
                result.add(new ProductItem.Builder()
                        .piId(piId)
                        .productName(productName)
                        .productVersion(productVersion)
                        .builder());
            }
            return result;
        }catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            if (statement!=null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }finally {
                    statement=null;
                }
            }
            if (resultSet!=null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }finally {
                    resultSet=null;
                }
            }
            if (connection!=null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }finally {
                    connection=null;
                }
            }
        }
    }

三、druid1.2.8 的源码结构

druid 1.2.8 源码结构:

druid/src/main/java/com/alibaba/druid/
├── Constants.java
├── DbType.java
├── DruidRuntimeException.java
├── FastsqlColumnAmbiguousException.java
├── FastsqlException.java
├── TransactionTimeoutException.java
├── VERSION.java
├── filter
├── mock
├── pool
├── proxy
├── sql
├── stat
├── support
├── util
└── wall
  • pool文件夹最核心,入口是DruidDataSource
  • util 文件夹,通用工具。不重要,知道是什么功能即可;
  • wall 防火墙相关。不重要,不需要看;
  • sql 文件夹,代码复杂,如果研究过SQL解析,可以认真看看;
  • proxy 和 support 文件夹,有兴趣了可以看一下;
  • filter 增加自定义的扩展能力。基于监控的filter,真正的实现在stat文件夹;
  • 如果平时使用 druid-spring-boot-starter, 可以稍带看看。建议通过test看;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值