[Java]JDBC学习笔记(尚硅谷康师傅JDBC)(四)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: [Java]JDBC学习笔记(尚硅谷康师傅JDBC)(四)

🌊 C3P0数据库连接池

💦 方式一

@Test
    public void test() throws Exception {
        // 获取c3p0数据库连接池
        // 实际开发中只需要一个数据库连接池即可
        ComboPooledDataSource cpds = new ComboPooledDataSource();
        cpds.setDriverClass("com.mysql.jdbc.Driver");
        cpds.setJdbcUrl("jdbc:mysql://localhost:3306/test?characterEncoding=utf8&rewriteBatchedStatements=true");
        cpds.setUser("root");
        cpds.setPassword("123123");
        // 通过设置相关的参数对数据库连接池进行管理
        // 设置初始时数据库连接池中的连接数
        cpds.setInitialPoolSize(10);
        // 获取数据库连接
        Connection connection = cpds.getConnection();
        System.out.println(connection);
    }

💦 方式二:使用配置文件

c3p0-config.xml(配置文件默认固定为该名,src目录下)

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
  <named-config name="helloc3p0">
    <!-- 提供获取连接的4个基本信息 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?characterEncoding=utf8</property>
    <property name="user">root</property>
    <property name="password">123123</property>
    <!-- 进行数据库连接池管理的基本信息 -->
    <!-- 当数据库连接池中的连接数不够时,c3p0一次性向数据库服务器申请的连接数 -->
    <property name="acquireIncrement">5</property>
    <!-- c3p0数据库连接池中初始化时的连接数 -->
    <property name="initialPoolSize">10</property>
    <!-- c3p0数据库连接池维护的最少连接数 -->
    <property name="minPoolSize">10</property>
    <!-- c3p0数据库连接池维护的最多的连接数 -->
    <property name="maxPoolSize">100</property>
    <!-- c3p0数据库连接池最多维护的Statement的个数 -->
    <property name="maxStatements">50</property>
    <!-- 每个连接中可以最多使用的Statement的个数 -->
    <property name="maxStatementsPerConnection">2</property>
  </named-config>
</c3p0-config>
@Test
    public void test2() throws Exception {
        // 获取c3p0数据库连接池
        // 实际开发中只需要一个数据库连接池即可
        // 参数值与<named-config name="hellc3p0">中的name值一致
        ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0");
        // 获取数据库连接
        Connection connection = cpds.getConnection();
        System.out.println(connection);
    }

@Test
    public void test2() throws Exception {
        // 获取c3p0数据库连接池
        // 参数值与<named-config name="hellc3p0">中的name值一致
        ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0");
        // 获取数据库连接
        Connection connection = cpds.getConnection();
        // System.out.println(connection);
        String sql = "select * from user_table";
        PreparedStatement ps = connection.prepareStatement(sql);
        ps.execute();
        ResultSet resultSet = ps.getResultSet();
        while (resultSet.next()) {
            System.out.println(resultSet.getString("user"));
        }
        resultSet.close();
        ps.close();
        connection.close();
    }

🌊 DBCP

💦 方式一

@Test
    public void test1() throws SQLException {
        // 创建DBCP数据库连接池
        // 实际开发中只需要一个数据库连接池即可
        BasicDataSource source = new BasicDataSource();
        // 设置基本信息
        source.setDriverClassName("com.mysql.jdbc.Driver");
        source.setUrl("jdbc:mysql://localhost:3306/test?characterEncoding=utf8");
        source.setUsername("root");
        source.setPassword("123123");
        //还可以设置其他涉及数据库连接池管理的相关属性:
        source.setInitialSize(10);
        source.setMaxActive(10);
        Connection connection = source.getConnection();
        System.out.println(connection);
    }

💦 方式二:使用配置文件

src目录下新建 dbcp.properties 配置文件

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8
username=root
password=123123
initialSize=10
#...
@Test
    public void test2() throws Exception {
        Properties properties = new Properties();
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties");
        properties.load(is);
        // 实际开发中只需要一个数据库连接池即可
        DataSource source = BasicDataSourceFactory.createDataSource(properties);
        Connection connection = source.getConnection();
        System.out.println(connection);
        connection.close();
    }

💦 dbcp连接池常用基本配置属性

  1. initialSize :连接池启动时创建的初始化连接数量(默认值为0)
  2. maxActive :连接池中可同时连接的最大的连接数(默认值为8,调整为20,高峰单机器在20并发左右,自己根据应用场景定)
  3. maxIdle:连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制(默认为8个,maxIdle不能设置太小,因为假如在高负载的情况下,连接的打开时间比关闭的时间快,会引起连接池中idle的个数 上升超过maxIdle,而造成频繁的连接销毁和创建,类似于jvm参数中的Xmx设置)
  4. minIdle:连接池中最小的空闲的连接数,低于这个数量会被创建新的连接(默认为0,调整为5,该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大,因为在机器很空闲的时候,也会创建低于minidle个数的连接,类似于jvm参数中的Xmn设置)
  5. maxWait :最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待(默认为无限,调整为60000ms,避免因线程池不够用,而导致请求被无限制挂起)
  6. poolPreparedStatements:开启池的prepared(默认是false,未调整,经过测试,开启后的性能没有关闭的好。)
  7. maxOpenPreparedStatements:开启池的prepared 后的同时最大连接数(默认无限制,同上,未配置)
  8. minEvictableIdleTimeMillis :连接池中连接,在时间段内一直空闲, 被逐出连接池的时间

🌊 Druid

💦 使用配置文件获取链接

在src目录下新建 druid.properties 配置文件

url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8
username=root
password=285013
driverClassName=com.mysql.jdbc.Driver
@Test
    public void test1() throws Exception {
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
        Properties properties = new Properties();
        properties.load(is);
        // 实际开发中只需要一个数据库连接池即可
        DataSource source = DruidDataSourceFactory.createDataSource(properties);
        Connection connection = source.getConnection();
        System.out.println(connection);
    }

💦 Druid连接池常用基本配置属性

🥽 Apache-DBUtils实现CRUD操作

🌊 QueryRunner类

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

  • QueryRunner类提供了两个构造器:
  • 默认的构造器
  • 需要一个 javax.sql.DataSource 来作参数的构造器
  • QueryRunner类的主要方法:
  • 更新
  • public int update(Connection conn, String sql, Object… params) throws SQLException:用来执行一个更新(插入、更新或删除)操作。
  • 插入
  • public T insert(Connection conn,String sql,ResultSetHandler 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.即自动生成的键值
  • 批处理
  • public int[] batch(Connection conn,String sql,Object[][] params)throws SQLException: INSERT, UPDATE, or DELETE语句
  • public T insertBatch(Connection conn,String sql,ResultSetHandler rsh,Object[][] params)throws SQLException:只支持INSERT语句
  • 查询
  • public Object query(Connection conn, String sql, ResultSetHandler rsh,Object… params) throws SQLException:执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句 的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。

🌊 ResultSetHandler接口及实现类

  • 该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。
  • ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)。
  • 接口的主要实现类:
  • ArrayHandler:把结果集中的第一行数据转成对象数组。
  • ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
  • BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
  • BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
  • ColumnListHandler:将结果集中某一列的数据存放到List中。
  • KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
  • MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
  • MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
  • ScalarHandler:查询单个值对象,用于查询特殊值

🌊 插入数据

@Test
    public void test1() throws Exception {
        Properties properties = new Properties();
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
        properties.load(is);
        DataSource source = DruidDataSourceFactory.createDataSource(properties);
        Connection connection = source.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        String sql = "insert into customers(name, email, birth) values(?, ?, ?)";
        // 填充执行sql, 返回影响的行数
        int insterCount = queryRunner.update(connection, sql, "ZS", "ZSZSZS@qq.com", "2001-11-23");
        System.out.println("添加的记录条数为:" + insterCount);
        connection.close();
    }

🌊 查询数据

@Test
    public void test1() throws Exception {
        Properties properties = new Properties();
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
        properties.load(is);
        DataSource source = DruidDataSourceFactory.createDataSource(properties);
        Connection connection = source.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        String sql = "select id, name, email from customers where id=?";
        BeanHandler<Customer> customerBeanHandler = new BeanHandler<>(Customer.class);
        Customer customer = queryRunner.query(connection, sql, customerBeanHandler, 10);
        System.out.println(customer);
    }

@Test
    public void test1() throws Exception {
        Properties properties = new Properties();
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
        properties.load(is);
        DataSource source = DruidDataSourceFactory.createDataSource(properties);
        Connection connection = source.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        String sql = "select id, name, email from customers where id<?";
        BeanListHandler<Customer> customerBeanHandler = new BeanListHandler<>(Customer.class);
        List<Customer> customerList = queryRunner.query(connection, sql, customerBeanHandler, 10);
        customerList.forEach(System.out::println);
    }

@Test
    public void test1() throws Exception {
        Properties properties = new Properties();
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
        properties.load(is);
        DataSource source = DruidDataSourceFactory.createDataSource(properties);
        Connection connection = source.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        String sql = "select id, name, email from customers where id<?";
        MapListHandler mapListHandler = new MapListHandler();
        List<Map<String, Object>> query = queryRunner.query(connection, sql, mapListHandler, 10);
        for (Map<String, Object> q: query) {
            System.out.println(q);
        }
    }

🌊 查询特殊值

@Test
    public void test1() throws Exception {
        Properties properties = new Properties();
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
        properties.load(is);
        DataSource source = DruidDataSourceFactory.createDataSource(properties);
        Connection connection = source.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        String sql = "select count(*) from customers";
        ScalarHandler handler = new ScalarHandler();
        Long query = (Long) queryRunner.query(connection, sql, handler);
        System.out.println(query);
    }

🌊 自定义ResultSetHandler的实现类

/*
   * 自定义ResultSetHandler的实现类
   */
  @Test
  public void testQuery7(){
    Connection conn = null;
    try {
      QueryRunner runner = new QueryRunner();
      conn = JDBCUtils.getConnection3();
      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 {
//          System.out.println("handle");
//          return null;
//          return new Customer(12, "成龙", "Jacky@126.com", new Date(234324234324L));
          if(rs.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);
    }
  }


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
23天前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
40 0
|
3月前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(基础篇)
从Java环境的搭建到实际代码的编写,从基本用法的讲解到底层原理的剖析,深度解析Java基础知识。本文是《Java学习路线》专栏的起始文章,旨在提供一套完整的Java学习路线,覆盖Java基础知识、数据库、SSM/SpringBoot等框架、Redis/MQ等中间件、设计模式、架构设计、性能调优、源码解读、核心面试题等全面的知识点,并在未来不断更新和完善,帮助Java从业者在更短的时间内成长为高级开发。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(基础篇)
|
3月前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)
本文是Java基础的进阶篇,对异常、集合、泛型、Java8新特性、I/O流等知识进行深入浅出的介绍,并附有对应的代码示例,重要的地方带有对性能、底层原理、源码的剖析。适合Java初学者。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)
|
2月前
|
Java 数据安全/隐私保护
java学习笔记(基础习题)
java学习笔记(基础习题)
43 0
|
2月前
|
Java 程序员 开发工具
java学习笔记
java学习笔记
40 0
|
2月前
|
SQL Java 数据库连接
如何在 Java 脚本中有效地使用 JDBC
如何在 Java 脚本中有效地使用 JDBC
17 0
|
3月前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(高级篇)
本文是“Java学习路线”中Java基础知识的高级篇,主要对多线程和反射进行了深入浅出的介绍,在多线程部分,详细介绍了线程的概念、生命周期、多线程的线程安全、线程通信、线程同步,并对synchronized和Lock锁;反射部分对反射的特性、功能、优缺点、适用场景等进行了介绍。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(高级篇)
|
4月前
|
SQL Java 关系型数据库
探索Java数据库连接的奥秘:JDBC技术全攻略
探索Java数据库连接的奥秘:JDBC技术全攻略
63 8
|
13天前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
|
11天前
|
存储 监控 小程序
Java中的线程池优化实践####
本文深入探讨了Java中线程池的工作原理,分析了常见的线程池类型及其适用场景,并通过实际案例展示了如何根据应用需求进行线程池的优化配置。文章首先介绍了线程池的基本概念和核心参数,随后详细阐述了几种常见的线程池实现(如FixedThreadPool、CachedThreadPool、ScheduledThreadPool等)的特点及使用场景。接着,通过一个电商系统订单处理的实际案例,分析了线程池参数设置不当导致的性能问题,并提出了相应的优化策略。最终,总结了线程池优化的最佳实践,旨在帮助开发者更好地利用Java线程池提升应用性能和稳定性。 ####

热门文章

最新文章