Java-连接池及DBUtils

目录

一、什么是数据库连池

二、为什么要使用数据库连接池

三、市面上的数据库连接池技术

四、如何使用Druid连接池


一、什么是数据库连池

连接对象的缓冲区。负责申请,分配管理,释放连接的操作。

二、为什么要使用数据库连接池

不使用数据库连接池,每次都通过DriverManager获取新连接,用完直接抛弃断开,连接的利用率太低,太浪费。 对于数据库服务器来说,压力太大了。我们数据库服务器和Java程序对连接数也无法控制,很容易导致数据库服务器崩溃。

我们就希望能管理连接。 我们可以建立一个连接池,这个池中可以容纳一定数量的连接对象,一开始,我们可以先替用户先创建好一些连接对象, 等用户要拿连接对象时,就直接从池中拿,不用新建了,这样也可以节省时间。然后用户用完后,放回去,别人可以接着用。 可以提高连接的使用率。当池中的现有的连接都用完了,那么连接池可以向服务器申请新的连接放到池中。 直到池中的连接达到“最大连接数”,就不能在申请新的连接了,如果没有拿到连接的用户只能等待。

三、市面上的数据库连接池技术

JDBC 的数据库连接池使用 javax.sql.DataSource 来表示,DataSource 只是一个接口(通常被称为数据源),该接口通常由服务器(Weblogic, WebSphere, Tomcat)提供实现,也有一些开源组织提供实现:

  • DBCP 是Apache提供的数据库连接池,速度相对c3p0较快,但因自身存在BUG,Hibernate3已不再提供支持

  • C3P0 是一个开源组织提供的一个数据库连接池,速度相对较慢,稳定性还可以

  • Proxool 是sourceforge下的一个开源项目数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点

  • BoneCP 是一个开源组织提供的数据库连接池,速度快,优于DBCP和C3P0,但是已被HikariCP取代。

  • Druid(德鲁伊)是阿里提供的数据库连接池,据说是集DBCP 、C3P0 、Proxool 优点于一身的数据库连接池

四、如何使用Druid连接池

  1. 引入德鲁伊连接池jar包

    例如:引入druid-1.1.10.jar,像引入JDBC驱动jar包一样操作。注意:JDBC驱动jar包也是必须要引入的

  2. 代码步骤:

    • 第一步:建立一个数据库连接池对象

    • 第二步:设置连接池的参数

    • 第三步:从连接池中获取连接对象来使用

  3. 代码示例:

public class TestPool {
	public static void main(String[] args) throws SQLException {
		//1、创建数据源(数据库连接池)对象
		DruidDataSource ds =new DruidDataSource();
		
		//2、设置参数
		//(1)设置基本参数
		ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
		ds.setUrl("jdbc:mysql://localhost:3306/test");
		ds.setUsername("root");
		ds.setPassword("1234");
		
		//(2)设置连接数等参数
		ds.setInitialSize(5);//一开始提前申请好5个连接,不够了,重写申请
		ds.setMaxActive(10);//最多不超过10个,如果10都用完了,还没还回来,就会出现等待
		ds.setMaxWait(1000);//用户最多等1000毫秒,如果1000毫秒还没有人还回来,就异常了
		
		//3、获取连接
		for (int i = 1; i <=15; i++) {
			Connection conn = ds.getConnection();
			System.out.println("第"+i+"个:" + conn);
			
			//如果这里没有关闭,就相当于没有还
//			conn.close();#这里关闭,是还回池中
		}
	}
}

 4.德鲁伊连接池参数说明

配置 缺省 说明
name 配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。 如果没有配置,将会生成一个名字,格式是:”DataSource-” + System.identityHashCode(this)
url 连接数据库的url,不同数据库不一样。例如: mysql: jdbc:mysql://10.20.153.104:3306/druid2 oracle:jdbc:oracle:thin:@10.20.149.85:1521:ocnauto
username 连接数据库的用户名
password 连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。详细看这里:使用ConfigFilter · alibaba/druid Wiki · GitHub
driverClassName 根据url自动识别 这一项可配可不配,如果不配置druid会根据url自动识别jdbType,然后选择相应的driverClassName(建议配置下)
initialSize 0 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
maxActive 8 最大连接池数量
maxIdle 8 已经不再使用,配置了也没效果
minIdle 0 最小连接池数量
maxWait -1 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
poolPreparedStatements false 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
maxOpenPreparedStatements -1 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
validationQuery 用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
testOnBorrow true 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturn false 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testWhileIdle false 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
timeBetweenEvictionRunsMillis 有两个含义: 1)Destroy线程会检测连接的间隔时间2)testWhileIdle的判断依据,详细看testWhileIdle属性的说明
numTestsPerEvictionRun 不再使用,一个DruidDataSource只支持一个EvictionRun
minEvictableIdleTimeMillis 配置一个连接在池中最小生存的时间,单位是毫秒
connectionInitSqls 物理连接初始化的时候执行的sql
exceptionSorter 根据dbType自动识别 当数据库抛出一些不可恢复的异常时,抛弃连接
filters 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall
proxyFilters 类型是List,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系

DBUtils​​​​​​​

commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。

其中QueryRunner类封装了SQL的执行,是线程安全的。

(1)可以实现增、删、改、查、批处理、

(2)考虑了事务处理需要共用Connection。

(3)该类最主要的就是简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。

(4)如果从连接池中获取的连接,不需要手动关闭连接,runner会自动关闭连接,释放到连接池中

构造器:

空参构造器,执行操作时,需要传入参数Connection对象。使用完毕需要手动释放资源。

public QueryRunner() {}

有参构造器,传入一个数据源,执行操作时,从数据源中获取连接,使用完毕自动释放资源。

public QueryRunner(DataSource ds) {}

增删改查操作:

(1)更新

public int update(Connection conn, String sql, Object... params) throws SQLException:用来执行一个更新(插入、更新或删除)操作。

......

(2)插入

public <T> T insert(Connection conn,String sql,ResultSetHandler<T> rsh, Object... params) throws SQLException:只支持INSERT语句,其中 rsh - The handler used to create the result object from the ResultSet of auto-generated keys. 返回值: An object generated by the handler.即自动生成的键值

....

(3)批处理

public int[] batch(Connection conn,String sql,Object params)throws SQLException: INSERT, UPDATE, or DELETE语句

public <T> T insertBatch(Connection conn,String sql,ResultSetHandler<T> rsh,Object params)throws SQLException:只支持INSERT语句

.....

(4)使用QueryRunner类实现查询

public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException {
}

执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。

public Object query(Connection conn, String sql, ResultSetHandler rsh,Object... params) throws SQLException

执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。

...

ResultSetHandler接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql.ResultSet rs)该方法的返回值将作为QueryRunner类的query()方法的返回值。

该接口有如下实现类可以使用:

  • BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。

  • BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。

  • ScalarHandler:查询单个值对象

  • MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。

  • MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List

  • ColumnListHandler:将结果集中某一列的数据存放到List中。

  • KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。

  • ArrayHandler:把结果集中的第一行数据转成对象数组。

  • ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。

猜你喜欢

转载自blog.csdn.net/rbx508780/article/details/127288319