Java - JDBC

Java - JDBC

文章目录

  • Java - JDBC
    • 引言
    • JDBC
      • 1 什么是JDBC
      • 2 MySQL数据库驱动
      • 3 JDBC开发步骤
      • 4 具体介绍

引言

思考:

当下我们如何操作数据库?

  • 使用客户端工具访问数据库,手工建立连接,输入用户名和密码登录。
  • 编写SQL语句,点击执行,查看操作结果(结果集或受影响行数)。

实际开发中,会采用上述方式吗?

  • 不会,因为操作量过大,无法保证效率和正确性。
  • 普通用户不能直接操作客户端工具。

JDBC

1 什么是JDBC

概念:

  • JDBC(Java DataBase Connectivity)Java数据库连接,SUN公司定义的一套连接数据库的规范(标准)。
  • 使用JDBC连接数据库完成CRUD操作。

核心思想:

  • JDBC中定义了访问数据库的接口,可以为多种关系型数据库提供统一的访问方式。
  • 由数据库厂商提供驱动实现类(Driver数据库驱动)。

如图:

在这里插入图片描述

2 MySQL数据库驱动

MySQL数据库驱动包:

  • mysql-connector-java-5.1.X 适用于5.X版本。
  • mysql-connector-java-8.0.X 适用于8.X版本。

JDBC API:

类型全限定名简介
classjava.sql.DriverManager管理多个数据库驱动类,提供了获取数据库连接的方法。
interfacejava.sql.Connection代表一个数据库连接。当connection不是null时,表示已连接数据库。
interfacejava.sql.Statement发送SQL语句到数据库工具。
interfacejava.sql.ResultSet保存SQL查询语句的结果数据(结果集)。
classjava.sql.SQLException处理数据库应用程序时所发生的异常。

3 JDBC开发步骤

开发六步骤:

  • 注册驱动:

  • Class.forName("com.mysql.jdbc.Driver");
    
  • 获取连接:

  • Connection conn = DriverManager.getConnection(url,name,pwd);
    
  • 创建命令对象:

  • Statement statement = conn.createStatement();
    
  • 执行SQL语句:

  • int result = statement.executeUpdate(sql);
    
  • 处理结果:

  • System.out.println(result);
    
  • 释放资源:

  • statement.close();
    conn.close();
    

4 具体介绍

1 DriverManager类

概念:

  • java.sql.DriverManager管理所有数据库的驱动,如果想要建立数据库连接需要先在java.sql.DriverManager中注册对应的驱动类,然后调用getConnection方法才能连接上数据库。

注册驱动:

  • 方法1:(推荐使用)

  • Class.forName("com.mysql.jdbc.Driver");
    
  • 方法2:(不推荐使用)

  • DriverManager.registerDriver(new Driver());
    
  • 原因: 会导致注册两次, 耦合性高;

获取连接:

String url= "jdbc:mysql://localhost:3306/mysql";//连接字符串
String user= "root";//用户名
String password = "root";//密码//jdbc:mysql	协议
//localhost 	主机名
//3306  	    端口号
//mysql		    数据库名Connection connection = DriverManager.getConnection(url, user, password);

这样连接后会出现一个警告:

Fri Jan 26 09:35:24 CST 2024 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.

这段警告信息是关于MySQL数据库SSL连接的,其翻译如下:

警告:在未验证服务器身份的情况下建立SSL连接是不推荐的。根据MySQL 5.5.45+、5.6.26+ 和 5.7.6+ 的要求,如果未设置明确选项,则必须默认建立SSL连接。为了兼容不使用SSL的现有应用程序,已将verifyServerCertificate属性设置为’false’。您需要明确通过设置useSSL=false来禁用SSL,或者设置useSSL=true并为服务器证书验证提供truststore。

简单来说,这个警告告诉你,你的MySQL连接没有使用SSL或者没有正确地验证服务器的SSL证书。为了安全起见,你应该考虑启用SSL并提供正确的证书验证,或者如果你确定不需要SSL,你可以明确禁用它。

怎么解决这个问题:

我们采用明确禁止SSL的方式:

更新 url (添加参数):

参数: ?useSSL=false&characterEncoding=utf-8
useSSL=false	明确禁止SSL
characterEncoding=utf-8		设置数据库编码为 UTF-8url="jdbc:mysql://localhost:3306/mysql?useSSL=false&characterEncoding=utf-8";

2 Connection

概念:

  • Connection接口代表与特定的数据库的连接,要对数据表中的数据进行操作,首先要获取数据库连接,Connection实现就像在应用程序中与数据库之间开通了一条渠道。
方法名说明
createStatement()创建Statement命令对象
prepareStatement(String sql)创建预编译命令对象

3 Statement

概念:

  • 获取连接对象后,可以创建Statement对象,用来执行命令。

语法: Statement stat=连接对象.createStatement();

方法名说明
execute()执行任何SQL语句,一般不用
executeUpdate()执行增删改、创建库、表等
executeQuery()执行查询,返回ResultSet结果集

4 ResultSet

概念:

  • 在执行查询SQL后,存放查询到的结果集数据。

接收结果集:

  • ResultSet rs = statement.executeQuery(sql);

注意:

  • 作用是完成了查询结果的存储功能,默认只能向前读取,不能修改.

遍历ResultSet结果集

  • ResultSet以表结构进行临时结果的存储,通过JDBC API将其中数据进行依次获取
方法名返回值类型描述
next();boolean数据行指针,每调用一次,指针向下移动一行。结果为 true,表示当前行有数据。结果为false,没有数据。
getXxx(编号);xxx代表根据列的编号顺序获得,从 1 开始。
getXxx(“列名”);xxx代表根据列名获得。推荐

**经验:**getXxx方法可以获取的类型有:基本数据类型、引用数据类型

5 常见错误

在这里插入图片描述

6 代码演示

代码演示-1

JDBCDemo1:

public class JDBCDemo1 {public static void main(String[] args) throws Exception{//1 注册驱动Class.forName("com.mysql.jdbc.Driver");//2 获取连接//url: 连接字符串 jdbc:mysql://localhost:3306/companydb//useSSL=false 明确禁用SSL//characterEncoding=utf-8 设置字符编码为utf-8//user: 用户名//password: 密码// 定义数据库连接参数String url = "jdbc:mysql://localhost:3306/companydb?useSSL=false&characterEncoding=utf-8";String username = "root";String password = "root";Connection connection = null;connection = DriverManager.getConnection(url, username, password);if (connection != null) {System.out.println("连接成功...");}//3 关闭// 关闭数据库连接if (connection != null) {connection.close();}}
}

代码演示-2

JDBCDemo2:

public class JDBCDemo2 {public static void main(String[] args) throws Exception{// 1 注册驱动Class.forName("com.mysql.jdbc.Driver");// 2 获取连接对象// 定义数据库连接参数String url = "jdbc:mysql://localhost:3306/companydb?useSSL=false&characterEncoding=utf-8";String username = "root";String password = "root";Connection connection;connection = DriverManager.getConnection(url, username, password);// 3 创建命令对象Statement statement = connection.createStatement();// 4 执行命令// 4.1 创建数据库int count1 = statement.executeUpdate("create database if not exists myschool;");// 4.2 切换数据库int count2 = statement.executeUpdate("use myschool;");// 4.3 创建数据表int count3 = statement.executeUpdate("create table if not exists student(stu_id int primary key auto_increment, stu_name varchar(20), stu_age int);");// 4.4 添加数据int count4 = statement.executeUpdate("insert into student values (null,'张三',18),(null,'李四',19),(null,'王五',20);");// 4.5 修改数据int count5 = statement.executeUpdate("update student set stu_age = stu_age+5,stu_name='张利' where stu_id=1;");// 4.6 删除数据int count6 = statement.executeUpdate("delete from student where stu_id=1;");// 4.7 删除数据表/数据库
//        statement.executeUpdate("drop table student;");
//        statement.executeUpdate("drop database myschool;");// 5 处理System.out.println("count1: "+ count1);System.out.println("count2: "+ count2);System.out.println("count3: "+ count3);System.out.println("count4: "+ count4);System.out.println("count5: "+ count5);System.out.println("count6: "+ count6);// 6 关闭资源statement.close();connection.close();}
}

代码演示-3

JDBCDemo3:

public class JDBCDemo3 {public static void main(String[] args) throws Exception{// 1 注册驱动Class.forName("com.mysql.jdbc.Driver");// 定义数据库连接参数String url = "jdbc:mysql://localhost:3306/companydb?useSSL=false&characterEncoding=utf-8";String username = "root";String password = "root";// 2 获取连接对象Connection connection;connection = DriverManager.getConnection(url, username, password);// 3 创建命令对象Statement statement = connection.createStatement();// 4 执行命令ResultSet resultSet = statement.executeQuery("select * from student;");// 5 处理while (resultSet.next()) {int stuId = resultSet.getInt("stu_id");String stuName = resultSet.getString("stu_name");int stuAge = resultSet.getInt("stu_age");String stuGender = resultSet.getString("stu_gender");String stuAddress = resultSet.getString("stu_address");Date stuBorn = resultSet.getDate("stu_born");System.out.println(stuId+"\t"+stuName+"\t"+stuAge+"\t"+stuGender+"\t"+stuAddress+"\t"+stuBorn);}// 6 关闭resultSet.close();statement.close();connection.close();}
}

代码演示-4

JDBCDemo4:

需求:
创建用户表(user): 字段:user_id,user_name,password,age,phone,email
实现用户登录功能
public class JDBCDemo4 {public static void main(String[] args) throws Exception{Scanner scanner = new Scanner(System.in);System.out.println("请输入用户名");//回车返回String user_name = scanner.nextLine();System.out.println("请输入密码");//空格返回String user_pwd = scanner.next();// 1 注册驱动Class.forName("com.mysql.jdbc.Driver");// 定义数据库连接参数String url = "jdbc:mysql://localhost:3306/companydb?useSSL=false&characterEncoding=utf-8";String username = "root";String password = "root";// 2 获取连接对象Connection connection;connection = DriverManager.getConnection(url, username, password);// 3 创建命令对象//当在 SQL 中使用字符串时,必须非常小心,确保采取适当的安全措施,以防止 SQL 注入和其他安全威胁。String sql = "select * from user where user_name = '" + user_name + "' and password = '" + user_pwd + "'";Statement statement = connection.createStatement();// 4 执行命令//容易受到 SQL 注入攻击ResultSet resultSet = statement.executeQuery(sql);// 5 处理if (resultSet.next()) {System.out.println("登录成功...");} else {System.out.println("登录失败...");}// 6 关闭resultSet.close();statement.close();connection.close();}
}

SQL注入攻击:

请输入用户名
xxxx' or 1=1;#
请输入密码
root
登录成功...

什么是SQL注入攻击?

SQL注入:用户输入的数据中有SQL关键字或语句并且参与了SQL语句的编译,导致SQL语句编译后的条件含义为true,实现欺骗服务器,一直得到正确的结果。这种现象称为SQL注入。

如何避免:

不要使用SQL拼接方式,SQL 语句要在用户输入数据前就已编译成完整的 SQL 语句,再进行填充数据。

PreparedStatement

概念:

  • PreparedStatement继承了Statement接口,执行SQL语句的方法无异。

作用:

  • 预编译SQL语句,效率高。
  • 安全,避免SQL注入。
  • 可以动态的填充数据,执行多次同构的SQL语句。

应用:

  • 预编译SQL语句,数据参数使用?占位:

  • PreparedStatement pstmt = null;
    pstmt = conn.prepareStatement("select * from user where uname=? and pwd=?");
    
  • 为参数下标赋值:

  • pstmt.setString(1,Gavin);
    pstmt.setString(2,123456);
    

注意:

  • JDBC中的所有参数都由 ?符号占位,这被称为参数占位符。
  • 在执行SQL语句之前,必须为每个参数提供值。
  • 当你不知道数据参数的类型是什么时, 可以使用setObject();方法

预编译命令, 预防SQL注入攻击

请输入用户名
xxxx' or 1=1;#
请输入密码
root
登录失败...

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

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

相关文章

Vue(十九):ElementUI 扩展实现树形结构表格组件的勾父选子、半勾选、过滤出半勾选节点功能

效果 原理分析 从后端获取数据后,判断当前节点是否勾选,从而判断是否勾选子节点勾选当前节点时,子节点均勾选全勾选与半勾选与不勾选的样式处理全勾选和全取消勾选的逻辑筛选出半勾选的节点定义变量 import {computed, nextTick, reactive, ref} from vue; import {tree} f…

解剖 Python 代码,深入学习 interpret 库的功能和应用!

更多资料获取 📚 个人网站:ipengtao.com Python是一门广泛应用的编程语言,拥有丰富的标准库和第三方库,可以用于各种应用场景。在Python中,有一个名为interpret的库,它提供了一种强大的方式来处理和执行Py…

【大数据】Flink 架构(三):事件时间处理

《Flink 架构》系列(已完结),共包含以下 6 篇文章: Flink 架构(一):系统架构Flink 架构(二):数据传输Flink 架构(三):事件…

基于C#制作一个俄罗斯方块小游戏

目录 引言游戏背景介绍游戏规则游戏设计与实现开发环境与工具游戏界面设计游戏逻辑实现游戏优化和测试性能优化测试工具和流程说明引言 俄罗斯方块是一款经典的益智游戏,深受玩家喜爱。本文将介绍如何使用C#编程语言制作一个简单的俄罗斯方块小游戏,并探讨其设计与实现过程。…

【蓝桥杯日记】复盘篇二:分支结构

前言 本篇笔记主要进行复盘的内容是分支结构,通过学习分支结构从而更好巩固之前所学的内容。 目录 前言 目录 🍊1.数的性质 分析: 知识点: 🍅2.闰年判断 说明/提示 分析: 知识点: &am…

如何使用 Google 搜索引擎保姆级教程(附链接)

前言 需要挂梯子 一、介绍 "Google语法"通常是指在 Google 搜索引擎中使用一系列特定的搜索语法和操作符来精确地定义搜索查询。这些语法和操作符允许用户过滤和调整搜索结果,提高搜索的准确性。 二、安装 Google 下载 Google 浏览器 Google 官网ht…

自动化测试——selenium工具(web自动化测试)

1、自动化测试 优点:通过自动化测试有效减少人力的投入,同时提高了测试的质量和效率。 也用于回归测试。随着版本越来越多,版本回归的压力越来越大,仅仅通过人工测试 来回归所以的版本肯定是不现实的,所以…

如何在 Ubuntu 中安装 Microsoft Edge 浏览器

微软终于聪明了一回,也学会了「打不过就加入」。Microsoft Edge 浏览器的 Linux 稳定版已经于 2020 年 10 月 23 日发布,并提供给 Linux 发行版使用。除了官方 Edge APT 源以外,还提供了.deb和.rpm格式的安装包。 Microsoft Edge 基于 Chrom…

【Linux操作系统】:Linux开发工具编辑器vim

目录 Linux 软件包管理器 yum 什么是软件包 注意事项 查看软件包 如何安装软件 如何卸载软件 Linux 开发工具 Linux编辑器-vim使用 vim的基本概念 vim的基本操作 vim正常模式命令集 插入模式 插入模式切换为命令模式 移动光标 删除文字 复制 替换 撤销 跳至指…

Python爬虫解析库安装

解析库的安装 抓取网页代码之后,下一步就是从网页中提取信息。提取信息的方式有多种多样,可以使用正则来提取,但是写起来相对比较烦琐。这里还有许多强大的解析库,如 lxml、Beautiful Soup、pyquery 等。此外,还提供了…

备战蓝桥杯---数据结构与STL应用(基础实战篇1)

话不多说,直接上题: 当然我们可以用队列,但是其插入复杂度为N,总的复杂度为n^2,肯定会超时,于是我们可以用链表来写,同时把其存在数组中,这样节点的访问复杂度也为o(1).下面是AC代码: 下面我们来…

Shell中sed编辑器

1.简介 sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个 命令文本文件中。 2.sed编辑器的工作流程 sed…

《元梦之星》bug层出不穷,逼得玩家研发“自救套路”?

对于bug,想必喜爱游戏的玩家都不会陌生,在各类软件或者游戏中偶尔会出现一些影响正常运行的bug,但是并不会引起很大的反响。大家之所以能以平常心看待是因为各大游戏或者是应用软件中的bug都会因为玩家的及时发现而进行修复,在出现…

软件价值3-A*算法寻路

A*算法(A-star算法)是一种启发式搜索算法,主要用于在图或网络中找到从起始节点到目标节点的最佳路径。它结合了Dijkstra算法的广度优先搜索和贪婪最优优先搜索的特点,通过估算从起始节点到目标节点的代价来指导搜索方向。 A*算法…

Android中属性property_get和property_set的详细用法介绍

1,property_get和property_set的作用说明 在Android操作系统中,property_get和property_set是用于获取和设置系统属性的函数。这些属性通常用于存储和读取配置信息,例如设备配置、网络设置、系统参数等。 property_get函数用于获取指定属性…

二叉树中和为某一值的路径

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 学习必须往深处挖&…

一、创建Vue3项目

1. 下载 node.js 下载地址:https://nodejs.org/zh-cn 优先选择 16 版本; node -v || node -version 可以检查本地 node.js 版本 2. 设置淘宝镜像源 npm config set registry https://registry.npmmirror.com/ 设置淘宝镜像源 npm config get registry 查看当前镜像…

如何获得《幻兽帕鲁》隐藏帕鲁唤夜兽?13000个配种配方查询 幻兽帕鲁Steam好评率还在涨 Mac苹果电脑玩幻兽帕鲁 Crossover玩Windows游戏

《幻兽帕鲁》是一款Steam平台热门游戏,开放式大陆和养成式冒险结合,成为2024首款热门游戏,不过由于官方仅发布了Windows版的游戏客户端,Mac用户无法直接玩,好在有Crossover这样的神器,让苹果电脑也能玩上《…

JavaScript 基础 (二)

文章目录 JavaScript 基础 (二)一.运算符1.1 **算术运算符**1.1.1 基础1.1.2 算术运算符执行的优先级顺序1.1.3 小结 1.2 **赋值运算符**1.2.1 基础1.2.2 小结 1.3 **一元运算符**1.3.1 基础1.3.2 小结 1.4 **比较运算符**1.4.1 比较运算符的介绍1.4.2 比…

如何改变音频的频率教程

这是一篇教你如何通过一些工具改变音频频率的教学文章。全程所用的软件都是免费的。 本文用到的软件: AIX智能下载器 用于抓取任何视频网站资源的插件 格式工厂 将mp4转化为mp3 Audacity 改变音频频率的软件 如果你已备好mp3或其他格式的音频,那么直接看…