详解JDBC各个对象

文章目录

    • DriverManager
    • Connection
    • Statement
    • PreparedStatement
    • ResultSet
    • 案例
      • 案例一:JDBC控制事务
      • 案例二:SQL 注入错误演示

DriverManager

  • 概述:DriverManager 是驱动管理类

  • 作用

    • 获取数据库连接
    // 返回数据库连接的对象,url 是指定连接路径,user 是数据库用户名 password 是数据库密码
    static Connection getConnection(String url , String user , String password);
    
    • url 语法
    jdbc:mysql://IP地址(域名):端口号/数据库名称
    

    如果连接的是本机 MySQL 服务器,并且端口号默认则 url简写为:jdbc:mysql:///数据库名称>

  • 示例代码

    // 1、获取数据库连接对象-自行更换数据库用户名和密码
    Connection con = DriverManager.getConnection("jdbc:mysql:///test","root","root");
    

Connection

  • 概述:Connection 是数据库连接类

  • 作用

    • 获取执行 SQL 的对象
    方法作用
    Statement createStatement();返回执行 SQL 对象
    PreparedStatement prepareStatement(String sql);返回执行 SQL 对象,和上述对象有区别
    • 管理事务
    方法作用注意事项
    setAutoCommit(boolean autoCommit);开启事务方法参数设置为 false ,即开启事务,反之
    commit();提交事务事务执行中未出现错误,执行提交
    rollback();回滚事务事务执行中出现错误,执行回滚
  • 示例代码(这里只为演示,并无实际效果,具体看后续案例)

    // 1、获取数据库连接对象
    Connection con = DriverManager.getConnection("jdbc:mysql:///test","root","root");
    // 2、获取执行 SQL 对象
    Statement st = con.createStatement();
    // ? 后续会讲,看下去
    PreparedStatement pst = con.prepareStatement("SELECT * FROM account WHERE id = ?");// 1、开启事务
    con.setAutoCommit(false);
    // 2、提交事务
    con.commit();
    // 3、回滚事务
    con.rollback();
    

Statement

  • 概述:执行 SQL 的对象

  • 常用方法

    方法作用
    boolean execute(String sql);可以执行任意的 SQL 语句
    int executeUpdate(String sql);执行 DML、DDL语句,返回值:影响的行数,>0 则代表执行成功
    ResultSet executeQuery(String sql);执行 DQL 查询语句
  • 示例代码

    • 数据库代码
    -- 创建一个数据库
    CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8;
    -- 使用数据库
    USE test;
    -- 创建一个账户表
    CREATE TABLE account(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20),balance DOUBLE
    );
    -- 向账户表中添加数据
    INSERT INTO account(NAME , balance) VALUES('张三',1000),('李四',1000);-- 查询账户表
    SELECT * FROM account;
    
    • Java 代码
    public class Test1 {public static void main(String[] args) throws ClassNotFoundException, SQLException {// 1、注册驱动Class.forName("com.mysql.cj.jdbc.Driver");// 2、获取数据库连接对象Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");// 3、获取执行 SQL 对象Statement st = con.createStatement();// 4、定义 SQL 语句String sql1 = "SELECT * FROM account WHERE id = 2";String sql2 = "UPDATE account SET balance = balance - 500 WHERE id = 1";// 5、执行 SQL 语句boolean flag = st.execute(sql1);int lineNum = st.executeUpdate(sql2);ResultSet rs = st.executeQuery(sql1);// 6、输出结果System.out.println(flag + " " + lineNum);// 输出 ResultSet 结果集结果while(rs.next()){int id = rs.getInt(1);String name = rs.getString("name");double balance = rs.getDouble(3);System.out.println(id + "---" + name + "---" + balance);}// 7、释放资源st.close();con.close();}
    }
    

    运行结果:

    true 1

    2—李四—1000.0


PreparedStatement

  • 概述:执行 SQL 的对象(可以防止 SQL 注入)

    • 作用:PreparedStatement 可以防止 SQL 注入,并且效率更高
  • SQL 注入!!!

    • 问题:在拼接 SQL 时候,有一些 SQL 特殊的关键字参与字符串的拼接,会造成安全性问题?(在案例中演示什么问题)
    • 解决此问题:使用 PreparedStatement 对象来解决,预编译的 SQL 参数使用>作为占位符
  • 常用方法

    方法作用参数
    setXxx(参数1,参数2)给 ?赋值,Xxx代表数据类型参数1:?的位置编号(从1开始)
    参数2:赋给?的值
  • 示例代码(此对象如何使用)

    • 数据库代码
    -- 创建一个数据库
    CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8;
    -- 使用数据库
    USE test;
    -- 创建一个账户表
    CREATE TABLE account(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20),balance DOUBLE
    );
    -- 向账户表中添加数据
    INSERT INTO account(NAME , balance) VALUES('张三',1000),('李四',1000);-- 查询账户表
    SELECT * FROM account;
    
    • Java 代码
    public class Test2 {public static void main(String[] args) throws ClassNotFoundException, SQLException {// 1、注册驱动Class.forName("com.mysql.cj.jdbc.Driver");// 2、获取数据库连接对象Connection con = DriverManager.getConnection("jdbc:mysql:///test", "root", "root");// 3、定义 SQL 语句,这里使用占位符 ?String sql = "UPDATE account SET balance = balance - ? WHERE id = ?";// 4、创建 执行 SQL 对象PreparedStatement pst = con.prepareStatement(sql);// 5、设置参数,给第一个?设置值为 500 给第二个?设置值为 1pst.setInt(1,500);pst.setInt(2,1);// 6、执行 SQL 语句int lineNum = pst.executeUpdate();// 7、输出结果System.out.println(lineNum);// 8、释放资源pst.close();con.close();;}
    }
    

    运行后,可看到控制台输出结果 1 ,数据库中编号 1 的balance 变成了 500


ResultSet

  • 概述:结果集对象,用来封装查询结果的

  • 常用方法

    方法作用注意事项
    boolean next();游标向下移动一行,判断当前行是否有数据有数据返回 true 无数据返回 false
    getXxx(参数);获取数据Xxx:代表数据类型
    参数是 int 类型,代表列的编号(从1开始),
    参数是 String 类型,代表列名称
  • 代码示例

    ResultSet rs = st.executeQuery(sql1);
    //循环判断游标是否是最后一行末尾。
    while(rs.next()){//获取数据int id = rs.getInt(1);String name = rs.getString("name");double balance = rs.getDouble(3);System.out.println(id + "---" + name + "---" + balance);
    }
    

案例

案例一:JDBC控制事务

  • 概述:事务,一个包含多个步骤的业务操作。如果这个业务操作被事务管理,多个步骤要么同时成功,要么同时失败。

  • 操作事务的三个步骤

    • 开始事务
    • 提交事务
    • 回滚事务
  • 代码示例(这里有很多的写法并不严谨,只是为了更好的演示效果,数据库还是上述步骤中用到过的)

    public class Test3 {public static void main(String[] args) {// 这里为了省事,简单这样写String url = "jdbc:mysql://localhost:3306/test";String user = "root";String password = "root";Connection con = null;PreparedStatement pst1 = null;PreparedStatement pst2 = null;try {// 1、注册驱动Class.forName("com.mysql.cj.jdbc.Driver");// 2、获取数据库连接con = DriverManager.getConnection(url,user,password);// 3、开启事务con.setAutoCommit(false);// 4、定义 SQL 语句,sql1 张三-500 sql2 李四+500String sql1 = "UPDATE account SET balance = balance - ? WHERE id = ?";String sql2 = "UPDATE account SET balance = balance + ? WHERE id = ?";// 5、获取执行 SQL 对象pst1 = con.prepareStatement(sql1);pst2 = con.prepareStatement(sql2);// 6、设置 占位符值pst1.setInt(1,500);pst1.setInt(2,1);pst2.setInt(1,500);pst2.setInt(2,2);// 7、执行 SQLpst1.executeUpdate();// 手动制造异常,可以运行次后,看下数据库的数字,再注释掉这行再运行,再看数据库数字int i = 3/0;pst2.executeUpdate();// 提交事务,因为遇见异常,所以这步代码并不执行con.commit();} catch (Exception e) {try{if(con != null){// 事务回滚,当 con 不为空的时候,才回滚con.rollback();}}catch (SQLException e1){e1.printStackTrace();}e.printStackTrace();} finally {try {// 释放资源pst1.close();pst2.close();con.close();} catch (SQLException e) {e.printStackTrace();}}}
    }
    

案例二:SQL 注入错误演示

  • 概述:SQL 语句拼接时,用一些特殊的关键字参与字符串拼接,会造成安全性问题

  • 代码示例

    • 数据库代码
    -- 创建数据库
    CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8;-- 创建 user 表
    CREATE TABLE USER(username VARCHAR(20),		-- 用户名PASSWORD VARCHAR(20)		-- 密码
    );-- 插入数据
    INSERT INTO USER VALUES('lisi',"a'or'a'='a");-- 查询数据,可发现下边 3行都会显示此条信息,这样错误太明显了,这是为什么?
    SELECT * FROM USER WHERE username = 'lisi' AND PASSWORD = 'a'OR'a'='a';SELECT * FROM USER WHERE username = 'fhdsjkf' AND PASSWORD = 'a' OR 'a' = 'a';SELECT * FROM USER WHERE username = 'a' AND PASSWORD = 'a' OR 'a' = 'a';
    

    注意:为什么上述3行都能显示呢?看下边两个框,可以知道,查询语句的条件有两个,中间又用 OR ,根据或的特性,只要满足其一即可,第二个红框,很明显一直是对的,所以就能查询出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/413799.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

资料收集:储能bms架构

储能系统保护与控制之电池管理系统(BMS) 重点储能BMS企业汇总 储能BMS分为三级架构: 第一级:每个电池插箱包含1并48串电池模组,插箱配置1个BMU从控模块,用于对该电池组的电压、温度等信息的采集和上传。 …

学习Spring的第五天(Bean的依赖注入)

Bean的依赖注入有两种方式: 一 . 常规Bean的依赖注入 很简单,不过多赘述了,注意ref: 是构造函数或set方法的参数,一般为对象, value: 是构造函数或set方法的参数,一般为值. 看下图 1.1 下面来演示一下集合数据类型的关于Bean的依赖注入 1.1.1这是List的注入(演示泛型为Strin…

设计 Mint.com

1. 梳理 User Case 和 约束 Use cases 作用域内的Use Case User 连接到 financial accountService 从 Account 中提取 transactions 日常 Update整理 transaction 所有的手动目录由 User 覆盖没有自动化的重排机制 - 通过目录分析月消费 Service 推荐 budget 允许 user 去…

提升开发效率,Fiddler Everywhere for Mac助您解决网络调试难题

在现代软件开发中,网络调试是一个不可或缺的环节。无论是前端开发还是后端开发,我们经常需要对网络请求进行监控和调试,以便及时发现并解决问题。而Fiddler Everywhere for Mac作为一款强大的网络调试工具,能够帮助开发者提升工作…

Backtrader 文档学习-Indicators混合时间框架

Backtrader 文档学习-Indicators混合时间周期 1.不同时间周期 如果数据源在Cerebro引擎中具有不同的时间范围和不同的长度,指示器将会终止。 比如:data0是日线,data1是月线 。 pivotpoint btind.PivotPoint(self.data1) sellsignal self…

快慢指针-Floyd判圈算法

对于环形链表是否存在环的做法,普通算法可以通过额外Hash数组来存储链表元素,直到Hash数组中出现重复元素。时间复杂度O(n),空间复杂度O(n) Floyd判圈算法通过利用快慢指针的移动来实现,时间复杂度O(n)&am…

54 C++ 多线程 条件变量 condition_variable,wait(),notify_one()

一 前提:之前代码的缺陷 在前面我们使用两个线程 ,一个线程读,一个线程写来完成对于共享数据访问。 我们把这个代码 先放在这里,方便回忆,然后说明代码可能存在的问题,然后改动。 class Teacher174 { pri…

Educational Codeforces Round 161 (Rated for Div. 2)

Educational Codeforces Round 161 (Rated for Div. 2) Educational Codeforces Round 161 (Rated for Div. 2) A. Tricky Template 题意:开始没看懂。。。给出长度均为n的三个字符串abc,字符串s与模板t匹配的条件为:当模板位置字符为小写…

Spring Boot自动配置原理

1.SpringBootApplication注解 springboot是基于spring的新型的轻量级框架,最厉害的地方当属**自动配置。**那我们就可以根据启动流程和相关原理来看看,如何实现传奇的自动配置 SpringBootApplication//标注在某个类上,表示这个类是SpringBo…

域环境权限提升

Windows系统配置错误 在Windows系统中,攻击者通常会通过系统内核溢出漏来提权,但是如果碰到无法通过系统内核溢出漏洞法国提取所在服务器权限的情况,就会系统中的配置错误来提权。Windows系统中常见哦欸之错误包括管理员凭证配置错误&#x…

【重点!!!】【背包】【回溯】518.零钱兑换II

题目 跟39.组合总数、322.零钱兑换题目很类似。 法1:背包DP,最优解法 解释如下: 0 1 2 3 4 5(背包容量)1 0 0 0 0 0 没有硬币的时候) 0 1 2 3 4 5(背包容量) 1 1 1 1 1 1 1 0 1 2 3 4 5(背包容量) 1 …

Leetcode刷题【每日n题】(3)

🎵今日诗词🎵 桃花潭水深千尺,不及汪伦送我情。 ——李白《赠汪伦》 目录 1.题目一 2.思路分析 3.代码实现 4.题目二 5.思路分析 6.代码实现 1.题目一 9. 回文数 给你一个整数 x ,如果 x 是一个回文整数,返回 tr…