41.0/查询/sql注入安全问题以及解决方式。

41.1. 回顾

1. jdbc:[java database connection] java连接数据库
2. 完成了增删改操作。
   [1]加载驱动。Class.forName("com.mysql.cj.jdbc.Driver");
   [2]获取连接对象: Connection conn=DriverManager.getConnection(url,user,pass);
      url: jdbc:mysql://localhost:3306/数据库名?serverTimezone=Asia/Shanghai
   [3]获取执行sql语句的对象: Statement st=conn.createStatement();   
   [4]执行sql语句: st.executeUpdate(sql);
        sql: 增删改的sql.
           修改: update 表名 set 字段名=值,字段名=值.... where 条件
           添加: insert into 表名 values(值,值....);
           删除: delete from 表名 where 条件
           
   [5]关闭资源         

41.2. 正文

目录

41.1. 回顾

41.2. 正文

41.3 查询-所有

41.4 异常处理

41.5 sql注入安全问题

41.6企业级开发的模式


41.3 查询-所有

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;public class Test02 {public static void main(String[] args) throws Exception{//1. 加载驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.获取连接对象String url="jdbc:mysql://localhost:3306/mydb";String user="root";String password="root";Connection conn= DriverManager.getConnection(url,user,password);//3.获取执行sql的对象Statement st=conn.createStatement();//4. 执行sql语句String sql="select * from tbl_emp";//把查询的结果封装到一个ResultSet对象中。ResultSet rs = st.executeQuery(sql);//5. 从resultSet中取出结果. next():指针往下移动并判断当前是否存在元素。  getXXX();获取当前行的指定列的值。while(rs.next()){System.out.println(rs.getInt("id")+"\t"+rs.getString("name")+"\t"+rs.getDouble("salary"));}//6. 关闭资源rs.close();st.close();conn.close();}
}

根据用户名查询: 查询姓李的人。

 

package com.demo01;import java.sql.*;public class Test05 {public static void main(String[] args) throws Exception {query();}public static void query() throws Exception {Class.forName("com.mysql.cj.jdbc.Driver");String url = "jdbc:mysql://localhost:3306/day112303";String user = "root";String password = "634835";Connection conn = DriverManager.getConnection(url, user, password);Statement statement = conn.createStatement();String sql = "SELECT * FROM student WHERE s_name LIKE '李%'";statement.executeQuery(sql);ResultSet rs = statement.executeQuery(sql);while (rs.next()) {System.out.println(rs.getInt("s_id") + "\t" + rs.getString("s_name"));}}
}

 

41.4 异常处理

import java.sql.*;public class Test02 {public static void main(String[] args) {Connection conn = null;Statement st = null;ResultSet rs = null;try {//1. 加载驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.获取连接对象String url = "jdbc:mysql://localhost:3306/mydb";String user = "root";String password = "root";conn = DriverManager.getConnection(url, user, password);//3.获取执行sql的对象st = conn.createStatement();//4. 执行sql语句String sql = "select * from tbl_emp";//把查询的结果封装到一个ResultSet对象中。rs = st.executeQuery(sql);//5. 从resultSet中取出结果. next():指针往下移动并判断当前是否存在元素。  getXXX();获取当前行的指定列的值。while (rs.next()) {System.out.println(rs.getInt("id") + "\t" + rs.getString("name") + "\t" + rs.getDouble("salary"));}} catch (Exception e) {e.printStackTrace();} finally {//6. 关闭资源if (rs != null) {try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (st != null) {try {st.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}}
}

41.5 sql注入安全问题

发现无论你输入任何的账户和密码 只要or 后面的条件成立

那么一定都可以登录成功。出现bug了。

问题出现在Statement类,该类存在sql注入安全隐患

为了解决该隐患,创建了一个子类PreparedStatement.  

 

import java.sql.*;
import java.util.Scanner;public class Test03 {static String url = "jdbc:mysql://localhost:3306/mydb";static String user = "root";static String pwd = "root";public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.print("请输入账户:");String u=sc.nextLine();System.out.print("请输入密码:");String p=sc.nextLine();// next()和nextLine()区别: next()输入空格 空格以后的内容无法获取boolean flag = login(u, p);if(flag==true){System.out.println("登录成功");}else{System.out.println("登录失败");}}/*** 根据账户和密码判断是否登录成功** @param name     输入的账户* @param password 输入的密码* @return true表示登录成功  false表示登录失败*/public static boolean login(String name, String password) {Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {Class.forName("com.mysql.cj.jdbc.Driver");conn = DriverManager.getConnection(url, user, pwd);//?:表示占位符。--对sql预先编译。String sql = "select * from tbl_user where username=? and password=?";ps = conn.prepareStatement(sql);//为占位符赋值。int parameterIndex 第几个占位符, Object x 占位符的内容ps.setObject(1,name);ps.setObject(2,password);rs = ps.executeQuery();while (rs.next()) {return true;}} catch (Exception e) {e.printStackTrace();} finally{//6. 关闭资源if (rs != null) {try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (ps != null) {try {ps.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}return false;}}

根据账户和年龄查询用户信息 使用preparedStatement

41.6企业级开发的模式

dao类:

[data access object ] 数据访问对象层

包下都是用来访问数据对应表的操作

StudentDao: 该类专门用来操作Student表的,每个操作对应一个方法。

TeacherDao: 该类专门用来操作Teacher表,每个操作对应一个方法。

package com.ykq.dao;import java.sql.*;public class UserDao {String url = "jdbc:mysql://localhost:3306/mydb";String user = "root";String pwd = "root";Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;//每个操作对应一个方法。//1.根据id删除用户public int deleteById(int id) {try {Class.forName("com.mysql.cj.jdbc.Driver");conn = DriverManager.getConnection(url, user, pwd);//?:表示占位符。--对sql预先编译。String sql = "delete from tbl_user where id=?";ps = conn.prepareStatement(sql);ps.setObject(1,id);int i = ps.executeUpdate();return i;} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException throwables) {throwables.printStackTrace();} finally {//6. 关闭资源if (rs != null) {try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (ps != null) {try {ps.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}return 0;}//2. 添加用户public int insert(String username,String password,String realname){try {Class.forName("com.mysql.cj.jdbc.Driver");conn = DriverManager.getConnection(url, user, pwd);//?:表示占位符。--对sql预先编译。String sql = "insert into tbl_user(username,password,realname) values(?,?,?)";ps = conn.prepareStatement(sql);ps.setObject(1,username);ps.setObject(2,password);ps.setObject(3,realname);//执行sqlint i = ps.executeUpdate();return i;} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException throwables) {throwables.printStackTrace();} finally {//6. 关闭资源if (rs != null) {try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (ps != null) {try {ps.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}return 0;}
}

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

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

相关文章

java+python农村集体产权管理系统php+vue

注册、登陆该系统根据操作权限的不同分为管理员和用户两种,新用户在登陆前要进行用户注册,注册完成后方可进行登陆。 本次设计的关键问题处理,主要有如下几点: (1)本次开发,采用主流Thinkphp框架进行开发&a…

香港科技大学广州|智能制造学域博士招生宣讲会—华中科技大学专场

时间:2023年12月08日(星期五)15:00 地点:华中科技大学大学生活动中心A座603 报名链接:https://www.wjx.top/vm/mmukLPC.aspx# 宣讲嘉宾: 胡鹏程 副教授 https://facultyprofiles.hkust-gz.edu.cn/faculty-…

【区块链】产品经理的NFT初探

常见的FT如比特币(BTC),以太币(ETH)等,两个代币之间是完全可替换的。而NFT具有唯一性,不可以互相替换。本文作者对NET的发展现状、相关协议、应用场景等方面进行了分析,一起来看一下…

数字阅读用户规模持续增长 5.3亿人享受数字化阅读便利

近日,鲁迅长孙周令飞在接受采访时表示,自己“现在90%的时间刷视频,10%的时间看书”,引发网友热议。不少网友表示,鲁迅的孙子都花90%的时间刷视频,难怪现在没人看书了,其实这并不奇怪,也并不表明没人看书,而是读屏与读书并重的时代,纸质阅读与数字阅读共同构成了日常的阅读模式。…

vue+echarts实现依赖关系无向网络拓扑结图节点折叠展开策略

目录 引言 一、设计 1. 树状图(不方便呈现节点之间的关系,次要考虑) 2. 力引导依赖关系图 二、力引导关系图 三、如何实现节点的Open Or Fold 1. 设计逻辑 节点展开细节 节点收缩细节 代码实现 四、结果呈现 五、完整代码 引言 我…

Spring Boot 3.2.0 Tomcat虚拟线程初体验 (部分装配解析)

写在前面 spring boot 3 已经提供了对虚拟线程的支持。 虚拟线程和平台线程主要区别在于,虚拟线程在运行周期内不依赖操作系统线程:它们与硬件脱钩,因此被称为 “虚拟”。这种解耦是由 JVM 提供的抽象层赋予的。 虚拟线程的运行成本远低于平…

ELK---filebeat日志收集工具

elk---filebeat日志收集工具 filebeat是一个轻量级的日志收集工具,所使用的资源比logstash部署和启动时使用的资源小的多。 filebeat可以在非Java环境收集日志,它可以代替logstash在非Java环境上收集日志。 filebeat无法实现数据的过滤,一般…

fiddler测试弱网别再去深山老林测了,这样做就能达到弱网效果了!

弱网测试 概念:弱网看字面意思就是网络比较弱,我们通称为信号差,网速慢。 意义:模拟在地铁、隧道、电梯和车库等场景下使用APP ,网络会出现延时、中断和超时等情况。 添加图片注释,不超过 140 字&#xf…

【API 自动化测试】Eolink Apikit 图形用例详解

Eolink Apikit 的图形用例是指通过图形化的方式去表现 API 流程测试。它包括了条件选择器、单个 API 步骤和操作集等组件。 相较于前面推荐的表格化的通用用例,图形用例可以让测试人员更方便地设计和管理 API 流程测试,同时也更加的灵活。 添加图形用例…

大疆开发板A型基于HAL库驱动M3508直流无刷电机及PID控制

1.首先,我们先了解一下大疆开发板A型的资料,官方有提供 官网:RoboMaster 机甲大师赛 芯片型号STM32F427IIH6 2.了解M3508直流无刷电机的资料,官网有提供 3.于是我找到了C620电调的资料,官网有提供 4.好了&#xff0…

Python小技巧:探索函数调用为何加速代码执行

更多资料获取 📚 个人网站:ipengtao.com Python 作为一种解释型语言,其执行速度相对于编译型语言可能会较慢。然而,在Python中,通常观察到代码在函数中运行得更快的现象。这个现象主要是由于函数调用的内部优化和解释…

ASCII值对照表

ASCII码是一种7位编码,但它存放时必须占全1个字节,也即占用8位,最高位为0,其余7位表示ASCII码。 ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符包括所有的大写和小写字母,数字0 到9、标点符…