Java基础入门day44

day44

登录功能

代码实现

DBUtil.java

package com.saas.util;
​
import java.sql.*;
​
public class DBUtil {
​private static final String DB_DRIVER = "com.mysql.jdbc.Driver";private static final String DB_URL = "jdbc:mysql://localhost:3306/saas";private static final String DB_USER = "root";private static final String DB_PASS = "Abc@1234";
​private static Connection conn = null;
​static {try {//  加载驱动,放在静态代码块中可以优先执行该驱动的加载Class.forName(DB_DRIVER);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}
​/*** 数据库连接对象的获取* @return 数据库连接对象*/public static Connection getConn(){
​try {conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);} catch (SQLException e) {throw new RuntimeException(e);}
​return conn;}
​/*** 数据库连接资源的关闭,要注意关闭的顺序* @param rs    //  要关闭的ResultSet对象* @param stmt  //  要关闭的Statement对象* @param conn  //  要关闭的Connection对象*/public static void closeAll(ResultSet rs, Statement stmt, Connection conn){try {if(rs != null){rs.close();rs = null;}if(stmt != null){stmt.close();stmt = null;}if(conn != null){conn.close();conn = null;}} catch (SQLException e) {throw new RuntimeException(e);}}
}

Account.java

package com.saas.entity;
​
public class Account {
​private int aid;private String name;private String pass;private double money;
​@Overridepublic String toString() {return "Account{" +"aid=" + aid +", name='" + name + '\'' +", pass='" + pass + '\'' +", money=" + money +'}';}
​public int getAid() {return aid;}
​public void setAid(int aid) {this.aid = aid;}
​public String getName() {return name;}
​public void setName(String name) {this.name = name;}
​public String getPass() {return pass;}
​public void setPass(String pass) {this.pass = pass;}
​public double getMoney() {return money;}
​public void setMoney(double money) {this.money = money;}
}

IAccountDao.java

package com.saas.dao;
​
public interface IAccountDao {
​/*** 登录方法,判断用户名密码是否匹配* @param name 用户名* @param pass 密码* @return 用户名和密码是否和数据库匹配*/boolean login(String name, String pass);
}

AccountDaoImpl.java

package com.saas.dao.impl;
​
import com.saas.dao.IAccountDao;
import com.saas.util.DBUtil;
​
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
​
public class AccountDaoImpl implements IAccountDao{
​private Connection conn = null;
​private Statement stmt = null;
​private ResultSet rs = null;
​@Overridepublic boolean login(String name, String pass) {boolean flag = false;
​conn = DBUtil.getConn();
​String sql = "select * from account where name = '" + name + "' and pass = '" + pass + "'";
​try {stmt = conn.createStatement();
​rs = stmt.executeQuery(sql);
​if (rs.next()){flag = true;}} catch (SQLException e) {throw new RuntimeException(e);}
​return flag;}
}

TestAccount.java

package com.saas.test;
​
import com.saas.dao.IAccountDao;
import com.saas.dao.impl.AccountDaoImpl;
​
import java.util.Scanner;
​
public class TestAccount {
​public static void main(String[] args) {IAccountDao iad = new AccountDaoImpl();
​Scanner input = new Scanner(System.in);
​System.out.println("请输入用户名:");String name = input.nextLine();
​System.out.println("请输入密码:");String pass = input.nextLine();
​
//        System.out.println(iad.login(name, "000' or 1 = 1 or '1' = '"));System.out.println(iad.login(name, pass));}
}
mysql> select * from account;
+-----+----------+--------+-------+
| aid | name     | pass   | money |
+-----+----------+--------+-------+
|   1 | wukong   | 999999 |  5000 |
|   2 | tangtang | 000000 |  6000 |
+-----+----------+--------+-------+

运行TestAccount测试类

请输入用户名:
wukong
请输入密码:
999999
true
用户名密码都正确得到true
请输入用户名:
wukong
请输入密码:
123
false
用户名密码不匹配false

这个结果看似没有问题

SQL注入

概念

用户输入的数据中含有SQL关键字或者语法并且参与了SQL语句的编译,导致SQL语句编译后的条件含义为true,一直得到正确的结果,这种现象被称之为SQL注入

请输入用户名:
wukong
请输入密码:
000' or 1 = 1 or '1' = '
true
用户名密码不匹配,但是也得到了true的结果,因为用户输入的输入中含有SQL关键字,导致SQL语句执行后都有结果

如何避免

由于编写SQL语句时在用户输入数据,整合后再进行编译,所以为了避免SQL注入的问题,我们要使SQL语句再用户输入数据前就已经进行编译成完整的SQL语句,再进行数据填充

JDBC中的PreparedStatement对象具备这样的功能

PreparedStatement

PreparedStatement接口继承自Statement接口,执行SQL语句的方法会更加有效

应用

作用:

预编译SQL语句,效率更高

安全,避免SQL注入

可以动态填充数据,执行多个SQL语句

实现

参数标记

String sql = "select * from account where name = ? and pass = ?";

动态绑定参数:

stmt.setXxx(index下标, 值)
参数下标从1开始,为指定参数下标绑定值
         stmt.setString(1, name);stmt.setString(2, pass);

执行结果

请输入用户名:
wukong
请输入密码:
000' or '1' = '1
false
即使输入了带有SQL关键字的语句,也可以保证不会有正确结果

jdbc实现事务

使用jdbc中connection对象的setAutoCommit(false)强制让连接对象不默认执行,每次都不直接执行,直到出现connection对象的commit或者rollback为止

@Override
public boolean transfer(String from, String to, double money) {boolean flag = false;try {conn = DBUtil.getConn();Account fromAccout = getAccountByName(from);if(fromAccout == null){System.out.println("请检查转出账户是否存在!");return  false;}Account toAccout = getAccountByName(to);if(toAccout == null){System.out.println("请检查转入账户是否存在!");return false;}double fromMoney = fromAccout.getMoney();if(fromMoney < money){System.out.println("请确保转出账户有足够的余额!");return false;}toAccout.setMoney(toAccout.getMoney() + money);updateAccount(toAccout);System.out.println(1 / 0);fromAccout.setMoney(fromAccout.getMoney() - money);updateAccount(fromAccout);flag = true;conn.commit();} catch (Exception e) {try {conn.rollback();} catch (Exception ex) {ex.printStackTrace();}e.printStackTrace();}return flag;
}

jdbc相对与MySQL命令框的好处是,Java中有强大的异常处理机制

在try中“尝试”正确执行所有的代码,直到最后一行都没有异常,则让连接对象进行commit操作

一旦尝试过程中出现任何问题,则Java异常处理机制将走catch代码块,则在catch代码块中进行rollback处理

由Java的异常处理机制动态自动决定到底进行哪一步操作

注意:想要实现事务处理,必须要要在同一个connection对象上操作

更安全的方式使用事务应该使用ThreadLocal保证连接对象是同一个

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

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

相关文章

数据结构复习/学习9--堆/堆实现/升降序建堆/top-k问题

一、堆与完全二叉树 1.堆的逻辑与物理结构 2.父节点与子节点的下标 3.大小根堆 二、堆的实现&#xff08;大根堆为例&#xff09; 注意事项总结&#xff1a; 注意堆中插入与删除数据的位置和方法与维持大根堆有序时的数据上下调整 三、堆排序 1.排升序建大堆效率高 注意事项…

Redis快速学习

Redis快速学习 一、 Redis快速入门1.1 初始Redis1.1.1 Redis的存储方式1.1.2 NoSQL 与 sql 之间的区别 1.2 Redis概述1.2.1 Redis是什么1.2.2 Redis有什么用1.2.3 Redis的特性 1.3 Redis安装测试1.3.1 Redis Linux安装 1.4 Redis测试工具1.5 Redis的基本知识 二、Redis的五大数…

HFSS-day3-HFSS的工作界面

工作界面也称为用户界面&#xff0c;是HFSS软件使用者的工作环境:了解、熟悉这个工作环境是掌握HFSS软件使用的第一步 HFSS工作环境介绍 1.HFSS工作界面简单的组成说明2.工作界面中各个工作窗口功能主菜单工具栏项目管理窗口属性窗口信息管理窗口进程窗口三维模型窗口 3.HFSS主…

gin自定义中间件

gin自定义中间件 代码 代码 package mainimport ("fmt""github.com/gin-gonic/gin""net/http""time" )// MyLogger 自定义中间件&#xff1a;方式二&#xff1a;通过定义函数&#xff0c;返回gin.HandlerFunc类型的函数&#xff0c;定…

解决vue elementUI el-tabs默认选项下划线不显示的问题

el-tabs初始加载时&#xff0c;el-tabs__active-bar的宽度为0&#xff0c;导致下划线不显示&#xff0c;因此设置其宽度即可&#xff1a; this.$nextTick((_) > {const activeBarElement document.getElementsByClassName("el-tabs__active-bar")[0];activeBarEl…

看完这个,你就懂了!IT审计到底是干什么的?如何做好IT审计?

01 大家应该都知道财务审计&#xff0c; 通俗讲&#xff0c;就是查账的。 看一下公司账上的数据是否准确&#xff0c; 每笔账是否都能合理溯源。 那IT审计到底是干什么的呢&#xff1f; 它和财务审计有什么关系吗&#xff1f; 这么跟你说吧&#xff0c; 现在很多公司都…

linux下dd制作启动U盘

dd命令是比较推荐的一种Linux环境中制作U盘启动盘的方式&#xff0c;无需安装额外的工具&#xff0c;基本上所有Linux发行版都集成了这个命令。 1、插入U盘&#xff1b; 2、打开终端&#xff1b; 3、确认U盘路径&#xff0c;在终端中输入&#xff1a;sudo fdisk -l 例如&am…

DInet

&#xff08;1&#xff09;数据&#xff1a; 1&#xff09;&#xff1a;随机获取5帧参考帧 2&#xff09;&#xff1a;处理这5帧连续帧&#xff0c;:source_frames:连续5帧的crop_moth b)audio_list:连续5帧的每一帧对应的5帧音频mel特征 c):refs:fintune 固定参考帧&#xff0…

通义千问-7B-Chat-Int4

通义千问-7B-Chat-Int4 代码仓库地址&#xff1a;https://github.com/QwenLM/Qwen 安装 克隆我们的仓库并跳转到相应目录 git clone https://www.modelscope.cn/qwen/Qwen-7B-Chat-Int4.git cd Qwen-7B-Chat-Int4 2. 创建 conda 环境 conda create -n qwenint4 python3.8…

1069 微博转发抽奖

solution #include<iostream> #include<string> #include<map> using namespace std; int main(){int n, m, s, loop 0, have 0;string id;map<string, int> mp;cin >> m >> n >> s;for(int i 1; i < m; i){//编号从1开始cin…

【docker】Spring Boot Layered Jar:优化Docker镜像构建与部署的新方案

一、Spring Boot Layered Jar优化Docker构建 Spring Boot Layered Jar 是一种特殊的 Jar 包格式&#xff0c;由 Spring Boot 2.3 及以上版本提供。这种格式主要是为了优化 Docker 镜像的构建和部署过程。以下是关于 Spring Boot Layered Jar 的详细解释&#xff1a; 1. 分层结…

怎么扫描二维码看图片?在线制作图片二维码的方法

随着现在二维码的广泛使用&#xff0c;用这个方式来展现内容的情况越来越多&#xff0c;比如扫码看图就是一种很常见的一种类型。将图片生成二维码后通过扫码来调取云端存储的图片查看&#xff0c;这样可以一次预览多张图片并且不会占据内存&#xff0c;能够快速的实现图片内容…

PyPI 与 GitHub 的双因素认证 | 2FA 配置指南

唠唠闲话 最近登录 GitHub 一直提示设置双重验证。除此之外&#xff0c;开发 Python 包常用的平台—— PyPI &#xff0c;也宣布从今年开始强制启用双因素认证&#xff08;2FA&#xff09;。这一变化虽然在提高安全性方面起到了积极作用&#xff0c;但也给日常工作带来了麻烦。…

P1164 小A点菜

题目描述: 不过 uim 由于买了一些书&#xff0c;口袋里只剩 &#x1d440;M 元 (&#x1d440;≤10000)(M≤10000)。 餐馆虽低端&#xff0c;但是菜品种类不少&#xff0c;有 &#x1d441;N 种 (&#x1d441;≤100)(N≤100)&#xff0c;第 &#x1d456;i 种卖 &#x1d44…

情感聊天赛道用al制作一分钟一条视频无脑玩法日入500+

详情介绍 这个赛道是用al快速制作情感故事聊天 原理就是用爆款的文案 al生成情感聊天视频全网独家赛道不拥挤 这个赛道几乎没人做一片蓝海 视频号分成计划 抖音中视频都可以做 建议做视频号创作者分成计划 单价高事少 视频号的平均用户年龄都是比较大的 对于这种情感故事的…

【UE+MQTT】Mqtt Client插件使用记录

步骤 1. 在虚幻商城中下载“Mqtt Client”插件 插件地址&#xff1a;https://www.unrealengine.com/marketplace/zh-CN/product/34cbcaef7a664451a886dba37b4769bc?sessionInvalidatedtrue 文档地址&#xff1a;[虚幻引擎] DT Mqtt 插件详细说明 – DT 2. 在虚幻编辑器中确…

CSS 预处理器:stylus运用详解

文章目录 一、stylus简介Stylus 的主要特性引入 Stylus1. 安装 Stylus2. 配置 webpack3. 编写 Stylus 文件4. 在项目中引入 Stylus 文件 总结 二、stylus常见问题三、stylus运用案例四、stylus优缺点五、热门文章 一、stylus简介 Stylus 是一个强大的 CSS 预处理器&#xff0c…

菜鸡学习netty源码(四)—— EventLoopGroup

1.概述 我们前面进行过分析,channel为netty网络操作的抽象类,EventLoop负责处理注册到其上的Channel处理的I/O事件;EventLoopGroup是一个EventLoop的分组,它可以获取到一个或者多个的EventLoop对象。 2.类关系图 NioEventLoopGroup的类继承图,蓝色部分为对应的java类,绿…

正点原子imx6ull内核移植网络驱动修改无法出现两个网络端口

重点1&#xff1a;手册上让我们在&iomuxc_snvs节点中做点添加网络复位信息&#xff0c;我们这里不需要做&#xff0c;直接下一步。 这里与手册不同&#xff0c;这里直接像我这样将pinctrl_enet2和pinctrl_enet1中对最后两行做修改和添加。直接将复位引脚的配置加入这个节点…

TalkingGaussian:基于高斯溅射的结构保持3D说话人头合成

TalkingGaussian: Structure-Persistent 3D Talking Head Synthesis via Gaussian Splatting TalkingGaussian&#xff1a;基于高斯溅射的结构保持3D说话人头合成 Jiahe Abstract 摘要 TalkingGaussian: Structure-Persistent 3D Talking Head Synthes…