JavaWeb:jdbc(详细讲解)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: JDBC,即 Java Database Connectivity,是 Java 语言操作关系型数据库的标准 API。通过 JDBC API,Java 应用程序可以连接到不同的数据库,执行 SQL 语句,读写数据等操作

1、jdbc简介

什么是jdbc

  • Java Data Base Connectivity:java数据库连接

jdbc作用

  • 通过jdbc可以让java程序操作数据库

jdbc的本质

  • 官方定义的一套操作所有关系型数据库的规则,即接口(API)
  • 各个数据库厂商去实现这个接口,提供数据库驱动jar包
  • 我们可以使用这套接口编程,真正执行的代码时驱动jar包中的实现类

jdbc的好处

  1. 我们只需要会调用jdbc接口中的方法即可,使用简单
  2. 使用同一套java代码,进行少量的修改就可以访问其他jdbc支持的数据库了

2、jdbc API介绍

jdbc四个核心对象

对象 说明
DriverManager 用于注册驱动
Connection 表示数据库的连接
Statement 执行SQL语句对象
ResultSet 结果集或一张虚拟表

jdbc使用步骤

  1. 注册驱动
  2. 获取数据库连接
  3. 获取执行SQL语句对象
  4. 执行SQL语句并返回结果
  5. 处理结果
  6. 释放资源

3、jdbc注册驱动

在使用jdbc之前我们需要导入jar包

image-20231030164453007

注册驱动API

java.sql.DriverManager类用于注册驱动,提供如下方法注册驱动

static void registerDriver(Driver driver) 向DriverManager注册给定驱动

代码示例:

    public static void main(String[] args) throws SQLException {
   
   
        //1、注册驱动
        DriverManager.registerDriver(new com.mysql.jdbc.Driver());
    }

注意:

  1. MySQL5之后的驱动包,可以省略注册驱动的步骤
  2. 自动加载jar包中META-INF/services/java.sql.Dreiver文件中的驱动类

4、Connection连接

Connection介绍

表示Java程序与数据库之间的连接,只有拿到Connection才能操作数据库

DriverManager类中的静态方法 描述
static Connection getConnection(String url, String user, String password) 连接到给定数据库URL,并返回连接

==参数说明:==

  1. String url:连接数据库的url,用于说明连接数据库的位置
  2. String user:数据库的账号
  3. String password:数据库的密码

连接数据库的URL地址格式:协议名:子协议://服务器名或IP地址:端口号/数据库名

以MySQL来写:

/**
* 1、协议名:jdbc
* 2、子协议:mysql
* 3、服务器名(本地):localhost
* 4、端口号:3306
* 5、数据库名:db1
**/
jdbc:mysql://localhost:3306/db1

获取Connection对象

public class Main {
   
   
    public static void main(String[] args) throws SQLException {
   
   
        //1、注册驱动
        DriverManager.registerDriver(new com.mysql.jdbc.Driver());

        //2、获取数据库连接
        Connection cn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1?useSSL=false", "root", "123456");
    }
}

5、Statement对象

获取Statement对象

在java.sql.Connection接口有如下方法获取到Statement对象

Statement createStatement()
创建一个Statement对象来将SQL语句发送到数据库

案例代码

public class Main {
   
   
    public static void main(String[] args) throws SQLException {
   
   
        //1、注册驱动
        DriverManager.registerDriver(new com.mysql.jdbc.Driver());

        //2、获取数据库连接
        Connection cn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1?useSSL=false", "root", "123456");

        //3、获取运送SQL的对象
        Statement state = cn.createStatement();
    }
}

6、JDBC实现对单表数据增删改操作

准备数据

CREATE TABLE USER (
  id INT AUTO_INCREMENT PRIMARY KEY,
  NAME VARCHAR(50),
  PASSWORD VARCHAR(50)
);

INSERT  INTO `user` VALUES
(NULL,'admin','123'),
(NULL,'test','123'),
(NULL,'gm','123');

CREATE DATABASE day17;

INSERT INTO USER VALUES(NULL,'weipeng','123');
6.1、使用Statement对象来执行SQL语句

API介绍

API 说明
ResultSet executeQuery(String sql) 用于执行查询语句,返回查询到的结果集合
int executeUpdate(String sql) 用于执行除查询外的SQL;返回影响的行数

==代码案例:==

public class demo01 {
   
   
    public static void main(String[] args) throws SQLException {
   
   
        /**
         * 1、注册驱动
         * 2、获取Connection连接
         * 3、执行Statement
         * 4、执行sql语句
         * 5、处理结果
         * 6、释放资源
         */
        //1、注册驱动
        DriverManager.registerDriver(new Driver());
        //2、获取Connection连接
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo?useSSL=false", "root", "123456");
        //执行Statement
        Statement statement = connection.createStatement();
        //定义sql语句
        String sql = "INSERT INTO USER VALUES(NUll,'xiao ','123');";
        //4、执行sql语句,返回影响函数
        int row = statement.executeUpdate(sql);
        System.out.println(row);

        //5、关闭资源
        statement.close();
        connection.close();
    }

}
6.2、ResultSet查询数据库

ResultSet原理

ResultSet用于保存执行查询SQL语句的结果,我们不能一次性取出所有的数据,需要一行一行的取出。

ResultSet内部有一个指针,记录获取到哪行数据

获取查询结果

  • boolean next() 将光标从当前位置向前移动一行,判断当前行是否有效

    • 返回值

      true :有效行,当前行有数据

      false:无效行,当前行没有数据

    • get(参数):获取数据

      数据类型:如 int getInt(参数);String getString(参数)

    • 参数: String 列的名称

案例代码

public class demo02 {
   
   
    public static void main(String[] args) throws Exception {
   
   
        // 1、注册驱动
        DriverManager.registerDriver(new Driver());

        // 2、创建连接
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo?useSSL=false"
                , "root", "123456");

        // 3、获取Statement对象
        Statement statement = connection.createStatement();

        //编写SQL语句
        String sql = "select * from user;";

        //执行sql
        ResultSet resultSet = statement.executeQuery(sql);
        //循环输出结果集合
        while (resultSet.next()){
   
   
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String password = resultSet.getString("password");

            System.out.println("id="+ id + ",name=" + name + ",password="+ password);
        }

        //关闭资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}
6.3、查询结果封装对象

对象关系映射介绍

  • 表 ----> 类
  • 字段 ----> 成员变量
  • 一条记录 ----> 一个对象

案例

  • 先创建一个与数据库一一对应的实体类
  • 再查询数据并进行封装

案例代码

  • 实体类(字段要与mysql表一一对应,自行添加构造方法)
public class user {
   
   
    private int id;
    private String name;
    private String password;
}
  • 测试类
public class demo03 {
   
   
    public static void main(String[] args) throws SQLException {
   
   
        //1、注册驱动
        DriverManager.registerDriver(new Driver());

        //2、创建连接
        Connection connection = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/demo?useSSL=false", "root", "123456");

        //3、获取Statement对象
        Statement statement = connection.createStatement();

        //4、编写SQL语句
        String sql = "select * from user;";

        //5、执行SQL
        ResultSet resultSet = statement.executeQuery(sql);

        //6、创建集合
        ArrayList<user> list = new ArrayList<>();

        //7、循环遍历结果
        while (resultSet.next()){
   
   
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String password = resultSet.getString("password");
            user newUser = new user(id, name, password);
            list.add(newUser);
        }

        //8、遍历集合
        for (user user : list) {
   
   
            System.out.println(user);
        }

        //9、关闭资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

7、JDBC中使用事务

数据准备

create table account(
    id int primary key auto_increment,
    name varchar(10),
    balance double
);

insert into account(name, balance) values ('张三',1000),('李四',1000);

JDBC事务API

Connection接口中与事务有关的方法

方法名 说明
void setAutoCommit(boolean autoCommit) false:开始事务,true:关闭事务
void commit() 提交事务
void rollback 回滚事务

使用步骤:

  1. 注册驱动
  2. 获取连接
  3. 开启事务
  4. 获取到Statement
  5. Statement执行SQL
  6. 提交或回滚事务
  7. 关闭资源

案例代码

public class demo04 {
   
   
    public static void main(String[] args) {
   
   
        Connection connection = null;
        Statement statement = null;
        try {
   
   
            //1、注册驱动
            DriverManager.registerDriver(new Driver());
            //2、获取连接
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo?useSSL=false",
                    "root", "123456");

            //3、开启事务
            connection.setAutoCommit(false);

            //4、获取到Statement
            statement = connection.createStatement();
            //5、执行sql,张三借给李四500
            statement.executeUpdate("update account set balance = balance - 500 where name = '张三'");
            statement.executeUpdate("update account set balance = balance + 500 where name = '李四'");

            //6、提交事务
            connection.commit();
            System.out.println("执行成功");
        } catch (Exception e) {
   
   

            try {
   
   
                //失败回滚事务
                if (connection != null){
   
   
                    connection.rollback();
                }
                System.out.println("执行失败");
            } catch (SQLException ex) {
   
   
                throw new RuntimeException(ex);
            }

        } finally {
   
   
            //关闭资源
            try {
   
   
                if (statement != null){
   
   
                    statement.close();
                }
            } catch (Exception e) {
   
   
                throw new RuntimeException(e);
            }

            try {
   
   
                if (connection != null){
   
   
                    connection.close();
                }
            } catch (SQLException e) {
   
   
                throw new RuntimeException(e);
            }

        }

    }

8、JDBC编写登录案例

用户输入账号和密码,有则登录成功,没有则失败

public class demo05 {
   
   
    public static void main(String[] args) {
   
   
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入账号");
        String name = scanner.next();
        System.out.println("请输入密码");
        String password = scanner.next();
        pdUser(name,password);
    }

    public static void pdUser(String name,String password){
   
   
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
   
   
            DriverManager.registerDriver(new Driver());
            connection = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/demo?useSSL=false", "root", "123456");

            statement = connection.createStatement();

            resultSet = statement.executeQuery("select * from user where NAME = '" + name +"' and PASSWORD = '" + password +"';");

            if (resultSet.next()){
   
   
                System.out.println("登录成功");
            } else {
   
   
                System.out.println("账号或密码错误");
            }

        } catch (Exception e) {
   
   

            try {
   
   
                resultSet.close();
            } catch (SQLException ex) {
   
   
                throw new RuntimeException(ex);
            }

            try {
   
   
                statement.close();
            } catch (SQLException ex) {
   
   
                throw new RuntimeException(ex);
            }

            try {
   
   
                connection.close();
            } catch (SQLException ex) {
   
   
                throw new RuntimeException(ex);
            }
        }
    }
}

注意:

  • 上面的代码中,SQL语句中我们使用拼接的方式,所以存在SQL注入的风险
  • 所以我们需要去改进SQL语句
8.1、PreparedStatement使用

PreparedStatement使用格式

  • SQL语句中的参数使用?作为占位符
  • 给?占位符赋值

设置参数

  • setXxx(参数1,参数2) ;Xxx代表数据类型
  • 参数1:第几个
  • 参数2:?的实际参数

执行SQL语句

  • int executeUpdate();执行insert、update、delete语句
  • ResultSet executeQuery();执行select语句

改进登陆案例

public class demo05 {
   
   
    public static void main(String[] args) {
   
   
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入账号");
        String name = scanner.next();
        System.out.println("请输入密码");
        String password = scanner.next();
        pdUser(name,password);
    }

    public static void pdUser(String name,String password){
   
   
        Connection connection = null;
        ResultSet resultSet = null;
        PreparedStatement preparedStatement = null;

        try {
   
   
            DriverManager.registerDriver(new Driver());
            connection = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/demo?useSSL=false", "root", "123456");

            String sql = "select * from user where name = ? and password = ?;";

            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,name);
            preparedStatement.setString(2,password);

            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()){
   
   
                System.out.println("登录成功");
            } else {
   
   
                System.out.println("账号或密码错误");
            }

        } catch (Exception e) {
   
   

            try {
   
   
                if (resultSet != null){
   
   
                    resultSet.close();
                }
            } catch (SQLException ex) {
   
   
                throw new RuntimeException(ex);
            }

            try {
   
   
                preparedStatement.close();
            } catch (SQLException ex) {
   
   
                throw new RuntimeException(ex);
            }

            try {
   
   
                connection.close();
            } catch (SQLException ex) {
   
   
                throw new RuntimeException(ex);
            }
        }
    }
}

9、数据库连接池

数据库连接池简介

连接池概念:连接池就是一个容器,连接池中保存了一些数据库连接,这些连接是可以重复使用的

连接池原理:

  1. 启动数据库,连接池会初始化一些连接
  2. 当用户需要使用数据库连接,直接从连接池中取出
  3. 当用户使用完连接,会将连接重新放回连接池中

常用连接池介绍

javax.sql.DataSource表示数据库连接池,是JDK中提供的一个接口,没有具体的实现,它的实现是由连接池的厂商去实现,我们只需要学习这个工具即可

public interface DataSource{
   
   
    Connection getConmection();
}

常用的连接池实现组件:

  1. 阿里巴巴-德鲁伊Druid连接池:Druid是阿里巴巴开源平台上的项目
  2. C3P0是一个开源的连接池,目前使用它的开源项目有Hibernate,Spring等
  3. DBCP(DataBase Connection Pool)数据库连接池,是Tomcat使用的连接池组件
9.1、Druid连接池

Druid常用 的配置参数

方法名 说明
initialSize 刚启动连接池时,连接池中包含连接的数量
maxActive 连接池中最多可以放多少个连接
maxWait 获取连接时最大等待时间,单位毫秒

Druid连接池使用步骤

  1. 导入druid的jar包
  2. 设置properties文件
  3. 加载properties文件到Properties对象中
  4. 创建Druid连接池,使用配置文件中的参数
  5. 从Druid连接池中取出连接
  6. 执行SQL语句
  7. 关闭资源

案例代码

public class demo7 {
   
   
    public static void main(String[] args) throws Exception {
   
   
        //加载properties文件的内容到Properties对象中
        Properties properties = new Properties();
        FileInputStream fileInputStream = new FileInputStream("src\\druid.properties");
        properties.load(fileInputStream);

        //创建连接池,使用配置文件中的参数
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);

        //取出连接
        Connection connection = dataSource.getConnection();

        //执行sql语句
        String sql = "insert into user values(null,?,?);";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setString(1,"小陈");
        preparedStatement.setString(2,"1234");
        int row = preparedStatement.executeUpdate();
        System.out.println(row);

        //释放资源
        preparedStatement.close();
        //使用连接池之后,这里不是关闭,而是放回连接池
        connection.close();
    }
}
9.2、抽取工具类
package com.mysql.test;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class getUtils {
   
   
    public static DataSource dataSource = null;
    static {
   
   
        try {
   
   
            Properties properties = new Properties();
            FileInputStream inputStream = new FileInputStream("src\\druid.properties");
            properties.load(inputStream);

            dataSource = DruidDataSourceFactory.createDataSource(properties);

        } catch (Exception e) {
   
   
            throw new RuntimeException(e);
        }
    }

    public static Connection getConnection() throws SQLException {
   
   
        return dataSource.getConnection();
    }


}
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
10天前
|
Java 关系型数据库 MySQL
【JDBC编程】基于MySql的Java应用程序中访问数据库与交互数据的技术
【JDBC编程】基于MySql的Java应用程序中访问数据库与交互数据的技术
|
15天前
|
SQL Java 数据库连接
Java从入门到精通:2.3.1数据库编程——学习JDBC技术,掌握Java与数据库的交互
ava从入门到精通:2.3.1数据库编程——学习JDBC技术,掌握Java与数据库的交互
|
1月前
|
SQL Java 数据库连接
使用JDBC进行数据库操作:Java Web开发的数据库连接
【4月更文挑战第3天】Java Web开发中,JDBC是与数据库交互的关键,提供统一访问关系型数据库的规范。核心组件包括DriverManager、Connection、Statement和ResultSet。使用流程涉及加载驱动、建立连接、创建Statement、执行SQL及处理结果,最后关闭资源。最佳实践包括使用try-with-resources、PreparedStatement、事务管理等。在Web开发中,JDBC用于用户认证、数据持久化、检索和事务管理。虽然有ORM工具,但掌握JDBC基础仍然重要。
|
2月前
|
SQL Java 数据库连接
Java的JDBC编程
Java的JDBC编程
|
4月前
|
SQL Java 关系型数据库
Java学习—JDBC
Java学习—JDBC
|
4月前
|
druid Java 数据库连接
最新Java基础系列课程--Day16-JDBC编程(三)
最新Java基础系列课程--Day16-JDBC编程
|
4月前
|
SQL 安全 Java
最新Java基础系列课程--Day16-JDBC编程(二)
最新Java基础系列课程--Day16-JDBC编程
|
4月前
|
SQL Java 关系型数据库
最新Java基础系列课程--Day16-JDBC编程(一)
最新Java基础系列课程--Day16-JDBC编程
|
4月前
|
安全 Java
javaweb实训第四天下午——员工管理系统-JSP&Servlet&JDBC综合练习-CRUD
1.课程介绍 Servlet细节; (掌握) 员工信息相关的CRUD; (掌握) 部门信息相关的CRUD; (掌握) 2.Servlet细节 2.1.多种匹配方式
41 0
|
4月前
|
SQL Java 数据库连接
javaweb实训第四天下午——JDBC深入理解(4)
如何把dbcp.properties中的配置信息,设置到程序中去: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210602102428898.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RlYXJRaUhhbw==,size_16,color_FFFFFF,t_70) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210602102435935.pn
53 3