学点Java_Day12_JDBC

1 JDBC

面向接口编程

在JDBC里面Java这个公司只是提供了一套接口Connection、Statement、ResultSet,每个数据库厂商实现了这套接口,例如MySql公司实现了:MySql驱动程序里面实现了这套接口,Java程序员只要调用实现了这些方法就可以实现对 MySql数据库的增删改查。

2 JDBC开发步骤

2.1 加载驱动Class.forName("")

2.2 获得连接对象Connection

2.3 写sql语句

2.4 创建Statement(一艘船)

2.5 执行sql语句

复制代码
 (1) 更新类(更改了表里面数据):delete/update/insert      executeUpdate()
       返回值:int,表示你影响的行数
  (2)查询(没有改变表里面数据):  select                              executeQuery()
       返回值:结果集ResultSet

2.6 关闭连接

java 复制代码
    @Test
    public void test1() {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            //1、加载驱动Class.forName("");
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2、获得连接对象Connection
            //Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "xiangjie");
            //jdbc:mysql:协议 localhost 127.0.0.1
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/study?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2b8", "root", "xiangjie");
            //3、写sql语句
            String sql = "select id,name,age,gender from student";
            //4、创建Statement(一艘船)
            statement = connection.createStatement();

            //5、执行sql语句
            //  (1) 更新类(更改了表里面数据):delete/update/insert     executeUpdate()
            //    返回值:int,表示你影响的行数
            //  (2)查询(没有改变表里面数据):  select                  executeQuery()
            //    返回值:结果集ResultSet
            resultSet = statement.executeQuery(sql);
            List<Student> studentList = new ArrayList<>();
            while (resultSet.next()) {//判断下一行有没有,如果没有返回FALSE,如果有返回true并且指向这一行。既判断也指向,没有指向自己
                //当前resultSet指向第一行
                //while循环每遍历一次,把这一行每个字段的值拿出来,就可以封装一个Student对象
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                String gender = resultSet.getString("gender");
                //以后有框架给干  但是自己也要过一遍流程
                Student student = new Student(id, name, age, gender);
                System.out.println(student);
                studentList.add(student);
            }

            //6、关闭连接  见finally

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            //6、关闭连接
            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);
                }
            }
        }
    }

3 JDBC接口核心的API

|- DriverManager类: 驱动管理器类,用于管理所有注册的驱动程序

       |-registerDriver(driver) : 注册驱动类对象

       |-Connection getConnection(url,user,password); 获取连接对象

|- Connection接口: 表示java程序和数据库的连接对象。

       |- Statement createStatement() : 创建Statement对象

       |- PreparedStatement prepareStatement(String sql) 创建PreparedStatement对象

       |- CallableStatement prepareCall(String sql) 创建CallableStatement对象(调用写好的存储过程)

|- Statement接口: 用于执行静态的sql语句

       |- int executeUpdate(String sql) : 执行静态的更新sql语句

       |- ResultSet executeQuery(String sql) :执行的静态的查询sql语句

    |-PreparedStatement接口:用于执行预编译sql语句

       |- int executeUpdate() : 执行预编译的更新sql语句

       |-ResultSet executeQuery() : 执行预编译的查询sql语句

|- ResultSet接口:用于封装查询出来的数据

    |- boolean next() : 将光标移动到下一行

    |-getXX() : 获取列的值

java 复制代码
    @Test
    public void test2() {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/study?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2b8", "root", "xiangjie");
            String sql = "select id,name,age,gender from student";
            statement = connection.createStatement();
            resultSet = statement.executeQuery(sql);
            List<Student> studentList = new ArrayList<>();
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                String gender = resultSet.getString("gender");
                Student student = new Student(id, name, age, gender);
                System.out.println(student);
                studentList.add(student);
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement, resultSet);
        }
    }

4 PreparedStatement(预编译)和Statement区别

1、语法不同:

PreparedStatement可以使用预编译的sql,只需要发送一次sql语句,后面只要发送参数即可,公用一个sql语句。

Statement只能使用静态的sql。

2、效率不同:PreparedStatement使用了sql缓冲区,效率要比Statement高。

3、安全性不同:PreparedStatement可以有效的防止sql注入,而Statement不能防止sql注入。

java 复制代码
    @Test
    public void test3() {//预编译的statement
        Connection connection = null;
        //Statement statement = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            connection = JDBCUtil.getConnection();
            String sql = "select id,name,age,gender from student";
            //预编译的statement
            statement = connection.prepareStatement(sql);
            resultSet = statement.executeQuery();
            List<Student> studentList = new ArrayList<>();
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                String gender = resultSet.getString("gender");
                Student student = new Student(id, name, age, gender);
                System.out.println(student);
                studentList.add(student);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement, resultSet);
        }
    }

5 SQL注入

sql 复制代码
-- 演示Sql注入问题
CREATE TABLE users(
    id INT PRIMARY KEY AUTO_INCREMENT,
    `name` VARCHAR(10),
    `password` VARCHAR(10)
);
INSERT INTO users(`name`, `password`) VALUES('lisi',123);
SELECT * FROM users WHERE 1=1;  -- 1=1   true
SELECT * FROM users WHERE `name`='lisi' AND `password`='123';
--  zhangsan' OR 1=1 -- y 
SELECT * FROM users WHERE `name`='zhangsan' OR 1=1 -- y' AND `password`='343';
相关推荐
这是个栗子19 分钟前
前端开发中的常用工具函数(八)
开发语言·前端·javascript
凤凰院凶涛QAQ33 分钟前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
研☆香40 分钟前
为什么变量声明在赋值前也能使用?—— 深入理解 JavaScript 变量提升与作用域
开发语言·前端·javascript
右耳朵猫AI1 小时前
PHP周刊2026W28 | 安全更新、Laravel 13.18、Twig 3.28
开发语言·php·laravel
second601 小时前
第一部分:快速上手 —— 建立 C++ 基本语法与编程范式
开发语言·c++
罗政1 小时前
PDF 批量合并工具:本地 AI 自动排序、识别正文日期与合同编号
数据库·pdf·php
郝学胜-神的一滴1 小时前
算法实战:最小k个数——大顶堆的优雅解法
开发语言·数据结构·c++·python·程序人生·算法·排序算法
SelectDB1 小时前
宽表元数据膨胀怎么解?Doris Segment V3 对比 Parquet、Lance
大数据·数据库·数据分析
bksczm1 小时前
linux之线程概念和控制
linux·开发语言·c++
掘金_答案1 小时前
上线那天,一个 ConcurrentHashMap 差点送走我的 AI 客服——3 天排查 JVM 血泪史
java·后端·架构