侧边栏壁纸
  • 累计撰写 53 篇文章
  • 累计收到 5 条评论

Chapter25_JDBC

bbchen
2023-02-26 / 0 评论 / 41 阅读 / 正在检测是否收录...

JDBC

image-20221016193810576

简介

概念

  • JDBC是使用 Java 语言操作关系型数据库的一套 API
  • 全称:(Java DataBase Connectivity)Java 数据库连接

本质

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

好处

  • 各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发
  • 可随时替换底层数据库,访问数据库的Java代码基本不变

快速入门

image-20221016200245229

package com.bbedu.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");

        // 2.获取连接
        String url = "jdbc:mysql://127.0.0.1:3306/db1";
        String username = "root";
        String password = "123456";

        Connection connection = DriverManager.getConnection(url, username, password);

        // 3.定义 sql
        String sql = "UPDATE stu SET math = 100 WHERE NAME = '码云';";

        // 4.获取执行sql对象的 Statement
        Statement statement = connection.createStatement();

        // 5.执行sql
        int count = statement.executeUpdate(sql);   // 受影响的行数

        // 6.处理结果
        System.out.println(count);

        // 7.释放资源
        statement.close();
        connection.close();
    }
}

image-20221016200200617

JDBC API 详解

DriveManager

作用:

  1. 注册驱动

    image-20221016200958196

  2. 获取数据库连接

    image-20221016201014663

Connection

作用:

  1. 获取执行 SQL 的对象

    image-20221016201705557

  2. 管理事务

    image-20221016201759365

package com.bbedu.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCDemo_Connection {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 1.注册驱动
        //Class.forName("com.mysql.cj.jdbc.Driver");  // MySQL5 以后可以不写

        // 2.获取连接
        String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";
        String username = "root";
        String password = "123456";

        Connection connection = DriverManager.getConnection(url, username, password);

        // 3.定义 sql
        String sql1 = "UPDATE stu SET english = 100 WHERE id = '1';";
        String sql2 = "UPDATE stu SET english = 100 WHERE id = '2';";

        // 4.获取执行sql对象的 Statement
        Statement statement = connection.createStatement();

        try {
            // 开启事务
            connection.setAutoCommit(false);
            // 执行
            int count1 = statement.executeUpdate(sql1);   // 受影响的行数
            System.out.println(count1);
            int i = 3/0;
            int count2 = statement.executeUpdate(sql2);   // 受影响的行数
            System.out.println(count2);
            // 提交事务
            connection.commit();
        } catch (Exception e) {
            // 回滚事务
            connection.rollback();
            e.printStackTrace();
        }

        // 7.释放资源
        statement.close();
        connection.close();
    }
}

Statement

执行 SQL 语句

image-20221016202721372

ResultSet

image-20221016212615812

package com.bbedu.jdbc;

import java.sql.*;

public class JDBCDemo_ResultSet {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 1.注册驱动
        //Class.forName("com.mysql.cj.jdbc.Driver");  // MySQL5 以后可以不写

        // 2.获取连接
        String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";
        String username = "root";
        String password = "123456";

        Connection connection = DriverManager.getConnection(url, username, password);

        // 3.定义SQL
        String sql = "select * from stu;";

        // 4.获取执行对象
        Statement statement = connection.createStatement();

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

        // 6.遍历
        while (resultSet.next()){
//            int id = resultSet.getInt(1);
//            String name = resultSet.getString(2);
//            double math = resultSet.getDouble(6);
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            double math = resultSet.getDouble("math");

            System.out.println(id + " " +  name + " " + math);

            System.out.println("-----------------");
        }

        // 7.释放
        resultSet.close();
        statement.close();
        connection.close();
    }
}

练习

image-20221016214337354

@Test
public void testResultSet2() throws SQLException {
    // 1.注册驱动
    //Class.forName("com.mysql.cj.jdbc.Driver");  // MySQL5 以后可以不写

    // 2.获取连接
    String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";
    String username = "root";
    String password = "123456";

    Connection connection = DriverManager.getConnection(url, username, password);

    // 3.定义SQL
    String sql = "select * from stu;";

    // 4.获取执行对象
    Statement statement = connection.createStatement();

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

    // 创建集合
    ArrayList<Account> list = new ArrayList<>();

    // 6.遍历
    while (resultSet.next()){
        Account account = new Account();
        int id = resultSet.getInt("id");
        String name = resultSet.getString("name");
        double math = resultSet.getDouble("math");

        account.setId(id);
        account.setName(name);
        account.setMath(math);

        list.add(account);
    }

    System.out.println(list);

    // 7.释放
    resultSet.close();
    statement.close();
    connection.close();
}

PreparedStatement

作用:

预编译 SQL 语句并执行,预防 SQL 注入问题

SQL 注入

SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。

@Test
public void testInsert() throws Exception{
    // 1.注册驱动
    //Class.forName("com.mysql.cj.jdbc.Driver");  // MySQL5 以后可以不写

    // 2.获取连接
    String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";
    String username = "root";
    String password = "123456";

    Connection connection = DriverManager.getConnection(url, username, password);

    // 接收用户输入 用户名和密码
    String name = "zhangsan";
    String pwd = "' or '1' = '1";

    String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"';";
    System.out.println(sql);

    Statement statement = connection.createStatement();

    ResultSet resultSet = statement.executeQuery(sql);

    // 判断登录是否成功
    if(resultSet.next()){
        System.out.println("登陆成功");
    }else {
        System.out.println("登陆失败");
    }


    // 7.释放资源
    resultSet.close();
    statement.close();
    connection.close();
}

image-20221016230559016

package com.bbedu.jdbc;

import org.junit.jupiter.api.Test;

import java.sql.*;

public class JDBCDemo_PreparedStatement {
    @Test
    public void testPreparedStatement() throws Exception{
        // 1.注册驱动
        //Class.forName("com.mysql.cj.jdbc.Driver");  // MySQL5 以后可以不写

        // 2.获取连接
        String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";
        String username = "root";
        String password = "123456";

        Connection connection = DriverManager.getConnection(url, username, password);

        // 接收用户输入 用户名和密码
        String name = "zhangsan";
        String pwd = "' or '1' = '1";

        String sql = "select * from tb_user where username = ? and password = ?";

        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        preparedStatement.setString(1, name);
        preparedStatement.setString(2, pwd);

        ResultSet resultSet = preparedStatement.executeQuery();

        //判断登录是否成功
        if(resultSet.next()){
            System.out.println("登陆成功");
        }else {
            System.out.println("登陆失败");
        }


        // 7.释放资源
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }
}

原理

image-20221016234640534

数据库连接池

image-20221016234805431

实现

image-20221017103400124

package com.bbedu.druid;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;

public class DruidDemo {
    public static void main(String[] args) throws Exception {
        // 导入jar包

        // 定义配置文件

        // 加载资源对象
        Properties prop = new Properties();
        prop.load(new FileInputStream("src/druid.properties"));

        // 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

        // 获取数据库连接
        Connection connection = dataSource.getConnection();

        System.out.println(connection);

        // System.out.println(System.getProperty("user.dir"));
    }
}

练习

完成商品品牌数据的增删改查操作

环境准备

  • 数据库表 tb_brand
  • 实体类
  • 测试用例
package com.bbedu.example;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.bbedu.pojo.Brand;
import org.junit.jupiter.api.Test;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Properties;

/**
 * 品牌数据的增删改查
 */
public class BrandTest {

    /**
     * 查询所有
     * SQL: select * from tb_brand;
     * 参数: 不需要
     * 结果: List<Brand>
     */

    @Test
    public void testSelectAll() throws Exception {
        // 导入jar包
        // 定义配置文件
        // 加载资源对象
        Properties prop = new Properties();
        prop.load(new FileInputStream("src/druid.properties"));

        // 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

        // 获取数据库连接
        Connection conn = dataSource.getConnection();

        // 定义 SQL
        String sql = "select * from tb_brand;";

        // 获取对象
        PreparedStatement preparedStatement = conn.prepareStatement(sql);

        // 执行SQL
        ResultSet rs = preparedStatement.executeQuery();

        ArrayList<Brand> brands = new ArrayList<>();
        // 处理结果
        while (rs.next()) {
            // 获取数据
            int id = rs.getInt("id");
            String brandName = rs.getString("brand_name");
            String companyName = rs.getString("company_name");
            int ordered = rs.getInt("ordered");
            String description = rs.getString("description");
            int status = rs.getInt("status");
            // 封装 Brand 对象
            Brand brand = new Brand();
            brand.setId(id);
            brand.setBrandName(brandName);
            brand.setCompanyName(companyName);
            brand.setOrdered(ordered);
            brand.setDescription(description);
            brand.setStatus(status);
            // 装载集合
            brands.add(brand);
        }

        System.out.println(brands);
        // 释放资源
        rs.close();
        preparedStatement.close();
        conn.close();
    }


    /**
     * 添加
     *
     * @throws Exception SQL:INSERT INTO tb_brand (brand_name, company_name, ordered, DESCRIPTION, STATUS) VALUES (?, ?, ?, ?, ?);
     *                   <p>
     *                   参数:需要,除 id 外所有参数信息
     *                   结果 boolean
     */
    @Test
    public void testAdd() throws Exception {
        // 接收参数
        String brandName = "香飘飘";
        String companyName = "香飘飘公司";
        int ordered = 1;
        String description = "一年售出三亿杯";
        int status = 1;


        // 导入jar包
        // 定义配置文件
        // 加载资源对象
        Properties prop = new Properties();
        prop.load(new FileInputStream("src/druid.properties"));

        // 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

        // 获取数据库连接
        Connection conn = dataSource.getConnection();

        // 定义 SQL
        String sql = "INSERT INTO tb_brand (brand_name, company_name, ordered, DESCRIPTION, STATUS) VALUES (?, ?, ?, ?, ?);";

        // 获取对象
        PreparedStatement pstmt = conn.prepareStatement(sql);

        // 设置参数
        pstmt.setString(1, brandName);
        pstmt.setString(2, companyName);
        pstmt.setInt(3, ordered);
        pstmt.setString(4, description);
        pstmt.setInt(5, status);

        // 执行SQL
        int count = pstmt.executeUpdate();  // 影响的行数

        // 处理结果
        System.out.println(count > 0);

        // 释放资源
        pstmt.close();
        conn.close();
    }

    /**
     * 测试修改
     *
     * @throws Exception SQL: update tb_brand set brand_name=?, company_name=?, ordered=?, description=?, status=? where id=?;
     *                   参数: 所有参数,包括 id
     *                   结果: boolean
     */

    @Test
    public void testUpdate() throws Exception {
        // 接收参数
        String brandName = "香飘飘";
        String companyName = "香飘飘股份有限公司";
        int ordered = 1000;
        String description = "一年售出三亿杯,绕地球三圈";
        int status = 1;
        int id = 5;


        // 导入jar包
        // 定义配置文件
        // 加载资源对象
        Properties prop = new Properties();
        prop.load(new FileInputStream("src/druid.properties"));

        // 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

        // 获取数据库连接
        Connection conn = dataSource.getConnection();

        // 定义 SQL
        String sql = "update tb_brand " + "set brand_name=?, " + "company_name=?, " + "ordered=?, " + "description=?, " + "status=? " + "where id=?;";

        // 获取对象
        PreparedStatement pstmt = conn.prepareStatement(sql);

        // 设置参数
        pstmt.setString(1, brandName);
        pstmt.setString(2, companyName);
        pstmt.setInt(3, ordered);
        pstmt.setString(4, description);
        pstmt.setInt(5, status);
        pstmt.setInt(6, id);

        // 执行SQL
        int count = pstmt.executeUpdate();  // 影响的行数

        // 处理结果
        System.out.println(count > 0);

        // 释放资源
        pstmt.close();
        conn.close();
    }

    /**
     * 删除
     *
     * @throws Exception SQL: delete from tb_brand where id = ?
     *                   参数: id
     *                   返回: boolean
     */

    @Test
    public void testDelete() throws Exception {
        // 接收参数
        int id = 5;

        // 导入jar包
        // 定义配置文件
        // 加载资源对象
        Properties prop = new Properties();
        prop.load(new FileInputStream("src/druid.properties"));

        // 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

        // 获取数据库连接
        Connection conn = dataSource.getConnection();

        // 定义 SQL
        String sql = "delete from tb_brand where id = ?";

        // 获取对象
        PreparedStatement pstmt = conn.prepareStatement(sql);

        // 设置参数
        pstmt.setInt(1, id);

        // 执行SQL
        int count = pstmt.executeUpdate();  // 影响的行数

        // 处理结果
        System.out.println(count > 0);

        // 释放资源
        pstmt.close();
        conn.close();
    }
}
0

评论

博主关闭了所有页面的评论