博客
关于我
JDBC——(5)使用Statement操作数据表的弊端
阅读量:318 次
发布时间: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/

你可能感兴趣的文章
js-禁止右键菜单代码、禁止复制粘贴代码
查看>>
Redis (三)——Linux 上安装 Redis
查看>>
java 重写(override)和重载(overload)区别
查看>>
java 多态类型转换
查看>>
常用正则表达式
查看>>
Java判断字符串是否为金额
查看>>
angr学习笔记(7)(malloc地址单元符号化)
查看>>
结构型设计在工作中的一些经验总结
查看>>
如何提升员工体验 助力企业业务增长?这个棘手的问题终于被解决了!
查看>>
AcWing 828. 模拟栈
查看>>
OpenAI Gym简介及初级实例
查看>>
Java面向对象
查看>>
JAVA带标签的break和continue
查看>>
Java获取线程基本信息的方法
查看>>
(C++11/14/17学习笔记):线程启动、结束,创建线程多法、join,detach
查看>>
紫书——蛇形填数
查看>>
A Guide to Node.js Logging
查看>>
webwxbatchgetcontact一个神奇的接口
查看>>
【考研英语-基础-简单句】简单句的核心变化_谓语情态
查看>>
实现一个简易Vue(三)Compiler
查看>>