6.数据库连接池&DBUtils

6.数据库连接池&DBUtils

1.数据库连接池

1.连接池的概念

  • 连接池就是存放连接的池子,用来管理连接。
  • 好处:可减少重复的使用连接,减少资源浪费(不用每次创建、释放连接)

2.如何使用数据库连接池

  • java为数据库提供了公共的接口:java.sql.DataSource,具体的实现由驱动程序供应商实现。6.数据库连接池&DBUtils
  • 常见的有DBCP连接池、C3P0连接池、Druid连接池

3.DBCP连接池

  • DBCP是Apache成员之一,是一个开源连接池(tomcat内置连接池)
  • 每创建一个项目要导入相应的jar包
  • 6.数据库连接池&DBUtils

1.编写工具类

  • java提供了连接池接口:DataSource;
  • DBCP提供了实现类:BasicDataSource;
  • 工具类代码:
public class DBCPUtils {
    //1.定义常量 保存数据库连接信息
    public static final String DRIVERNAEM="com.mysql.jdbc.Driver";
    public static final String URL="jdbc:mysql://localhost:3306/db5?characterEncoding=UTF-8";
    public static final String  USERNAME="root";
    public static final String PASSWORD="123456";

    //2.创建连接对象(由DBCP提供的实现类)
    public static BasicDataSource dataSource=new BasicDataSource();
    
    //3.使用静态代码块进行配置
    static {
        dataSource.setDriverClassName(DRIVERNAEM);
        dataSource.setUrl(URL);
        dataSource.setUsername(USERNAME);
        dataSource.setPassword(PASSWORD);
    }
    //4.获取连接的方法
    public static Connection getConnection() throws SQLException {
        //从连接池中获取
        Connection connection=dataSource.getConnection();
        return  connection;
    }
    //5.释放资源
    public static void close(Connection con, Statement statement){}
    public static void close(Connection con, Statement statement, ResultSet resultSet){}

  • 测试类代码:

    public class TestDBCP {
        /**
         * 测试DBCP连接池
         * @param args
         */
        public static void main(String[] args) throws SQLException {
            //1.获取连接
            Connection connection= DBCPUtils.getConnection();
            //2.获取语句执行对象
            Statement statement = connection.createStatement();
            //3.SQL语句执行
            String sql="select ename from employee";
            ResultSet resultSet = statement.executeQuery(sql);
            //处理结果集
            while(resultSet.next()){
                String ename=resultSet.getString("ename");
                System.out.println(ename);
            }
            //5.释放资源
            DBCPUtils.close(connection,statement,resultSet);
        }
    }
    

2.DBCP的配置项

driverClassName 数据库驱动名称
url 数据库地址
username 用户名
password 密码

4.C3P0连接池

  • 开源的连接池。目前支持它的开源项目有:Spring、Hibernate
  • C3P0的核心工具类:ComboPooledDataSource
  • 导入相关架包至myjar文件夹。

1.导入配置文件xml

6.数据库连接池&DBUtils

  • 将写好的配置文件放入src。建议创建一个resource文件夹(专门存放资源文件)

    6.数据库连接池&DBUtils

2.编写C3P0工具类

public class C3P0Utils {
    //1.创建连接池对象,使用配置文件(无参使用xml中默认配置方法)
    public static ComboPooledDataSource dataSource = new ComboPooledDataSource("mysql");
    
    //2.获得连接方法
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    
    //3.关闭资源
    public static void close(Connection con, Statement statement){}
    public static void close(Connection con, Statement statement, ResultSet resultSet){}
}

5.Druid连接池

  • Druid(德鲁伊)是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是目前最好的数据库连接池。在功能、性能、扩展性方面,都超过其他数据库连接池,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况。
  • 同样需要导入相关jar包

1.导入配置文件(properties)格式

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db5?characterEncoding=UTF-8
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000


#### 2.编写Druid工具类

+ 获取连接池对象
+  通过工厂来获取: DruidDataSourceFactory类的createDataSource方法;
+ createDataSource(Properties p) 方法参数是一个属性集对象

```java
public class DruidUtils {
  //1.定义成员变量
  public static DataSource dataSource;

  //2.静态代码块
  static {
      try {
          //3.创建属性集对象
          Properties p=new Properties();

          //4.加载配置文件。Druid连接池不能主动加载配置文件,需要指定文件。
          InputStream inputStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");

          //5.使用Propreties对象的load方法,从字节流中读取配置文件
          p.load(inputStream);

          //6.使用工厂类获取连接池对象
          dataSource = DruidDataSourceFactory.createDataSource(p);
      } catch (Exception e) {
          e.printStackTrace();
      }

  }
  //获取连接方法
  public static Connection getConnection()  {
      try {
          return dataSource.getConnection();
      } catch (SQLException e) {
          e.printStackTrace();
          return null;
      }
  }
 //获取Druid连接池对象的方法  给QueryRunner使用
  public static DataSource getDataSource(){
      return dataSource;
  }

  //释放资源……

2.DBUtils工具类(重点)

1.DBUtils简介

  • Commons DBUtils是Apache提供的一个对JDBC进行简单封装的开源工具类库,可以简化JDBC程序的开发。
  • 同样导入相关jar包.(commons-dbutils-1.6.jar)

2.核心功能

  1. QueryRunner 中提供对sql语句操作的API
  2. ResultSetHandler接口,用于定义select操作后,怎样封装结果集
  3. DbUtils类,他就是一个工具类,定义了关闭资源与事务处理相关方法.

3.JavaBean组件

  • JavaBenn就是一个实体类,开发中通常用于封装数据。有以下特点:
  1. 实现序列化接口,Serializable
  2. 提供空参构造
  3. 私有化字段
  4. 提供getter和setter方法
  • 创建Employee类和数据库的employee表对应
    • :可以创建一个entity(实体)包,存放JavaBean

4.QueryRunner核心类

1.构造方法

  • QueryRunner() //手动
  • QueryRunner(DataSource ds) ,提供连接池对象,DBUtils底层自动维护连接connection

2.常用方法

  • update(Connection conn, String sql, Object… params) ,用来完成表数据的增加、删除、更新操作

  • query(Connection conn, String sql, ResultSetHandler rsh, Object… params) ,用来完成表 数据的查询操作

  • 参数 说明
    Connection conn 数据库连接对象, 自动模式创建QueryRun 可以不传 ,手动模式必须传递
    String sql 占位符形式的SQL ,使用 ? 号占位符
    Object…param Object类型的 可变参,用来设置占位符上的参数

步骤 1.创建QueryRunner(手动或自动) 2.占位符方式 编写SQL 3.设置占位符参数 4.执行

3.代码示例(DML)

//增加    
@Test  
    public void testInsert() throws SQLException {
        //1.手动创建QueryRunner
        QueryRunner qr=new QueryRunner();
        //2.编写sql
        String sql="insert into employee values(?,?,?,?,?,?)";
        //3.设置占位符参数
        Object[] parm={null,"张三",20,"女",10000,"2021-1-19"};
        //4.执行update方法
        Connection connection = DruidUtils.getConnection();
        int i = qr.update(connection, sql, parm);
        //5.释放资源
        //connection.close();
        DbUtils.close(connection);
    }
//修改
   @Test
    public void testUpdate() throws SQLException {
        //1.自动创建QueryRunner
        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
        //2.编写sql
        String sql = "update employee set salary=? where ename=?";
        //3.设置占位符参数
        Object[] parm = {0, "张三"};
        //4.执行update方法
        Connection connection = DruidUtils.getConnection();
        int i = qr.update(sql, parm);
        //5.释放资源
        DbUtils.close(connection);
    }

4.QueryRunner实现查询操作

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

ResultSetHandler接口的常见实现类:

ResultSetHandler 实现类 说明
ArrayHandler 将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值
ArrayListHandler 将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。
BeanHandler 将结果集中第一条记录封装到一个指定的javaBean中.
BeanListHandler 将结果集中每一条记录封装到指定的javaBean中,再将这些javaBean在封装到List 集合中
MapHandler 将结果集中第一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值
ColumnListHandler 将结果集中指定的列的字段值,封装到一个List集合中
ScalarHandler 用于封装单个数据(返回long类型)
  • ResultSetHandler 常用实现类
    • :query([Connection con],String sql, handler ,Object[] param) 。自动模式创建QueryRunner, 执行查询

5.代码示例

    @Test  //查询id为5的记录,封装到数组中 [ArrayHandler]
    public void testFindById() throws SQLException {
        //1.创建QueryRunner
        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
        //2.编写sql
        String sql = "select * from employee where eid=?";
        //3.执行
        Object[] query = qr.query(sql, new ArrayHandler(), 5);
        System.out.println(Arrays.toString(query));
    }
    @Test   //查询薪资大于 3000 的所员工信息,封装到JavaBean中再封装到List集合中[BeanListHandler]
    public void testFindBySalary() throws SQLException {
        //1.创建QueryRunner
        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
        //2.编写sql
        String sql = "select * from employee where salary>?";
        //3.执行
        List<Employee> query = qr.query(sql, new BeanListHandler<Employee>(Employee.class), 300);
        for (Employee e : query) {
            System.out.println(e);
        }
    }
    //查询姓名是 张百万的员工信息,将结果封装到Map集合中[MapHandler]
    @Test
    public void testFindByName() throws SQLException {
        //1.创建QueryRunner
        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
        //2.编写sql
        String sql = "select * from employee where ename=?";
        //3.执行
        Map<String, Object> query = qr.query(sql, new MapHandler(), "李白");
        //4. 返回键值对
        Set<Map.Entry<String, Object>> entries = query.entrySet();
        System.out.println(entries);
    }
    @Test //查询指定列的的字段值,封装到一个List集合中[ColumnListHandler]
    public void testFindName() throws SQLException {
        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
        String sql = "select ename from employee";
        List<String> query = qr.query(sql, new ColumnListHandler<String>());
        for (String e : query) {
            System.out.println(e);
        }
    }

3.数据库批处理

  • 一次操作执行多条SQL语句,提高效率
  • Mysql默认关闭批处理,要在url加个参数打开(rewriteBatchedStatements=true)
  • Statement和PreparedStatement都支持批处理操作
方法 说明
void addBatch() 将给定的 SQL 命令添加到此 Statement 对象的当前命令列表中。
int[] executeBatch() 提交命令值数据库执行,成功返回一个数组(受影响的行数)
Connection connection = DruidUtils.getConnection();//连接
//获取语句执行平台
String sql="insert into testBatch(uname) values(?)";
 PreparedStatement preparedStatement =connection.prepareStatement(sql);

for (int i = 0; i < 10000; i++) {
    preparedStatement.setString(1,"小张"+i);
    preparedStatement.addBatch();
      }
int[] ints = preparedStatement.executeBatch();

4.Mysql元数据

  • 除表以外的数据都是元数据,分为以下三类:
    1. 查询结构信息
    2. 数据库和数据表的信息
    3. MYSQL服务器信息

1.使用JDBC获取元数据

  • JDBC中描述元数据的类:
元数据类 作用
DatabaseMetaData 描述数据库的元数据对象(connection调用)
ResultSetMetaData 描述结果集的元数据对象(prepareStatement调用)
  • 获取元数据对象的方法:getMetaData ()

2.DatabaseMetaData常用方法

方法说明
getURL() : 获取数据库的URL
getUserName(): 获取当前数据库的用户名
getDatabaseProductName(): 获取数据库的产品名称
isReadOnly(): 判断数据库是否只允许只读 true 代表只读

3.ResultSetMetaData方法

方法说明
getColumnCount() : 当前结果集共有多少列
getColumnName(int i) : 获取指定列号的列名, 参数是整数 从1开始
getColumnTypeName(int i): 获取指定列号列的类型, 参数是整数 从1开始

roductName(): 获取数据库的产品名称 |
| isReadOnly(): 判断数据库是否只允许只读 true 代表只读 |

3.ResultSetMetaData方法

方法说明
getColumnCount() : 当前结果集共有多少列
getColumnName(int i) : 获取指定列号的列名, 参数是整数 从1开始
getColumnTypeName(int i): 获取指定列号列的类型, 参数是整数 从1开始
上一篇:DBUtils使用


下一篇:DBUtils工具类的使用