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.hqwc.cn/news/438995.html

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

相关文章

【论文阅读|半监督小苹果检测方法S3AD】

论文题目 : : Semi-supervised Small Apple Detection in Orchard Environments 项目链接:https://www.inf.uni-hamburg.de/en/inst/ab/cv/people/wilms/mad.html 摘要(Abstract) 农作物检测是自动估产或水果采摘等精准农业应用不…

GitCode|部分项目开源代码

1.EasyKeyboard 基于MFC的简单软键盘,使用vs2017开发 PangCoder / EasyKeyboard GitCode基于Windows平台的软键盘,使用VS2017开发,使用MFC框架https://gitcode.net/qq_36251561/easykeyboard 2.EncoderSimulator 基于WPF应用的编码器模拟工…

Vue2 通过.sync修饰符实现数据双向绑定

App.vue <template><div class"app"><buttonv-on:clickisShowtrue>退出按钮</button><BaseDialog:visible.syncisShow></BaseDialog></div> </template><script> import BaseDialog from "./components…

开源:基于Vue3.3 + TS + Vant4 + Vite5 + Pinia + ViewPort适配..搭建的H5移动端开发模板

vue3.3-Mobile-template 基于Vue3.3 TS Vant4 Vite5 Pinia ViewPort适配 Sass Axios封装 vconsole调试工具&#xff0c;搭建的H5移动端开发模板&#xff0c;开箱即用的。 环境要求&#xff1a; Node:16.20.1 pnpm:8.14.0 必须装上安装pnpm&#xff0c;没装的看这篇…

Blender 与 3ds Max | 面对面的直接较量(2024)

Blender和3ds Max&#xff0c;哪个动画软件更好&#xff1f;作为一个从事动画领域十年的专业人士&#xff0c;Mark McPherson提供了八条最新建议&#xff0c;帮助你了解哪个软件更适合满足你的3D动画需求。 1.建模 获胜者&#xff1a;3ds Max。3ds Max的建模机制已经被证明是…

FairGuard游戏加固入选《CCSIP 2023中国网络安全行业全景册(第六版)》

2024年1月24日&#xff0c; FreeBuf咨询正式发布《CCSIP 2023中国网络安全行业全景册(第六版)》。本次发布的全景图&#xff0c;共计展示20个一级分类、108个细分安全领域&#xff0c;旨在为广大企业提供网络安全产品选型参考&#xff0c;帮助企业了解中国网络安全技术与市场的…

《幻兽帕鲁》1月29日游戏服务器推荐!腾讯云降低规格再次降价!

腾讯29日刷新规格&#xff0c;从14M降低到12M&#xff0c;硬盘和流量都有降低&#xff0c;但价格打下来了&#xff01;价格从66元/月降低到32元/月&#xff0c;277元/3个月降低到96元/3个月&#xff01; 三大厂商4核16G的云服务器价格对齐&#xff0c;不过具体参数略有不同 阿里…

iOS 自动打包如何配置配置打包证书和profile provision文件

Jenkins 打包相关问题记录 打包失败截图&#xff1a; 1、证书找不到 NO certificate matching ‘ ‘ for ‘ ’ code singing is required …. D791BAD1-390A-4587-A35C-A743A3D88D52.png 由于更新过证书配置&#xff0c;导致新证书没有导入到Jenkins中。 配置步骤&#xf…

idea docker 内网应用实践

文章目录 前言一、服务器端1.1 离线安装docker1.2 开启docker远程访问1.3 制作对应jdk镜像1.3.1 下载jdk171.3.2 Dockerfile 制作jdk17镜像1.3.3 镜像导出1.3.4 服务器引入镜像 二、Idea 配置2.1 Dockerfile2.2 pom 引入docker插件2.3 idea docker插件配置2.4 打包镜像上传2.5 …

前端_关于CSS中外边距塌陷问题

问题描述&#xff1a; 当子级块级元素修改带动父级块级元素整体向下移动 我们希望当自级块级元素修改时&#xff0c;父级元素保持不动&#xff0c;解决方法有三个: 原代码&#xff1a; 方案一&#xff1a;为父级元素添加一个内边距 方案二&#xff1a;为父级元素添加overflo…

【机器学习300问】20、什么是神经网络?和深度学习什么关系?

在学习深度学习的相关知识之前&#xff0c;我们首先得了解什么是神经网络&#xff0c;解开神经网络的神秘面纱后&#xff0c;什么是深度学习的问题也就迎刃而解。我依旧会采用我习惯的方式&#xff1a;先给出例子直观理解&#xff0c;在给出定义深入理解&#xff0c;最后在实际…

MySQL行格式原理深度解析

MySQL中的行格式&#xff08;Row Format&#xff09;是指存储在数据库表中的数据的物理格式。它决定了数据是如何在磁盘上存储的&#xff0c;以及如何在查询时被读取和解析的。MySQL支持多种行格式&#xff0c;每种格式都有其特定的优点和适用场景。 一、前言 MySQL被分为Ser…