83_Java_JDBC4_druid_commons-dbutils
【摘要】 dbutils queryrunner
druid
数据库连接池
普通JDBC数据库连接使用 DriverManager 来获取, 缺点:
1 每次向数据库建立连接的时候都要将 Connection 加载到内存中, 数据库的连接资源并没有得到很 好的重复利用
2 对于每一次数据库连接,使用完后都得断开
3 不能控制被创建的连接对象数,如连接过多,也可能导致内 存泄漏,服务器崩溃
数据库连接池(DataSource来获取Connection) 为数据库连接建立一个“缓冲池” - 优点:
1. 资源重用避免了频繁创建,释放连接引起的大量性能开销
2. 初始化过程中,已经创建了若干数据库连接置于连接池中。对于业务请求处理而言,直接利用现有可用连接,避免了开销,减少了系统的响应时间
3. 对于多应用共享同一数据库, 可在应用层通过数据库连接池的配置,实现某一应用大可用数据库 连接数的限制,避免某一应用独占所有的数据库资源
4. 统一的连接管理,避免数据库连接泄漏,可根据预先的占用超时设定,强制回收被占用连接
Druid(德鲁伊)数据库连接池 加入了日志监控,可以很好的监控DB池连接和SQL的执行情况
配置 |
缺省 | 说明 |
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。详细看这里:https://github.com/alibaba/druid/wiki/%E4%BD%BF%E7%94%A8ConfigFilter | |
driverClassName | 根据url自动识别 这一项可配可不配,如果不配置druid会根据url自动 识别dbType,然后选择相应的driverClassName(建议配置下) |
|
initialSize | 0 | 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者 第一次getConnection时 |
maxActive | 8 | 大连接池数量 |
maxIdle | 8 | 已经不再使用,配置了也没效果 |
minIdle | 小连接池数量 |
|
maxWait | 获取连接时大等待时间,单位毫秒。配置了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,是组合关系,并非 替换关系 |
public class DruidReview {
@Test
public void test1() throws SQLException {
DruidDataSource source = new DruidDataSource();
source.setUrl("jdbc:mysql:///test");
source.setUsername("root");
source.setPassword("xxxx");
source.setDriverClassName("com.mysql.jdbc.Driver");
DruidPooledConnection connection = source.getConnection();
System.out.println(connection);
}
@Test
public void test2() throws Exception {
Properties pros = new Properties();
InputStream is = ClassLoader.getSystemResourceAsStream("druid.properties");
pros.load(is);
DataSource source = DruidDataSourceFactory.createDataSource(pros);
Connection connection = source.getConnection();
System.out.println(connection);
}
}
url=jdbc:mysql:///test?useSSL=false
username=root
password=xxx
driverClassName=com.mysql.jdbc.Driver
initialSize=10
maxActive=10
Apache-DBUtils_开源 JDBC工具类库,它是对JDBC的简单封装
ResultSetHandler: 此接口用于处理数据库查询操作得到的结果集,不同的结果集的情形,有不同子类来实现‘
QueryRunner: 提供数据库操作的一系列重载的update() 和 query()
public class DruidReview {
@Test
public void test1() throws SQLException {
DruidDataSource source = new DruidDataSource();
source.setUrl("jdbc:mysql:///test");
source.setUsername("root");
source.setPassword("szc.2020");
source.setDriverClassName("com.mysql.jdbc.Driver");
DruidPooledConnection connection = source.getConnection();
System.out.println(connection);
}
@Test
public void test2() throws Exception {
Properties pros = new Properties();
InputStream is = ClassLoader.getSystemResourceAsStream("druid.properties");
pros.load(is);
DataSource source = DruidDataSourceFactory.createDataSource(pros);
Connection connection = source.getConnection();
System.out.println(connection);
}
//测试插入
@Test
public void test3() throws SQLException {
Connection conn = JDBCUtils.getDruidConn();
QueryRunner runner = new QueryRunner();
String sql = "insert into customers(name,email,birth)values(?,?,?)" ;
int number = runner.update(conn, sql, "蔡坤","caikun@126.com","1997-09-08");
JDBCUtils.closeResource(conn,null);
}
//测试查询 BeanHander:是ResultSetHandler接口的实现类,用于封装表中的一条记录
@Test
public void testBeanHander() throws SQLException {
Connection conn = JDBCUtils.getDruidConn();
QueryRunner runner = new QueryRunner();
String sql = "select id,name,email,birth from customers where id = ?";
//Interface ResultSetHandler<T> 传入实现类 BeanHandler
BeanHandler<Customer> handler = new BeanHandler<>(Customer.class); // 接收单一记录
Customer customer = runner.query(conn, sql, handler, 10);
System.out.println(customer);
JDBCUtils.closeResource(conn, null);
}
//BeanListHandler:是ResultSetHandler接口的实现类,用于封装表中的多条记录构成的集合
@Test
public void testBeanListHandler() throws SQLException {
Connection conn = JDBCUtils.getDruidConn();
QueryRunner runner = new QueryRunner();
String sql = "select id,name,email,birth from customers where id < ?";
//Interface ResultSetHandler<T> 传入实现类 BeanListHandler
BeanListHandler<Customer> blh = new BeanListHandler<>(Customer.class); // 多条记录
List<Customer> result = runner.query(conn, sql, blh, 5);
System.out.println(result);
JDBCUtils.closeResource(conn, null);
}
// MapHander:是ResultSetHandler接口的实现类,对应表中的一条记录。
//将字段及相应字段的值作为map中的key和value
@Test
public void testMapHander() throws SQLException {
Connection conn = JDBCUtils.getDruidConn();
QueryRunner runner = new QueryRunner();
String sql = "select id,name,email,birth from customers where id = ?" ;
MapHandler mapHandler = new MapHandler();
Map<String, Object> result = runner.query(conn, sql, mapHandler, 1);
// System.out.println(result); //{id=1, name=汪峰, email=wf@126.com, birth=2010-02-02}
Set<String> keySet = result.keySet();
// 遍历 map
Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext()){
String key = iterator.next();
Object value = result.get(key);
System.out.println(key + " ---" + value);
}
JDBCUtils.closeResource(conn,null);
}
//MapListHander:是ResultSetHandler接口的实现类,对应表中的多条记录。
//将字段及相应字段的值作为map中的key和value。将这些map添加到List中
@Test
public void testMapListHander() throws SQLException {
Connection conn = JDBCUtils.getDruidConn();
QueryRunner runner = new QueryRunner();
String sql = "select id,name,email,birth from customers where id > ?" ;
MapListHandler mapListHandler = new MapListHandler();
List<Map<String, Object>> result = runner.query(conn, sql, mapListHandler, 13);
//System.out.println(result.size()); // List 长度
for (int i = 0; i < result.size(); i++) {
Map<String, Object> map1 = result.get(i); //get(index) 返回list 索引位置内容
Set<String> keySet = map1.keySet();
Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext()){
String key = iterator.next();
Object value = map1.get(key);
System.out.println(key + "-->" + value);
}
System.out.println( );
}
}
//ScalarHandler:用于查询特殊值
@Test
public void testScalarHandler() throws SQLException {
Connection conn = JDBCUtils.getDruidConn();
QueryRunner runner = new QueryRunner();
String sql = "select count(*) from customers";
String sql_date = "select max(birth) from customers";
ScalarHandler<Object> objectScalarHandler = new ScalarHandler<>();
Long count = (Long) runner.query(conn, sql, objectScalarHandler);
Date date = (Date) runner.query(conn, sql_date, objectScalarHandler);
System.out.println(count);
System.out.println(date);
}
/*
* 自定义ResultSetHandler的实现类
*/
@Test
public void testQuery7(){
Connection conn = null;
try {
QueryRunner runner = new QueryRunner();
conn = JDBCUtils.getDruidConn();
String sql = "select id,name,email,birth from customers where id = ?";
ResultSetHandler<Customer> handler = new ResultSetHandler<Customer>(){
@Override
public Customer handle(ResultSet rs) throws SQLException {
if(rs.next()){ // 类似 set 迭代器,hasnext(); next(), 返回布尔值/指针下移
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
Date birth = rs.getDate("birth");
Customer customer = new Customer(id, name, email, birth);
return customer;
}
return null;
}
};
Customer customer = runner.query(conn, sql, handler,23);
System.out.println(customer);
} catch (SQLException e) {
e.printStackTrace();
}finally{
JDBCUtils.closeResource(conn, null);
}
}
//使用dbutils.jar中提供的DbUtils工具类,实现资源的关闭
public static void closeResource1(Connection conn, Statement ps, ResultSet rs){
// DbUtils.close 不处理异常
try {
DbUtils.close(conn);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
// closeQuietlyquietly 处理异常
DbUtils.closeQuietly(conn);
DbUtils.closeQuietly(ps);
DbUtils.closeQuietly(rs);
}
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)