数据库连接池-JdbcUtils工具类/JDBCTemplate

一、概述


数据库连接是一种关键的、有限的、昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。能明显提高对数据库操作的性能。

image
运作原理

连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用(参考共享模式)。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等.

连接池配置
  • maxActive: 连接池支持的最大连接数,一般可以参考并发量来设定
  • maxIdle: 连接池中最多可空闲maxIdle个连接 ,表示即使没有数据库连接时依然可以保持空闲的连接,不被释放
  • minIdle: 连接池中最小空闲连接数,连接数低于时,连接池会自动创建连接数量
  • initialSize: 初始化连接数目
  • maxWait: 连接池中连接用完时,新的请求等待时间-毫秒
  • removeAbandoned: 是否清除已经超过“removeAbandonedTimout”设置的无效连接。如果值为“true”则超过“removeAbandonedTimout”设置的无效连接将会被清除。设置此属性可以从那些没有合适关闭连接的程序中恢复数据库的连接。
  • removeAbandonedTimeout: 活动连接的最大空闲时间,单位为秒 超过此时间的连接会被释放到连接池中,针对未被close的活动连接
  • minEvictableIdleTimeMillis: 连接池中连接可空闲的时间,单位为毫秒 针对连接池中的连接对象
  • timeBetweenEvictionRunsMillis / minEvictableIdleTimeMillis: 每timeBetweenEvictionRunsMillis毫秒秒检查一次连接池中空闲的连接,把空闲时间超过minEvictableIdleTimeMillis毫秒的连接断开,直到连接池中的连接数到minIdle为止.
运行步骤:
  • 建立数据库连接池对象(初始化)
  • 按照事先指定的参数创建初始数量的数据库连接(空闲连接数)
  • 对于一个数据库访问请求,直接从连接池中得到一个连接。如果 数据库连接池 对象中没有空闲的连接,且连接数没有达到最大(最大活跃连接数),创建一个新的数据库连接。
  • 存取操作数据库。
  • 关闭数据库,释放所有数据库连接(此时的关闭数据库连接,并非真正关闭,而是将其放入空闲队列中。如实际空闲连接数大于初始空闲连接数则释放连接)。
  • 释放数据库连接池对象(服务器停止、维护期间,释放数据库连接池对象,并释放所有连接)。

Java连接池

  • C3P0:是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象
  • Druid:Druid不仅是一个数据库连接池,还包含一个ProxyDriver、一系列内置的JDBC组件库、一个SQL Parser。支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等

Druid针对Oracle和MySql做了特别优化,比如:Oracle的PS Cache内存占用优化/ MySql的ping检测优化
Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便,通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter,就是通过Druid的SQL Parser分析语义实现的

Druid连接池实现

1.首先在 pom.xml 文件中新增 com.alibaba:druid 和 mysql:mysql-connector-java 依赖

   
        
        
            com.alibaba
            druid
            1.1.22
        

        
            mysql
            mysql-connector-java
            5.1.46
        
    

2.配置数据库连接 db.properties

# JDBC
driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mysql?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
username=root
password=123456

# JDBC Pool
#连接池建立时创建的初始化连接数
initialSize=4
#连接池中最小空闲连接数
minIdle=2
#连接池中最大的活跃连接数
maxActive=20
#连接池超时等待时间毫秒
maxWait=5000

3.简单演示Druid是如何实现连接池管理的

    /**
     *  main 调试打印Druid配置连接管理
     * @param args
     * @throws SQLException
     */
    public static void main(String[] args) throws SQLException {
        Properties properties = new Properties();
        InputStream inputStream = DruidDemo.class.getClassLoader().getResourceAsStream("db.properties");
        // 加载配置文件
        properties.load(inputStream);
        // 获取数据源对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
        // 获取连接对象
        Connection connection = dataSource.getConnection();
        // 输出连接池详情
        System.out.println(dataSource);
    }

连接池详情:

"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\Testplan\IntelliJ IDEA 2020.1\lib\idea_rt.jar=53968:D:\Testplan\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\DruidConnectionPool\target\classes;C:\Users\Administrator\.m2\repository\com\alibaba\druid\1.1.22\druid-1.1.22.jar;C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;C:\Users\Administrator\.m2\repository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.0.0.RELEASE\spring-beans-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.0.0.RELEASE\spring-core-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.0.0.RELEASE\spring-jcl-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.0.0.RELEASE\spring-context-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.0.0.RELEASE\spring-aop-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.0.0.RELEASE\spring-expression-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jdbc\5.0.0.RELEASE\spring-jdbc-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-tx\5.0.0.RELEASE\spring-tx-5.0.0.RELEASE.jar" com.comet.druid.utils.JdbcUtils

八月 18, 2020 9:46:45 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
信息: {dataSource-1} inited
{
    CreateTime:"2020-08-18 21:46:45",
    ActiveCount:1,
    PoolingCount:3,
    CreateCount:4,
    DestroyCount:0,
    CloseCount:0,
    ConnectCount:1,
    Connections:[
        {ID:401424608, ConnectTime:"2020-08-18 21:46:45", UseCount:0, LastActiveTime:"2020-08-18 21:46:45"},
        {ID:1348949648, ConnectTime:"2020-08-18 21:46:45", UseCount:0, LastActiveTime:"2020-08-18 21:46:45"},
        {ID:834133664, ConnectTime:"2020-08-18 21:46:45", UseCount:0, LastActiveTime:"2020-08-18 21:46:45"}
    ]
}

Process finished with exit code 0

4.演示使用Druid管理连接执行简单的数据库操作

package com.comet.druid;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

/**
 * Druid 演示
 *  1.导入依赖
 *  2.定义配置文件
 *  3.加载配置文件
 *  4.创建连接池对象
 *  5.获取连接对象
 *  6.执行SQL查询并返回结果
 */

public class DruidDemo {
    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();
        InputStream inputStream = DruidDemo.class.getClassLoader().getResourceAsStream("db.properties");
        // 加载配置文件
        properties.load(inputStream);
        // 获取数据源对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
        // 获取连接对象
        Connection connection = dataSource.getConnection();
        // 定义SQL
        String sql = "SELECT * FROM `world`.`city`;";
        // 获取游标传入SQL
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        // 执行SQL查询返回结果
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            // 遍历输出结果
            System.out.println(resultSet.getString(2));
        }
    }
}
"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\Testplan\IntelliJ IDEA 2020.1\lib\idea_rt.jar=49506:D:\Testplan\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\DruidConnectionPool\target\classes;C:\Users\Administrator\.m2\repository\com\alibaba\druid\1.1.22\druid-1.1.22.jar;C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar" com.comet.druid.DruidDemo
八月 16, 2020 11:00:50 上午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited
Kabul
Qandahar
Herat
Mazar-e-Sharif
Amsterdam
Rotterdam
Haag

Process finished with exit code 0

上面就是使用了Druid连接池技术管理连接及简单实现数据库的查询,但是这个执行过程的1-7步骤还是太繁琐不够简单,所以下面我们来自定义封装一个工具类,来节省我们在执行SQL的操作。


JdbcUtils 工具类

1.定义一个JdbcUtils 类,用于获取数据源对象、连接对象、释放连接的方法

package com.comet.druid.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.sql.*;
import java.util.*;


/**
 * JDBC wrapper utility classes
 */
public class JdbcUtils {
    private static DataSource dataSource;  //实现了单例

    /**
     *  使用静态方法加载配置文件,创建数据源对象
     */
    static{
        try {
            Properties properties=new Properties();
            properties.load(JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"));
            dataSource = DruidDataSourceFactory.createDataSource(properties);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *  获取数据源
     * @return
     */
    public static DataSource getDataSource() { return dataSource; }

    /**
     *  获取连接对象
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    /**
     *  释放连接
     * @param resultSet 结果集
     * @param preparedStatement  游标对象
     * @param conn 连接对象
     */
      public static void freeConnect(ResultSet resultSet, PreparedStatement preparedStatement, Connection conn) {
        try {
            if (resultSet != null) resultSet.close();
            if (preparedStatement != null) preparedStatement.close();
            if (conn != null) conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

}

2.定义一个 JdbcHelper 类用来封装一些常用的 CURD 数据库操作

package com.comet.druid.utils;


import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JdbcHelper {
    private static Connection conn;
    private static PreparedStatement preparedStatement;
    private static Statement statement;
    private static ResultSet resultSet;

    /**
    * 返回一个游标,传入SQL,一般使用 preparedStatement 
    */
    private static void getPreparedStatement(String sql) throws SQLException {
        conn = JdbcUtils.getConnection();
        preparedStatement = conn.prepareStatement(sql);
    }

    /**
     * 返回结果的第一个值,如count\min\max等等
     *
     * @param sql
     *            不带参数的sql语句
     * @return 结果集
     * @throws SQLException
     */
    public static Object getSingle(String sql) throws SQLException {
        Object result = null;
        try {
            getPreparedStatement(sql);
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) { result = resultSet.getObject(1); }
            return result;
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free();
        }

    }

    /**
     * 返回结果的第一个值,如count\min\max等等
     *
     * @param sql
     *            带参数的sql语句
     * @return 结果集
     * @throws SQLException
     */
    public static Object getSingle(String sql, Object... params) throws SQLException {
        Object result = null;
        try {
            getPreparedStatement(sql);
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(1 + i, params[i]);
            }
            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {
                result = resultSet.getObject(1);
            }
            return result;
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free();
        }
    }

    /**
     * 用于不带参数的查询,返回结果 Map集合
     *
     * @param sql
     *            sql语句
     * @return 结果集
     * @throws SQLException
     */
    public static Map queryForMap(String sql) throws SQLException {
        if (StringUtils.isBlank(sql)) { return null; }
        try {
            getPreparedStatement(sql);
            resultSet = preparedStatement.executeQuery();
            return ResultToMap(resultSet);
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free();
        }
    }

    /**
     * 用于不带参数的查询,返回结果 Map集合
     *
     * @param sql
     *            sql语句
     * @return 结果集
     * @throws SQLException
     */
    public static Map queryForMap(String sql, Object... args) throws SQLException {
        if (StringUtils.isBlank(sql)) { return null; }
        try {
            getPreparedStatement(sql);
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }
            resultSet = preparedStatement.executeQuery();
            return ResultToMap(resultSet);
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free();
        }
    }

    /**
     * 用于带参数的查询,返回结果 List> 集合
     *
     * @param sql
     *            sql语句
     *            参数集合由多个参数组成实现参数化传入SQL拼接
     * @return 结果集
     * @throws SQLException
     */
    public static List queryForList(String sql) throws SQLException {
        if (StringUtils.isBlank(sql)) { return null; }
        try {
            getPreparedStatement(sql);
            resultSet = preparedStatement.executeQuery();
            return ResultToListMap(resultSet);
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free();
        }

    }

    /**
     * 用于带参数的查询,返回结果 List> 集合
     *
     * @param sql
     *            sql语句
     * @param args
     *            参数集合由多个参数组成实现参数化传入SQL拼接
     * @return 结果集
     * @throws SQLException
     */
    public static List queryForList(String sql, Object... args) throws SQLException {
        if (StringUtils.isBlank(sql)) { return null; }
        try {
            getPreparedStatement(sql);
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }
            resultSet = preparedStatement.executeQuery();
            return ResultToListMap(resultSet);
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free();
        }
    }

    /**
     * 用于增删改、DDL/DML
     *
     * @param sql
     *            不带参数的sql语句
     * @return 影响行数
     * @throws SQLException
     */
    public static int update(String sql) throws SQLException {

        try {
            getPreparedStatement(sql);
            return preparedStatement.executeUpdate();

        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free();
        }
    }

    /**
     * 用于增删改(带参数执行)
     *
     * @param sql
     *            sql语句???占位符
     * @param params
     *            sql语句 赋值给?用于拼接SQL
     * @return 影响行数
     * @throws SQLException
     */
    public static int update(String sql, Object... params) throws SQLException {
        try {
            getPreparedStatement(sql);
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(i + 1, params[i]);
            }
            return preparedStatement.executeUpdate();
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            free();
        }
    }

    /**
     * 批量更新数据
     *
     * @param sqlList
     *            一组sql数据
     * @return
     */
    public static int[] batchUpdate(List sqlList) throws SQLException {

        int[] result = new int[] {};

        try {
            conn = JdbcUtils.getConnection();
            conn.setAutoCommit(false);
            statement = conn.createStatement();

            for (String sql : sqlList) {
                statement.addBatch(sql);
            }
            result = statement.executeBatch();
            conn.commit();

        } catch (SQLException e) {
            e.printStackTrace();
            conn.rollback();
        } finally {
            free();
        }
        return result;
    }

    /**
     *  处理查询结果数据,转换成 List> 类型数据
     * @param resultSet
     * @return List>
     * @throws SQLException
     */
    private static List> ResultToListMap(ResultSet resultSet) throws SQLException {
        List> list = new ArrayList>();
        while (resultSet.next()) {
            ResultSetMetaData md = resultSet.getMetaData();
            Map map = new HashMap<>();
            for (int i = 1; i <= md.getColumnCount(); i++) {
                map.put(md.getColumnName(i), resultSet.getObject(i));
            }
            list.add(map);
        }
        return list;
    }

    /**
     *  处理查询结果数据,转换成 Map 类型数据
     * @param resultSet
     * @return Map
     * @throws SQLException
     */
    private static Map ResultToMap(ResultSet resultSet) throws SQLException {
        Map map = new HashMap<>();
        while (resultSet.next()) {
            ResultSetMetaData md = resultSet.getMetaData();
            for (int i = 1; i <= md.getColumnCount(); i++) {
                map.put(md.getColumnName(i), resultSet.getObject(i));
            }
        }
        return map;
    }

    /**
     *  釋放對應連接
     */
    public static void free() { JdbcUtils.freeConnect(resultSet, preparedStatement, conn); }
}

3.封装的这些方法之后再来执行看一下,是否比之前要更简单方便省事,在 Main 方法里面执行一下

    public static void main(String[] args) throws SQLException {
        String sql = "SELECT * FROM `world`.`city` LIMIT 0, 5";
        List> result = JdbcHelper.query(sql);
        System.out.println(result);
    }
"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\Testplan\IntelliJ IDEA 2020.1\lib\idea_rt.jar=57749:D:\Testplan\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\DruidConnectionPool\target\classes;C:\Users\Administrator\.m2\repository\com\alibaba\druid\1.1.22\druid-1.1.22.jar;C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;C:\Users\Administrator\.m2\repository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar" com.comet.druid.utils.JdbcHelper
八月 16, 2020 12:07:02 下午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited
[{Population=1780000, ID=1, CountryCode=AFG, District=Kabol, Name=Kabul}, {Population=237500, ID=2, CountryCode=AFG, District=Qandahar, Name=Qandahar}, {Population=186800, ID=3, CountryCode=AFG, District=Herat, Name=Herat}, {Population=127800, ID=4, CountryCode=AFG, District=Balkh, Name=Mazar-e-Sharif}, {Population=731200, ID=5, CountryCode=NLD, District=Noord-Holland, Name=Amsterdam}]

Process finished with exit code 0

从上面的输出结果来看,工具类经过封装之后操作数据库的CRUD会变得非常简洁,那么这样封装的好处有哪些呢?

  • 不需要反复去申请连接
  • 不需要再去主动释放资源
  • 只关心SQL的定义和执行以及怎么处理
  • 数据的结果也不需要单独去处理都已经封装好,需要直接可以使用

以上都是自定义的一些方法,简单的来看,程序的复用性更高了,性能也变高了。那么在体会到了封装的好处之后,现在我们可以尝试在Dubbo API 自动化测试过程中使用CURD常规操作.


Dubbo API 自动化实践

1.DQL: 首先调用接口方法获取返回值 result, 然后调用 JdbcHelper.queryForList方法,通过TestNG框架的参数化传入需要执行的SQL入参,获取数据库查询结果 dbResult ,最后断言接口 result 与 数据库 dbResult 是否一致;

    @Test(dataProvider = DataConsts.DATA_PROVIDER, dataProviderClass = ExcelMapProvider.class, description = "获取所有商家信息")
    public void findAll(ParamMap paramMap) throws SQLException {
        List result = iMerchantInfoService.findAll();
        List dbResult = JdbcHelper.queryForList(paramMap.getString("SqlParams"));
        logger.info("实际输出: {}, Db->查询结果: {}", JSON.toJSONString(result.size()), Objects.requireNonNull(dbResult).size());
        Assert.assertEquals(result.size(), dbResult.size());

    }

2.DML: 调用API方法执行删除了一条数据,执行断言。测试用例执行完成后,进行数据预置操作,调用JdbcHelper.update方法,通过TestNG框架的参数化传入需要执行的SQL入参,把之前删除的一条数据重新插入表中,保证用例数据的可复用性

    @Test(dataProvider = DataConsts.DATA_PROVIDER, dataProviderClass = ExcelMapProvider.class, description = "删除商户")
    public void deleteById(ParamMap paramMap) throws SQLException {
        Boolean result = iMerchantInfoService.deleteById(Integer.valueOf(paramMap.getString("Params")));
        boolean dbResponse = JdbcHelper.getSingle(paramMap.getString("SqlParams")) == null;
        logger.info("实际输出: {}, db 查询结果: {}", result, dbResponse);
        Assert.assertTrue(result);
        Assert.assertTrue(dbResponse);
        JdbcHelper.update(paramMap.getString("After"));

    }

从以上的两个简单示例可以看出,在 Dubbo 接口自动化测试编写过程中可以使数据库操作步骤比较简洁,不用关心SQL的执行过程,只需要关注如何定义SQL,然后执行即可。在性能、效率、代码简洁上都有所提升。

以上是结合Druid 实现自定义的工具类,下面再去了解一下 JDBCTemplate 是如何封装的。


JDBCTemplate

Spring框架对JDBC的简单封装,提供了JDBCTemplate对象简化的JDBC的开发,简化持久层操作, JDBCTemplate 很灵活,但跟ORM框架相比 JDBCTemplate 功能就显得比较简单,学习 JDBCTemplate 可以先简单了解后续再学习ORM的时候就事半功倍了,当然在做单元测试的过程中已经够用了。

使用步骤:
  • 导入jar包or Maven 配置引用的依赖
  • 创建JDBCTemplate对象,依赖于数据源 DataSource-->JDBCTemplate template = new JdbcTemplate(dataSource)
  • 调用JdbcTemplate的常用方法来完成CRUD的操作:

update(): 执行DML、DQL语句
queryForMap(): 查询之后将结果封装为Map集合
queryForList(): 查询之后将结果封装为List集合
query(): 查询之后将结果封装为JavaBean对象 参数:SQL、RowMapper,一般我们使用 BeanPropertyRowMapper 实现类,可以完成数据到JavaBean的自动封装 new BeanPropertyRowMapper<对象类型>(类型.class)
queryForObject(): 查询结果,将结果封装为对象(Object),一般用于聚合函数查询

DML/DDL 操作实例

修改一行记录

package com.comet.druid;

import com.comet.druid.utils.JdbcUtils;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * Druid 演示
 *  1.导入依赖
 *  2.通过创建JdbcTemplate对象
 *      注意:传入的参数是Druid数据源,这里我们使用之前封装好的 JdbcUtils.getDataSource()
 *  3.调用 update() 方法
 */

public class DruidDemo {
    public static void main(String[] args) throws Exception {
        // 通过创建JdbcTemplate对象需要传入数据源
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JdbcUtils.getDataSource());
        // 定义一个SQL修改一个记录行
        String sql = "UPDATE `world`.`city` SET `Population` = ? WHERE `ID` = ?;";
        jdbcTemplate.update(sql,178,1);
    }
}

修改结果:

"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\Testplan\IntelliJ IDEA 2020.1\lib\idea_rt.jar=62881:D:\Testplan\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\DruidConnectionPool\target\classes;C:\Users\Administrator\.m2\repository\com\alibaba\druid\1.1.22\druid-1.1.22.jar;C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;C:\Users\Administrator\.m2\repository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.0.0.RELEASE\spring-beans-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.0.0.RELEASE\spring-core-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.0.0.RELEASE\spring-jcl-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.0.0.RELEASE\spring-context-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.0.0.RELEASE\spring-aop-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.0.0.RELEASE\spring-expression-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jdbc\5.0.0.RELEASE\spring-jdbc-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-tx\5.0.0.RELEASE\spring-tx-5.0.0.RELEASE.jar" com.comet.druid.DruidDemo
八月 16, 2020 12:49:46 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
信息: {dataSource-1} inited
1  //返回的是1,证明就是执行成功了

Process finished with exit code 0

insert 一行记录

package com.comet.druid;

import com.comet.druid.utils.JdbcUtils;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * Druid 演示
 *  1.导入依赖
 *  2.通过创建JdbcTemplate对象
 *      注意:传入的参数是Druid数据源,这里我们使用之前封装好的 JdbcUtils.getDataSource()
 *  3.调用 update() 方法
 */

public class DruidDemo {
    public static void main(String[] args) throws Exception {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JdbcUtils.getDataSource());
        String sql = "INSERT INTO `world`.`city` VALUES (?, ?, ?, ?, ?);";
        System.out.println(jdbcTemplate.update(sql, 4079, "Rafah", "PSE", "Rafah", 92020));
    }
}

新增结果:

"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\Testplan\IntelliJ IDEA 2020.1\lib\idea_rt.jar=64437:D:\Testplan\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\DruidConnectionPool\target\classes;C:\Users\Administrator\.m2\repository\com\alibaba\druid\1.1.22\druid-1.1.22.jar;C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;C:\Users\Administrator\.m2\repository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.0.0.RELEASE\spring-beans-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.0.0.RELEASE\spring-core-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.0.0.RELEASE\spring-jcl-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.0.0.RELEASE\spring-context-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.0.0.RELEASE\spring-aop-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.0.0.RELEASE\spring-expression-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jdbc\5.0.0.RELEASE\spring-jdbc-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-tx\5.0.0.RELEASE\spring-tx-5.0.0.RELEASE.jar" com.comet.druid.DruidDemo
八月 16, 2020 1:02:13 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
信息: {dataSource-1} inited
1  // 插入一条记录

Process finished with exit code 0

现在来删除这条记录

package com.comet.druid;

import com.comet.druid.utils.JdbcUtils;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * Druid 演示
 *  1.导入依赖
 *  2.通过创建JdbcTemplate对象
 *      注意:传入的参数是Druid数据源,这里我们使用之前封装好的 JdbcUtils.getDataSource()
 *  3.调用 update() 方法
 */

public class DruidDemo {
    public static void main(String[] args) throws Exception {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JdbcUtils.getDataSource());
        String sql = "DELETE FROM `world`.`city` WHERE `ID` = ?;";
        System.out.println(jdbcTemplate.update(sql, 4079));
    }
}

删除结果:

"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\Testplan\IntelliJ IDEA 2020.1\lib\idea_rt.jar=64723:D:\Testplan\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\DruidConnectionPool\target\classes;C:\Users\Administrator\.m2\repository\com\alibaba\druid\1.1.22\druid-1.1.22.jar;C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;C:\Users\Administrator\.m2\repository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.0.0.RELEASE\spring-beans-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.0.0.RELEASE\spring-core-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.0.0.RELEASE\spring-jcl-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.0.0.RELEASE\spring-context-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.0.0.RELEASE\spring-aop-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.0.0.RELEASE\spring-expression-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jdbc\5.0.0.RELEASE\spring-jdbc-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-tx\5.0.0.RELEASE\spring-tx-5.0.0.RELEASE.jar" com.comet.druid.DruidDemo
八月 16, 2020 1:04:35 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
信息: {dataSource-1} inited
1  // 删除了一条记录

Process finished with exit code 0

DQL 操作实例

queryForMap()

queryForMap() 方法:查询结果讲过结果集封装为Map集合,将列名作为key,值为value
注意:这个方法查询的结果集长度只能是1,至于是为什么自己想想?

package com.comet.druid;

import com.comet.druid.utils.JdbcUtils;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * Druid 演示
 *  1.导入依赖
 *  2.通过创建JdbcTemplate对象
 *      注意:传入的参数是Druid数据源,这里我们使用之前封装好的 JdbcUtils.getDataSource()
 *  3.调用 queryForMap() 方法:查询结果讲过结果集封装为Map集合,将列名作为key,值为value
 *      注意:这个方法查询的结果集长度只能是1,否则会抛出异常
 */

public class DruidDemo {
    public static void main(String[] args) throws Exception {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JdbcUtils.getDataSource());
        String sql = "SELECT  * FROM `world`.`city` where name=?;";
        System.out.println(jdbcTemplate.queryForMap(sql, "Qandahar"));
    }
}
"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\Testplan\IntelliJ IDEA 2020.1\lib\idea_rt.jar=65461:D:\Testplan\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\DruidConnectionPool\target\classes;C:\Users\Administrator\.m2\repository\com\alibaba\druid\1.1.22\druid-1.1.22.jar;C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;C:\Users\Administrator\.m2\repository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.0.0.RELEASE\spring-beans-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.0.0.RELEASE\spring-core-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.0.0.RELEASE\spring-jcl-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.0.0.RELEASE\spring-context-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.0.0.RELEASE\spring-aop-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.0.0.RELEASE\spring-expression-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jdbc\5.0.0.RELEASE\spring-jdbc-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-tx\5.0.0.RELEASE\spring-tx-5.0.0.RELEASE.jar" com.comet.druid.DruidDemo
八月 16, 2020 1:10:54 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
信息: {dataSource-1} inited
{ID=2, Name=Qandahar, CountryCode=AFG, District=Qandahar, Population=237500}  // Map 集合

Process finished with exit code 0

queryForList()

查询之后将结果封装为List>集合
注意:首先将每一条记录封装为一个Map集合,然后再将Map集合装载到List集合中

package com.comet.druid;

import com.comet.druid.utils.JdbcUtils;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;
import java.util.Map;

/**
 * Druid 演示
 *  1.导入依赖
 *  2.通过创建JdbcTemplate对象
 *      注意:传入的参数是Druid数据源,这里我们使用之前封装好的 JdbcUtils.getDataSource()
 *  3.调用 queryForList() 方法:查询之后将结果封装为List>集合
 *      注意:首先将每一条记录封装为一个Map集合,然后再将Map集合装载到List集合中
 */

public class DruidDemo {
    public static void main(String[] args) throws Exception {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JdbcUtils.getDataSource());
        String sql = "SELECT * FROM `world`.`city` LIMIT ?, ?;";
        List> maps = jdbcTemplate.queryForList(sql, 0, 5);
        for (Map map : maps) {
            System.out.println(map);
        }
    }
}

遍历获取一下结果:

"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\Testplan\IntelliJ IDEA 2020.1\lib\idea_rt.jar=49902:D:\Testplan\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\DruidConnectionPool\target\classes;C:\Users\Administrator\.m2\repository\com\alibaba\druid\1.1.22\druid-1.1.22.jar;C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;C:\Users\Administrator\.m2\repository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.0.0.RELEASE\spring-beans-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.0.0.RELEASE\spring-core-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.0.0.RELEASE\spring-jcl-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.0.0.RELEASE\spring-context-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.0.0.RELEASE\spring-aop-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.0.0.RELEASE\spring-expression-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jdbc\5.0.0.RELEASE\spring-jdbc-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-tx\5.0.0.RELEASE\spring-tx-5.0.0.RELEASE.jar" com.comet.druid.DruidDemo
八月 16, 2020 1:18:02 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
信息: {dataSource-1} inited

{ID=1, Name=Kabul, CountryCode=AFG, District=Kabol, Population=1780}
{ID=2, Name=Qandahar, CountryCode=AFG, District=Qandahar, Population=237500}
{ID=3, Name=Herat, CountryCode=AFG, District=Herat, Population=186800}
{ID=4, Name=Mazar-e-Sharif, CountryCode=AFG, District=Balkh, Population=127800}
{ID=5, Name=Amsterdam, CountryCode=NLD, District=Noord-Holland, Population=731200}

Process finished with exit code 0

queryForObject()

查询结果,将结果封装为对象(Object),一般用于聚合函数查询

package com.comet.druid;

import com.comet.druid.utils.JdbcUtils;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * Druid 演示
 *  1.导入依赖
 *  2.通过创建JdbcTemplate对象
 *      注意:传入的参数是Druid数据源,这里我们使用之前封装好的 JdbcUtils.getDataSource()
 *  3.调用 queryForObject() 方法:查询结果,将结果封装为对象(Object),一般用于聚合函数查询
 */

public class DruidDemo {
    public static void main(String[] args) throws Exception {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JdbcUtils.getDataSource());
        String sql = "SELECT COUNT(ID) FROM `world`.`city`;";
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
        System.out.println(count);
    }
}

结果输出

"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\Testplan\IntelliJ IDEA 2020.1\lib\idea_rt.jar=50665:D:\Testplan\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\DruidConnectionPool\target\classes;C:\Users\Administrator\.m2\repository\com\alibaba\druid\1.1.22\druid-1.1.22.jar;C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;C:\Users\Administrator\.m2\repository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.0.0.RELEASE\spring-beans-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.0.0.RELEASE\spring-core-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.0.0.RELEASE\spring-jcl-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.0.0.RELEASE\spring-context-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.0.0.RELEASE\spring-aop-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.0.0.RELEASE\spring-expression-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jdbc\5.0.0.RELEASE\spring-jdbc-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-tx\5.0.0.RELEASE\spring-tx-5.0.0.RELEASE.jar" com.comet.druid.DruidDemo
八月 16, 2020 1:24:38 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
信息: {dataSource-1} inited
4078  //查询的总记录数

Process finished with exit code 0

query() 方法:

查询之后将结果封装为JavaBean对象,参数:SQL、RowMapper
RowMapper 是一个接口,如果我们直接使用它的话,那么就需要实现它的 mapRow 方法,下面看实例:
1. 先定义一个JavaBean对象 City() 注意:定义实体类的时候不要用基本数据类型,而是使用引用类型,避免null值的异常

package com.comet.druid;

public class City {

    /**  对应数据库的字段
     *  `ID` int NOT NULL AUTO_INCREMENT,
     *   `Name` char(35) NOT NULL DEFAULT '',
     *   `CountryCode` char(3) NOT NULL DEFAULT '',
     *   `District` char(20) NOT NULL DEFAULT '',
     *   `Population` int NOT NULL DEFAULT '0',
     * 注意:定义实体类的时候不要用基本数据类型,要用引用类型,避免null值的异常
     */
    private Integer ID;
    private String Name;
    private String CountryCode;
    private String District;
    private Integer Population;

    public Integer getID() {
        return ID;
    }

    public void setID(Integer ID) {
        this.ID = ID;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public String getCountryCode() {
        return CountryCode;
    }

    public void setCountryCode(String countryCode) {
        CountryCode = countryCode;
    }

    public String getDistrict() {
        return District;
    }

    public void setDistrict(String district) {
        District = district;
    }

    public Integer getPopulation() {
        return Population;
    }

    public void setPopulation(Integer population) {
        Population = population;
    }

    @Override
    public String toString() {
        return "City{" +
                "ID=" + ID +
                ", Name='" + Name + '\'' +
                ", CountryCode='" + CountryCode + '\'' +
                ", District='" + District + '\'' +
                ", Population=" + Population +
                '}';
    }
}

调用 query() 方法,传入参数:sql、RowMapper,实现它的 mapRow 方法,并将结果封装为City 对象的数据

package com.comet.druid;

import com.comet.druid.utils.JdbcUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * Druid 演示
 *  1.导入依赖
 *  2.通过创建JdbcTemplate对象
 *      注意:传入的参数是Druid数据源,这里我们使用之前封装好的 JdbcUtils.getDataSource()
 *  3.调用 query() 方法:查询之后将结果封装为JavaBean对象,参数:SQL、RowMapper
 */

public class DruidDemo {
    public static void main(String[] args) throws Exception {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JdbcUtils.getDataSource());
        String sql = "SELECT * FROM `world`.`city` LIMIT 0, 10";
        List count = jdbcTemplate.query(sql, new RowMapper() {
            @Override
            public City mapRow(ResultSet resultSet, int i) throws SQLException {
                City city = new City();
                Integer id = resultSet.getInt("ID");
                String name = resultSet.getString("Name");
                String countryCode = resultSet.getString("CountryCode");
                String district = resultSet.getString("District");
                Integer population = resultSet.getInt("Population");

                city.setID(id);
                city.setName(name);
                city.setCountryCode(countryCode);
                city.setDistrict(district);
                city.setPopulation(population);
                return city;
            }
        });
        for (City city : count) {
            System.out.println(city);
        };
    }
}

结果输出

"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\Testplan\IntelliJ IDEA 2020.1\lib\idea_rt.jar=52858:D:\Testplan\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\DruidConnectionPool\target\classes;C:\Users\Administrator\.m2\repository\com\alibaba\druid\1.1.22\druid-1.1.22.jar;C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;C:\Users\Administrator\.m2\repository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.0.0.RELEASE\spring-beans-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.0.0.RELEASE\spring-core-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.0.0.RELEASE\spring-jcl-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.0.0.RELEASE\spring-context-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.0.0.RELEASE\spring-aop-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.0.0.RELEASE\spring-expression-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jdbc\5.0.0.RELEASE\spring-jdbc-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-tx\5.0.0.RELEASE\spring-tx-5.0.0.RELEASE.jar" com.comet.druid.DruidDemo
八月 16, 2020 1:43:47 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
信息: {dataSource-1} inited
// 结果就是 City 对象的数据
City{ID=1, Name='Kabul', CountryCode='AFG', District='Kabol', Population=1780}
City{ID=2, Name='Qandahar', CountryCode='AFG', District='Qandahar', Population=237500}
City{ID=3, Name='Herat', CountryCode='AFG', District='Herat', Population=186800}
City{ID=4, Name='Mazar-e-Sharif', CountryCode='AFG', District='Balkh', Population=127800}
City{ID=5, Name='Amsterdam', CountryCode='NLD', District='Noord-Holland', Population=731200}
City{ID=6, Name='Rotterdam', CountryCode='NLD', District='Zuid-Holland', Population=593321}
City{ID=7, Name='Haag', CountryCode='NLD', District='Zuid-Holland', Population=440900}
City{ID=8, Name='Utrecht', CountryCode='NLD', District='Utrecht', Population=234323}
City{ID=9, Name='Eindhoven', CountryCode='NLD', District='Noord-Brabant', Population=201843}
City{ID=10, Name='Tilburg', CountryCode='NLD', District='Noord-Brabant', Population=193238}

Process finished with exit code 0

从上面的方法和结果来看,过程的使用并不简单。还需要自己去实现接口中的方法,比较麻烦,而我们使用JDBCTemplate的初衷就是为了简化操作,如果还这么干的话,就没意义了。其实JDBC有提供 RowMapper 接口的实现类 BeanPropertyRowMapper,我们可以拿过来直接使用,下面看一个实例:

package com.comet.druid;

import com.comet.druid.utils.JdbcUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

/**
 * Druid 演示
 *  1.导入依赖
 *  2.通过创建JdbcTemplate对象
 *      注意:传入的参数是Druid数据源,这里我们使用之前封装好的 JdbcUtils.getDataSource()
 *  3.调用 query() 方法:查询之后将结果封装为JavaBean对象,参数:SQL、RowMapper
 *      注意:
 *          1.一般我们使用 BeanPropertyRowMapper 实现类,可以完成数据到JavaBean的自动封装
 *          2. new BeanPropertyRowMapper<对象类型>(类型.class)
 */

public class DruidDemo {
    public static void main(String[] args) throws Exception {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JdbcUtils.getDataSource());
        String sql = "SELECT * FROM `world`.`city` LIMIT 0, 10";
        List count = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(City.class));
        for (City city : count) {
            System.out.println(city);
        }
    }
}

结果是一样的,因为通过源码可以看到 BeanPropertyRowMapper 已经实现了 RowMapper 接口中抽象方法

"C:\Program Files\Java\jdk1.8.0_191\bin\java.exe" "-javaagent:D:\Testplan\IntelliJ IDEA 2020.1\lib\idea_rt.jar=54516:D:\Testplan\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_191\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\DruidConnectionPool\target\classes;C:\Users\Administrator\.m2\repository\com\alibaba\druid\1.1.22\druid-1.1.22.jar;C:\Users\Administrator\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;C:\Users\Administrator\.m2\repository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.0.0.RELEASE\spring-beans-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.0.0.RELEASE\spring-core-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.0.0.RELEASE\spring-jcl-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.0.0.RELEASE\spring-context-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.0.0.RELEASE\spring-aop-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.0.0.RELEASE\spring-expression-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jdbc\5.0.0.RELEASE\spring-jdbc-5.0.0.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-tx\5.0.0.RELEASE\spring-tx-5.0.0.RELEASE.jar" com.comet.druid.DruidDemo
八月 16, 2020 1:58:42 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
信息: {dataSource-1} inited

City{ID=1, Name='Kabul', CountryCode='AFG', District='Kabol', Population=1780}
City{ID=2, Name='Qandahar', CountryCode='AFG', District='Qandahar', Population=237500}
City{ID=3, Name='Herat', CountryCode='AFG', District='Herat', Population=186800}
City{ID=4, Name='Mazar-e-Sharif', CountryCode='AFG', District='Balkh', Population=127800}
City{ID=5, Name='Amsterdam', CountryCode='NLD', District='Noord-Holland', Population=731200}
City{ID=6, Name='Rotterdam', CountryCode='NLD', District='Zuid-Holland', Population=593321}
City{ID=7, Name='Haag', CountryCode='NLD', District='Zuid-Holland', Population=440900}
City{ID=8, Name='Utrecht', CountryCode='NLD', District='Utrecht', Population=234323}
City{ID=9, Name='Eindhoven', CountryCode='NLD', District='Noord-Brabant', Population=201843}
City{ID=10, Name='Tilburg', CountryCode='NLD', District='Noord-Brabant', Population=193238}

Process finished with exit code 0

重点:query() 方法是单元测试过程中最常用的方法,实际业务中一般都是将数据查询出来封装为 JavaBean 对象,然后装载到List集合中使用

小结:

不管是自定义Druid连接池的工具类还是Spring 提供的 JDBCTemplate,确实大大提升了数据库的操作简化,在单元测试或者Dubbo 服务接口测试的时候可以提升编码效率,一般有轮子的时候不建议重复去写这些工具类,但是可以了解一下别人是如何实现的.

你可能感兴趣的:(数据库连接池-JdbcUtils工具类/JDBCTemplate)