原生 JDBC API、连接池概述

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 原生 JDBC API、连接池概述

概述

JDBC:Java DataBase Connectity(java数据库的连接)是一种专门用于执行SQL语句的 Java API,可以为多种关系数据库提供统一的访问,它由一组用Java语言编写的接口组成。java代码操作各种数据库底层都是使用 JDBC。

JDBC规范定义接口,具体的实现由各大数据库厂商来实现 ,JDBC是Java访问数据库的标准规范。真正怎么操作数据库还需要具体的实现类,也就是数据库驱动(第三方 JAR 包)。每个数据库厂商根据自家数据库方式编写好自己数据库的驱动。数据库驱动由数据库厂商提供。

JDBC API

DriverManager 类

// 加载驱动 
static void registerDriver(Driver driver)     // 实际开发中不会选择  因为加载了2次驱动
Class.forName(Driver的全限定名)                 // 反射方式 加载一次驱动  适用开发

// 获取数据库连接的对象。该步骤可以放入try()中自动释放资源,否则需手动释放资源
static Connection getConnection(String url, String user, String password);
参数:
    Url:数据库的地址   固定格式:jdbc:数据库类型://数据库地址:端口号/数据库名
    user:数据库的用户名
    Password:数据库的密码
注:
    如果数据出现乱码需要加上参数: ?characterEncoding=utf8,表示让数据库以UTF-8编码来处理数据。 
    例如:jdbc:数据库类型://数据库地址:端口号/数据库名?characterEncoding=utf8

Connection 接口

// 获取执行SQL语句的Statement(预编译)对象    -- 常用
PreparedStatement PreparedStatement(String sql)
// 获取执行SQL语句的Statement(编译)对象
Statement createStatement();

// 操作事务。false:开启事务, ture:关闭事务(默认)
void setAutoCommit(boolean autoCommit);    // 开始事务
void commit();        // 提交事务
void rollback();    // 回滚事务
// 注:在使用手动事务时,必须要抓取异常,在catch块中进行回滚事务。只要有事务,就必须try-catch捕捉处理。查询加不加事务都行

// 关闭连接,释放资源。重要!若未放入try()中自动释放资源,则需手动释放资源!
void close()

PreparedStatement:预编译对象

作用:用来执行sql语句的

语句执行者:Statement编译对象、preparedStatement预编译对象 的区别:

  • Statement编译对象是有什么样的sql就执行什么样的sql语句,每次执行任何一条sql语句都得让数据库去编译执行,如果执行一万条同样的查询语句,数据库要编译一万次,效率低
  • preparedStatement预编译对象是先将sql格式传递给数据库做预编译,其后拿着预编译结果传递参数执行sql,执行一万条同样的查询语句,数据库只编译一次,根据不同的参数做不用的执行

预编译的好处:

  1. 只需要编译一次,效率高
  2. 能让数据库提前知晓要执行的sql语句格式,只负责给数据库传参即可

语法格式:

select * from 表 where 字段1=值1 and 字段2=值2;    -- Statement编译对象: 

select * from 表 where name=? and password=?;    -- preparedStatement预编译对象

注:
    ? : 占位符。所有的实际参数都用占位符替换了,而不在是直接设值了。默认从左向右第1个开始
        通过外部方法来设置实际参数的值:set字段类型(占位符的序号,要设置的值);
        占位符的序号是从1开始的 
        setString(1,"jack");
        setString(2,"1234");

常用方法:

// 执行查询语句。返回结果集对象
ResultSet executeQuery();
// 执行sql语句(增删改),返回值为代表受影响的行数
int executeUpdate();
// 释放资源
void close()

Statement 接口

// 执行查询语句。返回结果集对象
ResultSet executeQuery()  
// 执行sql语句(增删改),返回值为代表受影响的行数
int executeUpdate()
// 释放资源
void close()

Statement编译对象:拼接什么样的sql就执行什么样的sql语句

注意:使用Statement对象来操作sql语句会有缺陷:会造成数据的安全隐患!

  • 比如登录中的sql拼接:select * from user where username='jack' #' and password='123';

    相当于注释掉了密码的校验,这种安全隐患称为:Sql注入

    Sql注入:将用户输入的内容作为了sql语句的一部分,改变了原有sql语句的含义

  • 解决:使用另一个对象--preparedStatement对象来操作SQL语句

Resultset 接口

// 封装查询语句的结果集
boolean next()         // 可以让指针向下移动一行,默认在第一行之前。返回值 true:代表有数据  false:代表没数据

// 获取结果集中每一行的数据
T get类型(int 列的位置)
T get类型(String 列名)
    
// 释放资源
void close()

原生 JDBC 代码示例

    @Test
    public void test1() throws Exception {

        // 加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        
        try(
            // 获取数据库连接对象。放入try()中,自动释放资源
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/bookdb", 
                                                                "root", "password");
        ) {
            // 拼接sql语句
            String sql="select * from user u where u.name=?";
            // 获取执行SQL语句的对象(预编译对象)
            PreparedStatement pst = connection.preparedStatement(sql);
            // 设置具体的参数
            pst.setString(1, "张三");
            // 执行sql语句。resultSet: 结果集对象 (代表的就是查出来的表)
            ResultSet resultSet = pst.executeQuery(sql);
    
            // 遍历结果集
            while(resultSet.next()){
                // 获取数据打印
                int id = resultSet.getInt("id");
                String username = resultSet.getString("username");
                String password = resultSet.getString("password");
    
                System.out.println(id+":"+username+":"+password);
            }
    
            // 释放资源
            resultSet.close();
            pst.close();
            // connection.close();        // 重要! 若没有放到try()内自动释放资源,则需要手动释放资源
        } catch(Exception e){
            ...
        }
    }

连接池(数据源)

连接池:存放数据库连接的容器(集合)

连接池的作用及优化原理

之前在使用jdbc操作数据库数据的时候,有一个步骤是获取连接(创建连接);连接用完,还需要释放连接(销毁连接),这2个步骤太消耗资源了;创建连接=0.1秒,销毁连接=0.1秒,10000000*0.2=2000000秒。

连接池可以帮助解决创建连接和销毁连接带来的资源消耗问题。

连接池就是用来优化jdbc的以下2个步骤:

  1. 优化的是 jdbc 的创建连接部分
  2. 优化的是 jdbc 的销毁连接部分

优化原理

在连接池初始化时,就在容器中创建一定量的连接;当用户要连数据库的时候,就从容器中拿一个连接使用;使用完毕之后,不再是销毁,而是把使用后的连接还放回容器 供下一个用户去循环使用。

在企业中使用的都是已经成熟并且性能很高的提供好的连接池。

常见的连接池:

  • DBCP:Apache提供的数据库连接池技术。
  • C3P0:数据库连接池技术,目前使用它的开源项目有Hibernate、Spring等。
  • HikaricP:日本开发的连接池技术,性能之王,目前使用它的开源项目有springBoot等。
  • Druid:阿里巴巴提供的数据库连接池技术,目前最好的数据库连接池

            <!-- alibaba连接池 依赖-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.0.31</version>
            </dependency>

jdbc + druid 代码示例

配置文件:druid.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db88
username=root
password=password

initialSize=10
maxActive=20
minIdle=2
maxWait=2000

工具类:使用druid的方法加载的配置文件,连接从druid连接池获取的

// jdbc+druid的工具类
public class JDBCUtils {
    // 数据源
    private static DataSource ds;

    static {
//        // 加载配置。不使用druid
//        ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
//        driver = bundle.getString("driver");
//        url = bundle.getString("url");
//        username = bundle.getString("username");
//        password = bundle.getString("password");
//        // 加载驱动
//        try {
//            Class.forName(driver);
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }
        
        // 加载配置。使用druid的方法加载的配置文件,连接从druid连接池获取的
        try {
            // 创建一个配置文件对象
            Properties properties=new Properties();
            // 只要获取src下的资源文件流。”.class.getResourceAsStream“获取的是classess文件的路径,返回流
            InputStream is = JDBCUtils.class.getResourceAsStream("/druid.properties");
            // 配置文件对象加载配置文件
            properties.load(is); 
            // 创建druid的数据源
            ds = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 获取连接的方法
    public static Connection getConnection() throws Exception {
        Connection connection = ds.getConnection();
        return connection;
    }

    // 释放资源的方法
    public static void closeZY(ResultSet rs, Statement statement, Connection connection){
        try {
            if(rs!=null){
                rs.close();
            }
            if(statement!=null){
                statement.close();
            }
            if(connection!=null){
                connection.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

jdbc + druid 测试代码

    @Test
    public void test1() {
        // 从连接池中获取连接
        Connection connection = JDBCUtils.getConnection();
        // 拼接sql语句
        String sql="select * from user u where u.name=?";
        // 获取执行SQL语句的对象(预编译对象)
        PreparedStatement preparedStatement = connection.preparedStatement(sql);
        // 设置具体的参数
        preparedStatement.setString(1, "张三");
        ResultSet rs = preparedStatement.executeQuery();
        while(rs.next()){
            int id = rs.getInt("id");
            String name = rs.getString("name");
            String password = rs.getString("password");
            System.out.println(id+"::"+name+"::"+password);
        }
        // 释放资源
        JDBCUtils.closeZY(null, preparedStatement, connection);
    }
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
25天前
|
JSON 安全 API
淘宝商品详情API接口(item get pro接口概述)
淘宝商品详情API接口旨在帮助开发者获取淘宝商品的详细信息,包括商品标题、描述、价格、库存、销量、评价等。这些信息对于电商企业而言具有极高的价值,可用于商品信息展示、市场分析、价格比较等多种应用场景。
|
1月前
|
数据采集 监控 数据挖掘
常用电商商品数据API接口(item get)概述,数据分析以及上货
电商商品数据API接口(item get)是电商平台上用于提供商品详细信息的接口。这些接口允许开发者或系统以编程方式获取商品的详细信息,包括但不限于商品的标题、价格、库存、图片、销量、规格参数、用户评价等。这些信息对于电商业务来说至关重要,是商品数据分析、价格监控、上货策略制定等工作的基础。
|
2月前
|
供应链 数据挖掘 API
电商API接口介绍——sku接口概述
商品SKU(Stock Keeping Unit)接口是电商API接口中的一种,专门用于获取商品的SKU信息。SKU是库存量单位,用于区分同一商品的不同规格、颜色、尺寸等属性。通过商品SKU接口,开发者可以获取商品的SKU列表、SKU属性、库存数量等详细信息。
|
3月前
|
机器学习/深度学习 算法 API
机器学习入门(五):KNN概述 | K 近邻算法 API,K值选择问题
机器学习入门(五):KNN概述 | K 近邻算法 API,K值选择问题
|
4月前
|
SQL 存储 Java
原生JDBC简单实现Mybatis核心功能
本文介绍了在Vertx项目中使用Tdengine时,因缺乏异步JDBC驱动而采用同步驱动结合`vertx.executeBlocking`实现异步查询的方法。文中详细描述了自行开发的一个简易JDBC工具,该工具实现了SQL参数绑定与返回值映射至实体类的功能,简化了原生JDBC的繁琐操作。通过具体示例展示了其实现过程及代码细节,并与原生JDBC进行了对比,突显了其便捷性和实用性。
|
4月前
|
JSON 缓存 API
淘系商品详情API接口概述,API文档说明
在成长的路上,我们都是同行者。这篇关于API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦! 淘宝API接口文档是淘宝开放平台为开发者提供的一套详细的技术规范和使用指南,旨在帮助开发者通过API接口与淘宝平台进行交互,获取商品详情等数据。以下是对淘宝商品详情数据解析的详细说明:
|
4月前
|
存储 SQL 监控
5-6|jdbc连接池
5-6|jdbc连接池
|
5月前
|
存储 JavaScript 前端开发
探索React状态管理:Redux的严格与功能、MobX的简洁与直观、Context API的原生与易用——详细对比及应用案例分析
【8月更文挑战第31天】在React开发中,状态管理对于构建大型应用至关重要。本文将探讨三种主流状态管理方案:Redux、MobX和Context API。Redux采用单一存储模型,提供预测性状态更新;MobX利用装饰器语法,使状态修改更直观;Context API则允许跨组件状态共享,无需第三方库。每种方案各具特色,适用于不同场景,选择合适的工具能让React应用更加高效有序。
113 0
|
4月前
|
负载均衡 API 数据安全/隐私保护
Zookeeper的客户端-原生的API
Zookeeper的客户端-原生的API
|
5月前
|
存储 算法 Oracle
19 Java8概述(Java8概述+lambda表达式+函数式接口+方法引用+Stream+新时间API)
19 Java8概述(Java8概述+lambda表达式+函数式接口+方法引用+Stream+新时间API)
78 8

热门文章

最新文章