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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 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);
    }
  }


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
3月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
3月前
|
小程序 Java 知识图谱
Java 学习笔记 —— BMI & BMR 计算器
这是一个使用 Java 编写的 BMI 与 BMR 计算器小程序,可输入年龄、性别、身高和体重,计算身体质量指数(BMI)和基础代谢率(BMR),并输出健康评估结果。通过该项目,掌握了 Java 的输入处理、数据验证、条件判断、数学运算及格式化输出等基础知识,是 Java 初学者的理想练习项目。
|
6月前
|
Java API 微服务
2025 年 Java 从入门到精通学习笔记全新版
《Java学习笔记:从入门到精通(2025更新版)》是一本全面覆盖Java开发核心技能的指南,适合零基础到高级开发者。内容包括Java基础(如开发环境配置、核心语法增强)、面向对象编程(密封类、接口增强)、进阶技术(虚拟线程、结构化并发、向量API)、实用类库与框架(HTTP客户端、Spring Boot)、微服务与云原生(容器化、Kubernetes)、响应式编程(Reactor、WebFlux)、函数式编程(Stream API)、测试技术(JUnit 5、Mockito)、数据持久化(JPA、R2DBC)以及实战项目(Todo应用)。
372 6
|
9月前
|
存储 Java
# 【Java全栈学习笔记-U1-day02】变量+数据类型+运算符
本篇笔记主要围绕Java全栈学习的第二天内容展开,涵盖了变量、数据类型、运算符以及Scanner类的应用。首先介绍了变量的概念与命名规范,以及如何定义和使用变量;接着详细讲解了Java中的基本数据类型,包括整型、浮点型、字符型、布尔型等,并通过实例演示了数据类型的运用。随后,深入探讨了各类运算符(赋值、算术、关系、逻辑)及其优先级,帮助理解表达式的构成。最后,介绍了如何利用Scanner类实现用户输入功能,并通过多个综合示例(如计算圆面积、购物打折、变量交换及银行利息计算)巩固所学知识。完成相关作业将进一步加深对这些基础概念的理解与实践能力。
167 13
|
9月前
|
SQL druid Oracle
【YashanDB知识库】yasdb jdbc驱动集成druid连接池,业务(java)日志中有token IDENTIFIER start异常
客户Java日志中出现异常,影响Druid的merge SQL功能(将SQL字面量替换为绑定变量以统计性能),但不影响正常业务流程。原因是Druid在merge SQL时传入null作为dbType,导致无法解析递归查询中的`start`关键字。
|
9月前
|
SQL Java 中间件
【YashanDB知识库】yasdb jdbc驱动集成BeetISQL中间件,业务(java)报autoAssignKey failure异常
在BeetISQL 2.13.8版本中,客户使用batch insert向yashandb表插入数据并尝试获取自动生成的sequence id时,出现类型转换异常。原因是beetlsql在prepareStatement时未指定返回列,导致yashan JDBC驱动返回rowid(字符串),与Java Bean中的数字类型tid不匹配。此问题影响业务流程,使无法正确获取sequence id。解决方法包括:1) 在batchInsert时不返回自动生成的sequence id;2) 升级至BeetISQL 3,其已修正该问题。
【YashanDB知识库】yasdb jdbc驱动集成BeetISQL中间件,业务(java)报autoAssignKey failure异常
|
9月前
|
开发框架 Java 开发工具
【Java全栈学习笔记-U1-day01】Java介绍
本笔记整理了Java学习的基础内容,涵盖程序理解、Java语言特性、JDK安装与配置、Java程序开发工具及编写步骤。重点介绍了Java程序的基本结构、编译和运行过程,以及输出语句的使用。通过实例演示了IDEA创建Java程序的方法,并强调了编码规范和注意事项。适合初学者复习和交流学习。 主要内容: 1. 理解程序:计算机组成、程序定义。 2. 简介:Java语言特点、技术平台、JDK作用。 3. 编写Java程序:编写、编译、运行步骤,基本结构。 4. 输出语句 5. DEA使用:新建工程、保存位置、文件介绍、新建类。 6. 扩展:注释、代码规范、大小写敏感、缩进等。
|
11月前
|
SQL Java 关系型数据库
使用 JDBC 实现 Java 数据库操作
JDBC(Java Database Connectivity)是 Java 提供的数据库访问技术,允许通过 SQL 语句与数据库交互。本文详细介绍了 JDBC 的使用方法,包括环境准备、编程步骤和完整示例。
943 7
|
11月前
|
SQL Java 数据库连接
【潜意识Java】Java中JDBC过时方法的替代方案以及JDBC为什么过时详细分析
本文介绍了JDBC中一些常见过时方法及其替代方案。
310 5
|
12月前
|
Java 数据库连接 数据库
springboot java.lang.ClassNotFoundException: dm.jdbc.driver.DmDriver应该如何解决
通过上述步骤,可以有效解决Spring Boot项目中遇到的 `java.lang.ClassNotFoundException: dm.jdbc.driver.DmDriver`问题。确保在项目中正确添加达梦数据库的JDBC驱动依赖,并在配置文件中正确配置数据源信息,是解决此问题的关键。通过这些方法,可以确保Spring Boot项目能够正确连接达梦数据库并正常运行。
2089 31