Druid连接池实现自定义场景的多数据库的连接

Druid连接池实现自定义场景的多数据库的连接

前言

最近在做一个报表的集成maven插件,里面的一个环节需要对多数据源进行维护,基础版直接使用最传统的方式【获取连接=》查询数据=》释放连接】但是这种方式每次的开销实在是太耗时间了,那这时候有两个方案一个是自己去手写一个数据库的连接池,还一个方案就是使用druid来做多数据源的连接池,这道题目还需要选择吗,别人都造好了16缸使用稳定版的发动机给你了,你还自己去造发动机吗,当然是直接使用druid来实现我们的多数据源的连接了。【自己手写下数据库连接池是没什么问题的,知道里面的原理就好了,就不用去重复造发动机了】

DruidDataSource数据源实体

package com.lazyboyl.dynamic.report.core.entity;

import java.util.Date;

/**
 * 类描述:数据源的实体类
 *
 * @author linzef
 * @since 2020-04-28
 */
public class DruidDataSource {

    /**
     * 数据源流水ID
     */
    private String druidDataSource Id;

    /**
     * 数据源名称
     */
    private String dataSourceName;

    /**
     * 驱动名称
     */
    private String driverClassName;

    /**
     * 账号
     */
    private String userName;

    /**
     * 密码
     */
    private String userPassword;

    /**
     * 数据库地址
     */
    private String url;

    /**
     * 1:正常;2:连接失败
     */
    private String state;

    /**
     * 创建时间
     */
    private Date crtDate;

    /**
     * 获取数据源流水ID
     *
     * @return reportDataSourceId - 数据源流水ID
     */
    public String getDruidDataSourceId () {
        return druidDataSource Id;
    }

    /**
     * 设置数据源流水ID
     *
     * @param reportDataSourceId 数据源流水ID
     */
    public void setDruidDataSourceId(String druidDataSource ) {
        this.druidDataSource = druidDataSource ;
    }

    /**
     * 获取数据源名称
     *
     * @return dataSourceName - 数据源名称
     */
    public String getDataSourceName() {
        return dataSourceName;
    }

    /**
     * 设置数据源名称
     *
     * @param dataSourceName 数据源名称
     */
    public void setDataSourceName(String dataSourceName) {
        this.dataSourceName = dataSourceName;
    }

    /**
     * 获取驱动名称
     *
     * @return driverClassName - 驱动名称
     */
    public String getDriverClassName() {
        return driverClassName;
    }

    /**
     * 设置驱动名称
     *
     * @param driverClassName 驱动名称
     */
    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    /**
     * 获取账号
     *
     * @return userName - 账号
     */
    public String getUserName() {
        return userName;
    }

    /**
     * 设置账号
     *
     * @param userName 账号
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }

    /**
     * 获取密码
     *
     * @return userPassword - 密码
     */
    public String getUserPassword() {
        return userPassword;
    }

    /**
     * 设置密码
     *
     * @param userPassword 密码
     */
    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    /**
     * 获取数据库地址
     *
     * @return url - 数据库地址
     */
    public String getUrl() {
        return url;
    }

    /**
     * 设置数据库地址
     *
     * @param url 数据库地址
     */
    public void setUrl(String url) {
        this.url = url;
    }

    /**
     * 获取1:正常;2:连接失败
     *
     * @return state - 1:正常;2:连接失败
     */
    public String getState() {
        return state;
    }

    /**
     * 设置1:正常;2:连接失败
     *
     * @param state 1:正常;2:连接失败
     */
    public void setState(String state) {
        this.state = state;
    }

    /**
     * 获取创建时间
     *
     * @return crtDate - 创建时间
     */
    public Date getCrtDate() {
        return crtDate;
    }

    /**
     * 设置创建时间
     *
     * @param crtDate 创建时间
     */
    public void setCrtDate(Date crtDate) {
        this.crtDate = crtDate;
    }
}

DruidUtil工具类编写

首先我们创建一个DruidUtil工具类,里面首先初始化一个Map用于存放我们不同的数据源。

     /**
     * 多数据源的Map的存储对象
     */
    public static Map<String, DruidDataSource> map = new HashMap<>();

接着我们编写实现数据库初始化的方法

/**
     * 功能描述: 初始化数据库连接池
     *
     * @param reportDataSource 待初始化的数据库信息
     */
    public static void initDataSource(DruidDataSource  druidDataSource) {
        Properties prop = new Properties();
        prop.setProperty("driver", druidDataSource.getDriverClassName());
        prop.setProperty("url", druidDataSource.getUrl());
        prop.setProperty("connectionProperties", "useUnicode=true;characterEncoding=UTF8");
        prop.setProperty("username", druidDataSource.getUserName());
        prop.setProperty("password", druidDataSource.getUserPassword());
        // 设置数据连接池初始化连接池数量
        prop.setProperty("initialSize", "3");
        // 最大连接数
        prop.setProperty("maxActive", "20");
        prop.setProperty("minIdle", "3");
        // 连接最大等待时间60秒
        prop.setProperty("maxWait", "60000");
        prop.setProperty("filters", "stat");
        prop.setProperty("timeBetweenEvictionRunsMillis", "35000");
        prop.setProperty("minEvictableIdleTimeMillis", "30000");
        prop.setProperty("testWhileIdle", "true");
        prop.setProperty("testOnBorrow", "false");
        prop.setProperty("testOnReturn", "false");
        prop.setProperty("poolPreparedStatements", "false");
        prop.setProperty("maxPoolPreparedStatementPerConnectionSize", "200");
        prop.setProperty("removeAbandoned", "true");
        try {
            DruidDataSource druidDataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(prop);
            map.put(druidDataSource.getDruidDataSourceId(), druidDataSource);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("初始化创建连接池失败!");
        }
    }

最后编写获取我们的数据库连接对象的方法

/**
     * 功能描述: 获取数据库的连接
     *
     * @param id 数据源流水ID
     * @return 获取数据库连接
     * @throws SQLException
     */
    public static DruidPooledConnection getConnection(String id) throws SQLException {
        DruidDataSource source = map.get(id);
        System.out.println("当前数据库连接池的量为:" + source.getActiveCount() + "---" + source.getActivePeak());
        return (DruidPooledConnection) source.getPooledConnection();
    }

验证我们的多数据源连接

我们直接在我们的DruidUtil中编写一个main方法然后我们启动20个线程来模拟数据库的访问。

public static void main(String[] args) throws SQLException {
        List<ReportDataSource> reportDataSourceList = new ArrayList<>();
        ReportDataSource report = new ReportDataSource();
        report.setUserName("数据库1账号");
        report.setUserPassword("数据库1密码");
        report.setUrl("jdbc:mysql://xx:3306/xx?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai");
        report.setDriverClassName("com.mysql.jdbc.Driver");
        report.setReportDataSourceId("2");
        reportDataSourceList.add(report);
        report = new ReportDataSource();
        report.setUserName("数据库2账号");
        report.setUserPassword("数据库2密码");
        report.setUrl("jdbc:mysql://xxx:3306/xx?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai");
        report.setDriverClassName("com.mysql.jdbc.Driver");
        report.setReportDataSourceId("1");
        reportDataSourceList.add(report);
        // 初始化多个数据源
        for (ReportDataSource reportDataSource : reportDataSourceList) {
            initDataSource(reportDataSource);
        }
        // 启动十个线程模拟访问数据库
        for(int k=0;k<10;k++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 1000; j++) {
                        try {
                            DruidPooledConnection conn = getConnection("1");
                            PreparedStatement ps = conn.prepareStatement("select * from xxx");
                            ResultSet rs = ps.executeQuery();
                            ResultSetMetaData resultSetMetaData = rs.getMetaData();
//                            while (rs.next()) {
//                                for (int i = 0; i < resultSetMetaData.getColumnCount(); i++) {
//                                    System.out.println("==>" + rs.getString(resultSetMetaData.getColumnLabel(i + 1)));
//                                }
//                            }
                            rs.close();
                            ps.close();
                            conn.close();
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
    }

这时候我们可以启动我们的main方法,大家会看到我们的控制台会打印如下的信息:
在这里插入图片描述
到此处我们就完成了我们的多数据源的druid的实现,我们就可以拿着我们的connection去做任何我们想做的事情了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨_鸟_不_会_飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值