博客
关于我
JDBC——(5)使用Statement操作数据表的弊端
阅读量:317 次
发布时间:2019-03-04

本文共 3747 字,大约阅读时间需要 12 分钟。

一,操作和访问数据库

  • 数据库连接被用于向数据库服务器发送命令和 SQL 语句,并接受数据库服务器返回的结果。其实一个数据库连接就是一个Socket连接。

  • 在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式:

    • Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。
    • PrepatedStatement:SQL 语句被预编译并存储在此对象中,可以使用此对象多次高效地执行该语句。
    • CallableStatement:用于执行 SQL 存储过程

二,使用Statement操作数据表的弊端

  • 通过调用 Connection 对象的 createStatement() 方法创建该对象。该对象用于执行静态的 SQL 语句,并且返回执行结果。如下代码演示
Connection conn = null;Statement st = null;conn=JDBCUtils.getConnection();//已经封装好的连接st = conn.createStatement();
  • Statement 接口中定义了下列方法用于执行 SQL 语句:

    int excuteUpdate(String sql):执行更新操作INSERT、UPDATE、DELETEResultSet executeQuery(String sql):执行查询操作SELECT
  • 但是使用Statement操作数据表存在弊端:

    • 问题一:存在拼串操作,繁琐
    • 问题二:存在SQL注入问题
  • SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令(如:SELECT user, password FROM user_table WHERE user=‘a’ OR 1 = ’ AND password = ’ OR ‘1’ = ‘1’) ,从而利用系统的 SQL 引擎完成恶意行为的做法。

  • 对于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement(从Statement扩展而来) 取代 Statement 就可以了。

    代码演示:

package com.atguigu2.statement.crud;import java.io.InputStream;import java.lang.reflect.Field;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;import java.util.Scanner;import org.junit.Test;public class StatementTest {   	// 使用Statement的弊端:需要拼写sql语句,并且存在SQL注入的问题	//如何避免出现sql注入:只要用 PreparedStatement(从Statement扩展而来) 取代 Statement	@Test	public void testLogin() {   		Scanner scanner = new Scanner(System.in);				System.out.print("请输入用户名:");		String user = scanner.nextLine();		System.out.print("请输入密码:");		String password = scanner.nextLine();		//SELECT user,password FROM user_table WHERE user = '1' or ' AND password = '=1 or '1' = '1'		String sql = "SELECT user,password FROM user WHERE user = '"+ user +"' AND password = '"+ password +"'";		User returnUser = get(sql,User.class);		if(returnUser != null){   			System.out.println("登录成功");		}else{   			System.out.println("用户名不存在或密码错误");		}	}	// 使用Statement实现对数据表的查询操作	public 
T get(String sql, Class
clazz) { T t = null; Connection conn = null; Statement st = null; ResultSet rs = null; try { // 1.加载配置文件 InputStream is = StatementTest.class.getClassLoader().getResourceAsStream("jdbc.properties"); Properties pros = new Properties(); pros.load(is); // 2.读取配置信息 String user = pros.getProperty("user"); String password = pros.getProperty("password"); String url = pros.getProperty("url"); String driverClass = pros.getProperty("driverClass"); // 3.加载驱动 Class.forName(driverClass); // 4.获取连接 conn = DriverManager.getConnection(url, user, password); st = conn.createStatement(); rs = st.executeQuery(sql); // 获取结果集的元数据 ResultSetMetaData rsmd = rs.getMetaData(); // 获取结果集的列数 int columnCount = rsmd.getColumnCount(); if (rs.next()) { t = clazz.newInstance(); for (int i = 0; i < columnCount; i++) { // //1. 获取列的名称 // String columnName = rsmd.getColumnName(i+1); // 1. 获取列的别名 String columnName = rsmd.getColumnLabel(i + 1); // 2. 根据列名获取对应数据表中的数据 Object columnVal = rs.getObject(columnName); // 3. 将数据表中得到的数据,封装进对象 Field field = clazz.getDeclaredField(columnName); field.setAccessible(true); field.set(t, columnVal); } return t; } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭资源 if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (st != null) { try { st.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } return null; }}

在这里插入图片描述

数据库中没有这个用户名和密码却可以登录成功

综上:

在这里插入图片描述

转载地址:http://xmqq.baihongyu.com/

你可能感兴趣的文章
NAT工作原理
查看>>
Processes, threads and goroutines
查看>>
c++中的10种常见继承
查看>>
Vue学习—深入剖析渲染函数
查看>>
Vue学习—深入剖析函数式组件
查看>>
简单Makefile的编写
查看>>
使用BAT批处理 匹配查找指定文件夹,并在当文件夹下创建空文件
查看>>
wxpython的Hello,World代码探索
查看>>
【数字图像处理】OpenCV3 学习笔记
查看>>
【单片机开发】智能小车工程(经验总结)
查看>>
【单片机开发】基于stm32的掌上游戏机设计 (项目规划)
查看>>
KeepAlived介绍、配置示例、KeepAlived配置IPVS、调用脚本进行监控
查看>>
【Numpy学习】np.count_nonzero()用法解析
查看>>
Scala集合-数组、元组
查看>>
JAVA网络爬虫01-http client爬取网络内容
查看>>
04 程序流程控制
查看>>
java并发编程(1)
查看>>
C++&&STL
查看>>
子集(LeetCode 78)
查看>>
1004 Counting Leaves (30分)
查看>>