JDBC初体验(二)——增、删、改、查
本课目标
理解SQL注入的概念
掌握 PreparedStatement 接口的使用
熟练使用JDBC完成数据库的增、删、改、查操作
SQL注入
注入原理:利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句
防止SQL注入的方法:
- 过滤用户输入的数据库中是否包含非法字符
- 分步校验,先使用用户名来查询用户,如果找到了,在比较密码
- 使用 PreparedStatement 接口
PreparedStatement接口是 Statement 的子接口,可以使用该接口来替换 Statement 接口

PreparedStatement的使用
- 使用 Connection 对象的preparedStatement(String sql):即创建它时就让它与一条SQL语句绑定
- 编写SQL语句时,如果存在参数,使用“?” 作为数据占位符
- 调用PreparedStatement 的 setXXX()系列方法为占位符设置值,索引从1开始
- 调用 executeUpdate() 或 executeQuery() 方法,但要注意,调用没有参数的方法
PreparedStatement编程模板

使用JDBC完成数据添加的操作模板

使用JDBC完成数据修改的操作模板

使用JDBC完成数据删除的操作模板

代码演示
-
User 类
public class User {private int id;private String userName;private String userPass;private int role;public User(int id, String userName, String userPass, int role) {this.id = id;this.userName = userName;this.userPass = userPass;this.role = role;}public User() {}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getUserPass() {return userPass;}public void setUserPass(String userPass) {this.userPass = userPass;}public int getRole() {return role;}public void setRole(int role) {this.role = role;}@Overridepublic String toString() {return "User{" +"id=" + id +", userName='" + userName + '\'' +", userPass='" + userPass + '\'' +", role=" + role +'}';}
}
-
方法类
public class UserDo {Connection connection = null;Statement statement = null;PreparedStatement ps = null;ResultSet resultSet = null;/*** 用户登录——查找* 用户名* 密码*/public User tologin(String userName, String userPass){//1.获取连接对象getConnection();//2.编写SQL语句String sql = "SELECT ID,USERNAME,ROLE FROM USER WHERE USERNAME = ? AND USERPASS = ?";System.out.println("要执行的SQL语句:" + sql);//3.创建statement对象User user = null;try {//statement = connection.createStatement();//创建PreparedStatement对象 发送SQL语句并执行ps = connection.prepareStatement(sql);//3.1处理参数ps.setString(1,userName);ps.setString(2,userPass);//resultSet = statement.executeQuery(sql);//4.执行并解析结果resultSet = ps.executeQuery();while (resultSet.next()) {user = new User();user.setId(resultSet.getInt(1));user.setUserName(resultSet.getString(2));user.setRole(resultSet.getInt(3));}} catch (SQLException e) {e.printStackTrace();}finally {closeResource();}return user;}public User login(String userName,String userPass){//1.获取连接对象getConnection();//2.编写SQL语句String sql = "select ID,USERNAME,ROLE from user where userName = '"+userName+"' and userPass = '"+userPass+"'";System.out.println("要执行的SQL语句是:" + sql);//3.创建statement对象User user = null;try {statement = connection.createStatement();resultSet = statement.executeQuery(sql);//4.解析结果while (resultSet.next()){user = new User();user.setId(resultSet.getInt(1));user.setUserName(resultSet.getString(2));user.setRole(resultSet.getInt(3));}} catch (SQLException e) {e.printStackTrace();}finally {closeResource();}return user;}public User login2(String userName,String userPass){//1.获取连接对象getConnection();//2.编写SQL语句String sql = "select ID,USERNAME,USERPASS,ROLE from user where userName = '"+userName+"'";System.out.println("要执行的SQL语句是:" + sql);//3.创建statement对象User user = null;try {statement = connection.createStatement();resultSet = statement.executeQuery(sql);//4.解析结果while (resultSet.next()){user = new User();user.setId(resultSet.getInt(1));user.setUserName(resultSet.getString(2));user.setUserPass(resultSet.getString(3));user.setRole(resultSet.getInt(4));}if(userPass.equals(user.getUserPass())){return user;}} catch (SQLException e) {e.printStackTrace();}finally {closeResource();}return null;}/*** 增加用户*/public int saveUser(User user){int line = 0;//获取连接对象getConnection();//sql语句String sql = "INSERT INTO USER VALUES(DEFAULT,?,?,?)";try {ps = connection.prepareStatement(sql);ps.setString(1, user.getUserName());ps.setString(2, user.getUserPass());ps.setInt(3,user.getRole());//执行 增删改的执行方法是executeUpdate()//返回受影响的行数line = ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();}finally {closeResource();}return line;}/*** 修改用户*/public int updateUser(User user){int line = 0;getConnection();String sql = "UPDATE USER SET USERNAME=?,USERPASS=?,ROLE=? WHERE ID=?";try {ps = connection.prepareStatement(sql);ps.setString(1, user.getUserName());ps.setString(2, user.getUserPass());ps.setInt(3,user.getRole());ps.setInt(4,user.getId());line = ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();}finally {closeResource();}return line;}/*** 删除用户*/public int deleteUser(int id){int line = 0;getConnection();String sql = "delete from user where id =?";try {ps = connection.prepareStatement(sql);ps.setInt(1,id);line = ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();}finally {closeResource();}return line;}/*** 获取连接对象* @return*/public Connection getConnection(){try {//1.加载驱动Class.forName("com.mysql.jdbc.Driver");//2.建立连接connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool?useSSL=false","root","123456");} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}return connection;}/*** 关闭资源*/public void closeResource(){if(resultSet!=null){try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if(ps!=null){try {ps.close();} catch (SQLException e) {e.printStackTrace();}}if(statement!=null){try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if(connection!=null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}
-
main 方法
查——登录
public class TestQuery {public static void main(String[] args) {Scanner sc = new Scanner(System.in);UserDo userDo = new UserDo();//验证登录System.out.print("请输入用户名:");String userName = sc.nextLine();System.out.print("请输入密码:");String userPass = sc.nextLine();User user = userDo.tologin(userName,userPass);if (user != null) {System.out.println("登录成功!欢迎您【" + user.getUserName() + "】!");}else {System.out.println("登录失败!用户名或密码错误!");}}
}
增加
public class TestInsert {public static void main(String[] args) {UserDo userDo = new UserDo();User user = new User();user.setUserName("yanlingji");user.setUserPass("666666");user.setRole(3);int line = userDo.saveUser(user);System.out.println(line > 0 ? "插入成功" : "插入失败");}
}
修改
public class TestUpdate {public static void main(String[] args) {UserDo userDo =new UserDo();User user = new User(13,"yanlingji","888888",1);int line = userDo.updateUser(user);System.out.println(line > 0 ? "修改成功" : "修改失败");}
}
删除
public class TestDelete {public static void main(String[] args) {UserDo userDo = new UserDo();int line = userDo.deleteUser(9);System.out.println(line > 0 ? "删除成功" : "删除失败");}
}相关文章:
JDBC初体验(二)——增、删、改、查
本课目标 理解SQL注入的概念 掌握 PreparedStatement 接口的使用 熟练使用JDBC完成数据库的增、删、改、查操作 SQL注入 注入原理:利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行能力,它可以通过在…...
Eva.js是什么(互动小游戏开发)
前言 Eva.js 是一个专注于开发互动游戏项目的前端游戏引擎。 易用:Eva.js 提供开箱即用的游戏组件供开发人员立即使用。是的,它简单而优雅! 高性能:Eva.js 由高效的运行时和渲染管道 (Pixi.JS) 提供支持,这使得释放设…...
监听 beforeunload 事件,阻止页面刷新导致的信息丢失
尤其是一个有编辑器的页面,可以监听 windwo.beforeunload 事件,在用户试图关闭当前标签页的时候提醒用户,内容可能会丢失。 Window:beforeunload 事件 - Web API 接口参考 | MDN...
Java 常见缓存详解以及解决方案
一. 演示Mybatis 一级缓存 首先我们准备一个接口 两个实现的方法, 当我们调用这个queryAll()方法时我们需要调用selectAll()方法来查询数据 调用此接口实现效果 这个时候我们就可以发现了问题,我们调用方法…...
Golang 交叉编译之一文详解
博客原文 文章目录 Golang 中的交叉编译不同操作系统间的编译Linux 下编译windowsmacos windows 下编译Linuxmacos macos 下编译Linuxwindows 不同架构下的编译amd64x86 参考 Golang 中的交叉编译 在 Golang 中,交叉编译指的是在同一台机器上生成针对不同操作系统或…...
最新ThinkPHP版本实现证书查询系统,实现批量数据导入,自动生成电子证书
前提:朋友弄了一个培训机构,培训考试合格后,给发证书,需要一个证书查询系统。委托我给弄一个,花了几个晚上给写的证书查询系统。 实现功能: 前端按照姓名手机号码进行证书查询证书信息展示证书展示&#x…...
windows安装运行Apache James(基于spring的版本)
下载地址 下载列表 https://james.apache.org/download.cgi 直接下载基于spring版本 https://www.apache.org/dyn/closer.lua/james/server/3.8.0/james-server-app-3.8.0-app.zip 设置签名 解压,并切换到james-server-spring-app-3.8.0目录下,在powe…...
Elasticsearch 基本概念:快速入门指南【记录】
简单记录,后续整理补充 介绍: Elasticsearch是一个分布式、可扩展、实时的搜索和分析引擎,建立在开源搜索库Lucene之上。它提供了强大的全文搜索功能和复杂的分析能力,适用于各种场景,包括应用日志分析、电子商务搜索…...
【JVM 基础】类字节码详解
JVM 基础 - 类字节码详解 多语言编译为字节码在JVM运行Java字节码文件Class文件的结构属性从一个例子开始反编译字节码文件字节码文件信息常量池方法表集合类名 再看两个示例分析try-catch-finallykotlin 函数扩展的实现 源代码通过编译器编译为字节码,再通过类加载…...
【算法】基础算法001之双指针
👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 🌝每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.数组分块…...
[力扣 Hot100]Day2 字母异位词分组
题目描述 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 出处 思路 这题有点考阅读理解,意思就是把输入数组中的所含字母相同但顺序不同的单词放到同…...
记一次 easyswoole 热重载失效复盘 grpc扩展惹的祸
首先看一下运行环境 swoole version 4.8.11 php version 7.4.33 easyswoole version 3.4.6 在easyswoole 的入口文件 如下: <?php namespace EasySwoole\EasySwoole; use App\WebSocket\WebSocketEvents; use Ap…...
存储过程从表中获取数据库名称
---------------业务数据库信息 CREATE TABLE [dbo].[app_erp_datbabase_conf] ( [id] [int] IDENTITY(1,1) NOT NULL, [database_type] [varchar](200) NOT NULL, [database_name] [varchar](200) NOT NULL, [create_time] [datetime] NULL, [modify_t…...
.NET 反射的介绍和简单应用
什么是反射? 反射就是动态发现类型信息的能力。它帮助程序设计人员在程序运行时利用一些信息去动态地使用类型,这些信息在设计时是未知的,这种能力类似于后期绑定。反射还支持的更高级的行为,能在运行时动态创建新类型࿰…...
在drawio中使用BPMN2.0绘制详细的业务流程图和编排模型
在drawio中使用BPMN2.0绘制详细的业务流程图和编排模型 drawio是一款强大的图表绘制软件,支持在线云端版本以及windows, macOS, linux安装版。 如果想在线直接使用,则直接输入网址draw.io或者使用drawon(桌案), drawon.cn内部完整的集成了drawio的所有功…...
GO——defer函数
定义 当前函数返回之前执行传入函数的一个关键字 执行时间 当前函数返回前执行 常用于 关闭文件描述符关闭数据库链接解锁资源 原理 参考:https://draveness.me/golang/docs/part2-foundation/ch05-keyword/golang-defer/ 后调用的 defer 函数会先执行&…...
【UE Niagara学习笔记】06 - 制作火焰喷射过程中飞舞的火星
在上一篇博客(【UE Niagara学习笔记】05 - 喷射火焰顶部的蓝色火焰)的基础上继续实现喷射火焰的火星的效果。 目录 效果 步骤 一、创建材质实例 二、添加新的发射器 2.1 设置粒子材质 2.2 设置发射器持续生成粒子 2.3 设置粒子生成数量 2.4 设…...
机器学习笔记一之入门概念
目录 一 基本分类二 按模型分类概率模型(Probabilistic Models)非概率模型(Non-Probabilistic Models)对比结论线性模型 (Linear Models)非线性模型 (Non-linear Models)对比 三 按算法分类1.批量学习(Batch Learning&…...
用于脚本支持的 CSS 媒体查询
Chrome 120 于近日发布,在这个版本中,我们获得了用于脚本支持的 CSS 媒体查询。简单地说,此媒体查询允许我们测试脚本语言是否可用,并根据支持定制页面内容和样式。我是白特,让我们一起来学习下吧。 媒体查询语法 媒…...
【HBase】——整合Phoenix
1 概述 Phoenix 是 HBase 的开源 SQL 皮肤。可以使用标准 JDBC API 代替 HBase 客户端 API 来创建表,插入数据和查询 HBase 数据。 Phoenix 在 5.0 版本默认提供有两种客户端使用(瘦客户端和胖客户端),在 5.1.2 版本 安装包中…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...
如何把工业通信协议转换成http websocket
1.现状 工业通信协议多数工作在边缘设备上,比如:PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发,当设备上用的是modbus从站时,采集设备数据需要开发modbus主站;当设备上用的是西门子PN协议时…...
比特币:固若金汤的数字堡垒与它的四道防线
第一道防线:机密信函——无法破解的哈希加密 将每一笔比特币交易比作一封在堡垒内部传递的机密信函。 解释“哈希”(Hashing)就是一种军事级的加密术(SHA-256),能将信函内容(交易细节…...
