NutzDao数据库连接池

 2022-07-30    0 条评论    12063 浏览

框架

如何创建 DataSource

何为DataSource(描述来自nutz官网)

先看看JDK中对DataSource的描述:

  • 作为 DriverManager 工具的替代项,DataSource 对象是获取连接的首选方法。
  • 基本实现 - 生成标准的 Connection 对象
  • 连接池实现 - 生成自动参与连接池的 Connection 对象。此实现与中间层连接池管理器一起使用。
  • 简单来说,就是获取数据库连接的一个通用接口, 常见的dbcp,c3p0,druid都是DataSource的实现.

NutDao也选用DataSource作为获取数据库连接的方式, 且只调用其无参数的getConnection()方法, 也是大部分数据库连接池唯一支持的方法.

提醒一下, DataSource只是接口,不等于连接池

NutDao不挑剔任何连接池/DataSource实现,只要实现了DataSource接口就行,不存在是否支持"XXXX连接池"的问题

SimpleDataSource

NutDao本身内置了简单的连接池SimpleDataSource,但是实际生产推荐使用。

NutDao是线程安全的,不能重复实例化。

直接创建实例方式


public class DaoUtil {
    private static Dao dao;

    public static Dao getDao(){
        return dao;
    }

    public static void init(BootConfig config) {
        // 创建一个数据源
        SimpleDataSource dataSource = new SimpleDataSource();
        dataSource.setJdbcUrl(config.getDbUrl());
        dataSource.setUsername(config.getUserName());
        dataSource.setPassword(config.getPassWord());
        // 创建一个NutDao实例,在真实项目中, NutDao通常由ioc托管, 使用注入的方式获得.
        dao = new NutDao(dataSource);
    }
}

ioc配置文件方式

配置文件

var ioc = {
    dao : {
        type : "org.nutz.dao.impl.NutDao",
        args : [{refer:"dataSource"}]
    },
    dataSource : {
        type : "org.nutz.dao.impl.SimpleDataSource",
        fields : {
            jdbcUrl : 'jdbc:mysql://xxxx:3306/xx?useUnicode=true&characterEncoding=utf8',
            username : 'root',
            password : 'xxxx'
        }
    }
}

获取

NutIoc ioc = new NutIoc(new JsonLoader("db/db_druid_source.js"));
DataSource ds = ioc.get(DataSource.class);
//如果已经定义了dao,那么改成dao = ioc.get(Dao.class);
Dao dao = new NutDao(ds);

DaoUp

推荐使用DaoUp,DaoUp内置了是否重复实例化校验,也加入了自动读取配置文件功能。

private static Dao dao;

static {
    try {
        //DaoUp,内置单例链接工具
        DaoUp.me().init("db/nutzdb.properties");
        dao = DaoUp.me().dao();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static Dao getDao() {
    return dao;
}

Druid(推荐)

国产精品连接池,淘宝温少诚意出品,带强大的监控功能哦, 推荐1.0.25+ druid : 通过 Nutz.Ioc 的 JSON 配置文件

ioc配置文件

var ioc = {
    dao : {
        type : "org.nutz.dao.impl.NutDao",
        args : [{refer:"dataSource"}]
    },
    dataSource : {
        type : "com.alibaba.druid.pool.DruidDataSource",
        events : {
            depose : 'close'
        },
        fields : {
            url : 'jdbc:mysql://xxxx:3306/xxxx?useUnicode=true&characterEncoding=utf8',
            username : 'root',
            password : 'xxxx'
            maxWait: 15000, // 若不配置此项,如果数据库未启动,druid会一直等可用连接,卡住启动过程
            defaultAutoCommit : false // 提高fastInsert的性能
        }
    }
}

获取实例

NutIoc ioc = new NutIoc(new JsonLoader("db/db_druid_source.js"));
DataSource ds = ioc.get(DataSource.class);
//如果已经定义了dao,那么改成dao = ioc.get(Dao.class);
Dao dao = new NutDao(ds);

链接超时警告问题

使用数据库连接池以后,时不时就会出现连接超时警告 异常信息如下 druid.pool.DruidAbstractDataSource : discard long time none received connection.

这个是什么原因呢?

上网搜索了一些,Druid 1.2.2版本以后,增加了超时设置,一个链接超过60s未使用,就会断开。再次使用就会打印这个警告,且因重新连接而卡顿,但是不影响正常使用。个人感觉相当于链接失效再次获取链接。

解决方式

将版本降低到1.2.2版本以前

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid-spring-boot-starter</artifactId>
	<version>1.2.2</version>
</dependency>

或者

通过全局静态配置,将druid.mysql.usePingMethod设置为false。

System.setProperty("druid.mysql.usePingMethod","false");