83_Java_JDBC4_druid_commons-dbutils

举报
alexsully 发表于 2021/07/06 18:19:21 2021/07/06
【摘要】 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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。