Java的JDBC编程

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: JDBC的介绍,常用的接口和使用等

 什么是JDBC?

JDBC,即Java Database Connectivityjava数据库连接。是一种用于执行SQL语句的Java API,它是 Java中的数据库连接规范。这个APIjava.sql.*,javax.sql.* 包中的一些类和接口组成,它为Java 开发人员操作数据库提供了一个标准的API,可以为多种关系数据库提供统一访问。

JDBC工作原理

JDBC 为多种关系数据库提供了统一访问方式,作为特定厂商数据库访问API的一种高级抽象,它主要包含一些通用的接口类。

JDBC访问数据库层次结构:

image.gif编辑

JDBC优势:

    • Java语言访问数据库操作完全面向抽象接口编程
    • 开发数据库应用不用限定在特定数据库厂商的API
    • 程序的可移植性大大增强

    JDBC常用接口和类

    JDBC API

    Java JDBC编程中对数据库的操作均使用JDK自带的API统一处理,通常与特定数据库的驱动类是完全解耦的。所以掌握Java JDBC API (位于 java.sql 包下) 即可掌握Java数据库编程。

    数据库连接Connection

    Connection接口实现类由数据库提供,获取Connection对象通常有两种方式:

      • 种是通过DriverManager(驱动管理类)的静态方法获取:
      // 加载JDBC驱动程序
      Class.forName("com.mysql.jdbc.Driver");
      // 创建数据库连接
      Connection connection = DriverManager.getConnection(url);

      image.gif

        • 种是通过DataSource(数据源)对象获取。实际应用中会使用DataSource对象。
        DataSource ds = new MysqlDataSource();
        ((MysqlDataSource) ds).setUrl("jdbc:mysql://localhost:3306/test");
        ((MysqlDataSource) ds).setUser("root");
        ((MysqlDataSource) ds).setPassword("root");
        Connection connection = ds.getConnection();

        image.gif

        以上两种方式的区别是:

          1. DriverManager类来获取的Connection连接,是无法重复利用的,每次使用完以后释放资源时,通过connection.close()都是关闭物理连接。
          2. DataSource提供连接池的支持。连接池在初始化时将创建一定数量的数据库连接,这些连接是可以复用的,每次使用完数据库连接,释放资源调用connection.close()都是将Conncetion连接对象回收。

          Statement对象

          Statement对象主要是将SQL语句发送到数据库中。JDBC API中主要提供了三种Statement对象。

          image.gif编辑

          实际开发中最常用的是PreparedStatement对象,以下对其的总结:

          image.gif编辑

          主要掌握两种执行SQL的方法:

            • executeQuery() 方法执行后返回单个结果集的,通常用于select语句
            • executeUpdate()方法返回值是一个整数,指示受影响的行数,通常用于updateinsertdelete语句

            ResultSet对象

              • ResultSet对象它被称为结果集,它代表符合SQL语句条件的所有行,并且它通过一套getXXX方法提供了对这些行中数据的访问。
              • ResultSet里的数据一行一行排列,每行有多个字段,并且有一个记录指针,指针所指的数据行叫做当前数据行,我们只能来操作当前的数据行。我们如果想要取得某一条记录,就要使用ResultSetnext()方法 ,如果我们想要得到ResultSet里的所有记录,就应该使用while循环。

              JDBC使用

              1.连接数据库

              //先定义一个数据源对象
                  private static DataSource dataSource = null;
                      //1.初始化数据源
                      MysqlDataSource mysqlDataSource = new MysqlDataSource();
                      //2.设置连接参数
                      mysqlDataSource.setURL(URL);
                      mysqlDataSource.setUser(USER);
                      mysqlDataSource.setPassword(PASSWORD);
                      //3.把构建好的Mysql数据源赋值给JDBC中的datasource
                      dataSource = mysqlDataSource;
                          //1.通过数据源获取一个数据库连接
                          connection = dataSource.getConnection();

              image.gif

              这里的URL(数据库连接字符串)为:

                • 5.7:jdbc:mysql://127.0.0.1:3306/数据库名?characterEncoding=UTF-8&useSSL=false

                       useSSL=false:是否加密;

                  • 8.0:jdbc:mysql://127.0.0.1:3306/数据库名?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai

                         serverTimezone=Asia/Shanghai:时区。

                  2.执行SQL语句

                  //接收用户输入值
                              System.out.println("请输入id:");
                              Scanner scanner = new Scanner(System.in);
                              int id = scanner.nextInt();
                              //2.定义SQL语句
                  //            String sql = "select * from student where id = " + id;
                              String sql = "select * from student where id = ?";
                              System.out.println("sql-->" + sql);
                              //3.获取statement对象
                  //            statement = connection.createStatement();
                              //获取预处理对象
                              statement = connection.prepareStatement(sql);
                              //处理占位符的值
                              statement.setInt(1,id);
                              //4.执行SQL
                              resultSet = statement.executeQuery();

                  image.gif

                  3.把查询的结果集转为JAVA对象

                  //5.解析结果集,resultSet.next()表示结果集中是否有记录
                              while (resultSet.next()) {
                                  //创建表示结果的JAVA对象
                                  Student student = new Student();
                                  //依次读取结果集中的数据斌赋值给JAVA对象
                                  student.setId(resultSet.getInt(1));
                                  student.setSn(resultSet.getInt(2));
                                  student.setName(resultSet.getString(3));
                                  student.setMail(resultSet.getString(4));
                                  //打印结果
                                  System.out.println(student);
                              }

                  image.gif

                  在完成删除和插入时:

                  // 4. 执行SQL并获取结果
                              int row = statement.executeUpdate();
                              if (row <= 0) {
                                  System.out.println("添加失败.");
                              } else {
                                  System.out.println("添加成功");
                              }

                  image.gif

                  4.释放资源

                  //依次关闭资源
                              if (resultSet != null) {
                                  try {
                                      resultSet.close();
                                  } catch (SQLException e) {
                                      throw new RuntimeException(e);
                                  }
                              }
                              if (statement != null) {
                                  try {
                                      statement.close();
                                  } catch (SQLException e) {
                                      throw new RuntimeException(e);
                                  }
                              }
                              if (connection != null) {
                                  try {
                                      connection.close();
                                  } catch (SQLException e) {
                                      throw new RuntimeException(e);
                                  }
                              }

                  image.gif

                  完整代码:

                  //先定义一个数据源对象
                      private static DataSource dataSource = null;
                      //数据库的用户名
                      private static final String USER = "root";
                      //数据库密码
                      private static final String PASSWORD = "123456";
                      //数据库连接字符串
                      private static final String URL = "jdbc:mysql://127.0.0.1:3306/java78?characterEncoding=utf-8&useSSL=false";
                      public static void main(String[] args) {
                          //1.初始化数据源
                          MysqlDataSource mysqlDataSource = new MysqlDataSource();
                          //2.设置连接参数
                          mysqlDataSource.setURL(URL);
                          mysqlDataSource.setUser(USER);
                          mysqlDataSource.setPassword(PASSWORD);
                          //3.把构建好的Mysql数据源赋值给JDBC中的datasource
                          dataSource = mysqlDataSource;
                          Connection connection = null;
                  //        Statement statement = null;
                          PreparedStatement statement = null;
                          ResultSet resultSet = null;
                          //建立数据库连接
                          try {
                              //1.通过数据源获取一个数据库连接
                              connection = dataSource.getConnection();
                              //接收用户输入值
                              System.out.println("请输入id:");
                              Scanner scanner = new Scanner(System.in);
                              int id = scanner.nextInt();
                              //2.定义SQL语句
                  //            String sql = "select * from student where id = " + id;
                              String sql = "select * from student where id = ?";
                              System.out.println("sql-->" + sql);
                              //3.获取statement对象
                  //            statement = connection.createStatement();
                              //获取预处理对象
                              statement = connection.prepareStatement(sql);
                              //处理占位符的值
                              statement.setInt(1,id);
                              //4.执行SQL
                              resultSet = statement.executeQuery();
                              //5.解析结果集,resultSet.next()表示结果集中是否有记录
                              while (resultSet.next()) {
                                  //创建表示结果的JAVA对象
                                  Student student = new Student();
                                  //依次读取结果集中的数据斌赋值给JAVA对象
                                  student.setId(resultSet.getInt(1));
                                  student.setSn(resultSet.getInt(2));
                                  student.setName(resultSet.getString(3));
                                  student.setMail(resultSet.getString(4));
                                  //打印结果
                                  System.out.println(student);
                              }
                          } catch (SQLException e) {
                              e.printStackTrace();
                          }finally {
                              //依次关闭资源
                              if (resultSet != null) {
                                  try {
                                      resultSet.close();
                                  } catch (SQLException e) {
                                      throw new RuntimeException(e);
                                  }
                              }
                              if (statement != null) {
                                  try {
                                      statement.close();
                                  } catch (SQLException e) {
                                      throw new RuntimeException(e);
                                  }
                              }
                              if (connection != null) {
                                  try {
                                      connection.close();
                                  } catch (SQLException e) {
                                      throw new RuntimeException(e);
                                  }
                              }
                          }
                      }

                  image.gif

                  当然这里还要定义一个student类,这里就不写了,大家可以根据自己的需求创建。

                  优化:

                  连接数据库和释放资源每次都是重复操作,所以我们可以将他们封装起来,每次使用时调用即可,我们每次只需处理要执行的SQL操作即可。

                  封装连接数据库和释放资源:

                  // 先定义一个数据源对象
                      private static DataSource dataSource = null;
                      // 数据库的用户名
                      private static final String USER = "root";
                      // 数据库的密码
                      private static final String PASSWORD = "123456";
                      // 数据库连接字符串
                      private static final String URL = "jdbc:mysql://127.0.0.1:3306/java78?characterEncoding=utf-8&useSSL=false";
                      static {
                          // 初始化数据源
                          MysqlDataSource mysqlDataSource = new MysqlDataSource();
                          mysqlDataSource.setURL(URL);
                          mysqlDataSource.setUser(USER);
                          mysqlDataSource.setPassword(PASSWORD);
                          dataSource = mysqlDataSource;
                      }
                      // 用private 修饰构造方法,使外部不能new 这个类的对象
                      private DBUtil() {}
                      /**
                       * 获取数据库连接
                       * @return
                       * @throws SQLException
                       */
                      public static Connection getConnection () throws SQLException {
                          return dataSource.getConnection();
                      }
                      /**
                       * 关闭对象并释放资源
                       * @param resultSet
                       * @param statement
                       * @param connection
                       */
                      public static void close (ResultSet resultSet, PreparedStatement statement, Connection connection) {
                          // 依次关闭对象,并释放资源
                          if (resultSet != null) {
                              try {
                                  resultSet.close();
                              } catch (SQLException e) {
                                  e.printStackTrace();
                              }
                          }
                          if (statement != null) {
                              try {
                                  statement.close();
                              } catch (SQLException e) {
                                  e.printStackTrace();
                              }
                          }
                          if (connection != null) {
                              try {
                                  connection.close();
                              } catch (SQLException e) {
                                  e.printStackTrace();
                              }
                          }
                      }

                  image.gif

                  示例调用封装类来实现SQL操作:

                  public static void main(String[] args) {
                          // 查询到的所有学生信息
                          List<Student> students = null;
                          Connection connection = null;
                          PreparedStatement statement = null;
                          ResultSet resultSet = null;
                          try {
                              // 1. 创建数据源并获取数据库连接
                              connection = DBUtil.getConnection();
                              // 2. 构造SQL语句
                              String sql = "select * from student";
                              // 使用SQL预处理对象处理SQL
                              statement = connection.prepareStatement(sql);
                              // 3. 执行SQL并获取结果,如果是结果集把结果集转成java对象
                              resultSet = statement.executeQuery();
                              // 遍历结果集,处理查询到数据
                              while (resultSet.next()) {
                                  // 如果List为空则创建
                                  if (students == null) {
                                      students = new ArrayList<>();
                                  }
                                  // 解析结果集并封装成Student对象
                                  Student student = new Student();
                                  student.setId(resultSet.getInt(1));
                                  student.setSn(resultSet.getInt("sn"));
                                  student.setName(resultSet.getString("name"));
                                  student.setMail(resultSet.getString(4));
                                  // 加入到集合中
                                  students.add(student);
                              }
                              // 打印结果
                              System.out.println(students);
                          } catch (SQLException e) {
                              e.printStackTrace();
                          } finally {
                              // 4. 释放资源
                              DBUtil.close(resultSet, statement, connection);
                          }
                      }

                  image.gif

                  期待各位大佬前来指点,制作不易,感谢支持。

                  相关实践学习
                  基于CentOS快速搭建LAMP环境
                  本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
                  全面了解阿里云能为你做什么
                  阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
                  相关文章
                  |
                  4天前
                  |
                  安全 Java 调度
                  深入理解Java并发编程:线程安全与性能优化
                  【5月更文挑战第12天】 在现代软件开发中,多线程编程是提升应用程序性能和响应能力的关键手段之一。特别是在Java语言中,由于其内置的跨平台线程支持,开发者可以轻松地创建和管理线程。然而,随之而来的并发问题也不容小觑。本文将探讨Java并发编程的核心概念,包括线程安全策略、锁机制以及性能优化技巧。通过实例分析与性能比较,我们旨在为读者提供一套既确保线程安全又兼顾性能的编程指导。
                  |
                  4天前
                  |
                  数据采集 安全 Java
                  Java并发编程学习12-任务取消(上)
                  【5月更文挑战第6天】本篇介绍了取消策略、线程中断、中断策略 和 响应中断的内容
                  30 4
                  Java并发编程学习12-任务取消(上)
                  |
                  1天前
                  |
                  Java
                  深入理解Java并发编程:线程池的应用与优化
                  【5月更文挑战第18天】本文将深入探讨Java并发编程中的重要概念——线程池。我们将了解线程池的基本概念,应用场景,以及如何优化线程池的性能。通过实例分析,我们将看到线程池如何提高系统性能,减少资源消耗,并提高系统的响应速度。
                  11 5
                  |
                  1天前
                  |
                  消息中间件 安全 Java
                  理解Java中的多线程编程
                  【5月更文挑战第18天】本文介绍了Java中的多线程编程,包括线程和多线程的基本概念。Java通过继承Thread类或实现Runnable接口来创建线程,此外还支持使用线程池(如ExecutorService和Executors)进行更高效的管理。多线程编程需要注意线程安全、性能优化和线程间通信,以避免数据竞争、死锁等问题,并确保程序高效运行。
                  |
                  1天前
                  |
                  安全 Java 容器
                  深入理解Java并发编程:线程安全与性能优化
                  【5月更文挑战第18天】随着多核处理器的普及,并发编程变得越来越重要。Java提供了丰富的并发编程工具,如synchronized关键字、显式锁Lock、原子类、并发容器等。本文将深入探讨Java并发编程的核心概念,包括线程安全、死锁、资源竞争等,并分享一些性能优化的技巧。
                  |
                  1天前
                  |
                  安全 Java 开发者
                  Java中的多线程编程:理解与实践
                  【5月更文挑战第18天】在现代软件开发中,多线程编程是提高程序性能和响应速度的重要手段。Java作为一种广泛使用的编程语言,其内置的多线程支持使得开发者能够轻松地实现并行处理。本文将深入探讨Java多线程的基本概念、实现方式以及常见的并发问题,并通过实例代码演示如何高效地使用多线程技术。通过阅读本文,读者将对Java多线程编程有一个全面的认识,并能够在实际开发中灵活运用。
                  |
                  1天前
                  |
                  Java 编译器
                  Java并发编程中的锁优化策略
                  【5月更文挑战第18天】在Java并发编程中,锁是一种常用的同步机制,用于保护共享资源的访问。然而,不当的锁使用可能导致性能问题和死锁风险。本文将探讨Java中锁的优化策略,包括锁粗化、锁消除、锁分离和读写锁等技术,以提高并发程序的性能和可靠性。
                  |
                  2天前
                  |
                  Java 编译器
                  Java 并发编程中的锁优化策略
                  【5月更文挑战第17天】在 Java 并发编程中,锁是一种常见的同步机制,用于保护共享资源的访问。然而,不当使用锁可能导致性能问题和死锁风险。本文将探讨 Java 中的锁优化策略,包括锁粗化、锁消除、锁降级以及读写锁等技术,以提高并发程序的性能和可靠性。
                  |
                  2天前
                  |
                  Java 编译器
                  Java并发编程中的锁优化策略
                  【5月更文挑战第17天】在Java并发编程中,锁是一种常见的同步机制,用于保护共享资源。然而,使用不当的锁可能导致性能下降和死锁等问题。本文将探讨Java中锁的优化策略,包括锁粗化、锁消除、锁排序等方法,以提高程序的性能和可靠性。
                  |
                  3天前
                  |
                  存储 关系型数据库 MySQL
                  《MySQL 入门教程》第 05 篇 账户和权限,Java高并发编程详解深入理解pdf
                  《MySQL 入门教程》第 05 篇 账户和权限,Java高并发编程详解深入理解pdf