JavaWeb:jdbc(详细讲解)

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 包

JavaWeb:jdbc(详细讲解)
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 文件中的驱动类
JavaWeb:jdbc(详细讲解)

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();
    }


}


原文始发于微信公众号(小林学编程):JavaWeb:jdbc(详细讲解)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/219385.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!