博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jdbc中Statement接口实现CRUD操作(了解)
阅读量:3965 次
发布时间:2019-05-24

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

1.Statement接口实现CRUD

package loey.java1;import java.sql.*;import java.util.HashMap;import java.util.Map;import java.util.Scanner;/** * 实现功能: *  1、需求 *      模拟用户登录功能的实现 *  2、业务描述 *      程序运行的时候,提供一个输入的入口,可以让用户输入用户名和密码 *      用户输入用户名和密码之后,提交信息,java程序收集用户信息 *      java程序连接数据库验证用户名和密码是否效 *      合法:显示登录成功 *      不合法:显示登录失败 *  3、数据的准备 *      在实际开发中,表的设计会使用专业的建模工具 *  4.当前程序存在问题: *      请输入登录名:aaa *      请输入登录密码:aaa' or '1' = '1 *      登录成功 *      这种现象被称为SQL注入(安全隐患,黑客经常使用 *  5.导致SQL注入的根本原因是什么? *   用户输入的信息中含SQL语句的关键字,并且这些关键字参与SQL语句的编译过程, *   导致SQL语句的愿意被扭曲,进而达到SQL注入。 * */public class JDBCTest06 {
public static void main(String[] args) {
Map
userLoginInfo = initUI(); boolean loginSuccess = loginSuccess(userLoginInfo); System.out.println(loginSuccess ? "登录成功" : "登录失败"); } private static boolean loginSuccess(Map
userLoginInfo){
boolean isSuccess = false; Connection conn = null; Statement stmt = null; ResultSet rs = null; try {
//1.注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2.获取连接 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306" + "/bjpowernode","root","1127"); //3.获取操作数据库的对象 stmt = conn.createStatement(); //4.执行sql语句 String sql = "Select * from t_user where loginName = '" + userLoginInfo.get("loginName") +"' and loginPwd = '" + userLoginInfo.get("loginPwd") + "'"; //以上正好完成了SQL语句拼接,以下代码的含义是:发送SQL语句给DBMS,DBMS进行编译SQL语句,正好 // 将用户输入的“非法信息”编译进去,导致了原SQL语句的含义被扭曲了。 rs = stmt.executeQuery(sql); while(rs.next()){
isSuccess = true; } } catch (ClassNotFoundException e) {
e.printStackTrace(); } catch (SQLException e) {
e.printStackTrace(); } finally {
if(rs != null){
try {
rs.close(); } catch (SQLException e) {
e.printStackTrace(); } } if(stmt != null){
try {
stmt.close(); } catch (SQLException e) {
e.printStackTrace(); } } if(conn != null){
try {
conn.close(); } catch (SQLException e) {
e.printStackTrace(); } } } return isSuccess; } /** * 用户登录界面 * @return 返回用户输入的登录名和登录密码 */ private static Map
initUI(){
HashMap
userLoginInfo = new HashMap<>(); Scanner scan = new Scanner(System.in); System.out.print("请输入登录名:"); String loginName = scan.nextLine(); System.out.print("请输入登录密码:"); String loginPwd = scan.nextLine(); userLoginInfo.put("loginName",loginName); userLoginInfo.put("loginPwd",loginPwd); return userLoginInfo; }}

弊端:

在这里插入图片描述

  • 问题三; Statement没办法操作Blob类型变量
  • 问题四:Statement实现批量插入时,效率较低

2.解决SQL注入问题

PreparedStatement和Statement对比?

  • Statement存在SQL注入问题,PreparedStatement解决了SQL注入问题
  • Statement是编译一次执行一次,PreparedStatement是编译一次,可执行N次,PreparedStatement效率较高一些
  • PreparedStatement会在编译阶段做类型的安全检查

什么情况下必须使用Statement呢?

  • 业务方面要求必须支持SQL注入的时候
  • Statement支持SQL注入,凡是业务方面要求是需要进行SQL语句拼接的,必须使用Statement,比如:用户输入desc表示降序,输入asc表示升序
package loey.java1;import java.sql.*;import java.util.HashMap;import java.util.Map;import java.util.Scanner;/** * 1.解决SQL注入问题 * 只要用户提供的信息不参与SQL语句的编译,问题就解决了, * 即使用户提供的信息含SQL语句的关键字,但是没参与编译,不起作用 * 要想用户的信息不参与SQL语句的编译,那么必须使用java.sql.PreparedStatement * java.sql.PreparedStatement接口继承了java.sql.Statement * PreparedAtatement的原理是:预先对SQL语句的框架进行编译,然后再给SQL语句传“值”。 * * 请输入登录名:aaa * 请输入登录密码:aaa' or '1' = '1 * 登录失败 * * PreparedStatement和Statement对比? * —Statement存在SQL注入问题,PreparedStatement解决了SQL注入问题 * —Statement是编译一次执行一次,PreparedStatement是编译一次,可执行N次,PreparedStatement效率较高一些 * —PreparedStatement会在编译阶段做类型的安全检查 * * 5、什么情况下必须使用Statement呢? *    业务方面要求必须支持SQL注入的时候 *    Statement支持SQL注入,凡是业务方面要求是需要进行SQL语句拼接的,必须使用Statement *  */public class JDBCTest07 {
public static void main(String[] args) {
Map
userLoginInfo = initUI(); boolean loginSuccess = loginSuccess(userLoginInfo); System.out.println(loginSuccess ? "登录成功" : "登录失败"); } /** * 判断用户登录是否成功 * * @param userLoginInfo 用户输入的登录名和登录密码 * @return true:登录成功 false:登录失败 */ private static boolean loginSuccess(Map
userLoginInfo) {
boolean isSuccess = false; Connection conn = null; PreparedStatement ps = null;//这里使用预编译的数据库操作对象 ResultSet rs = null; try {
//1.注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2.获取连接 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306" + "/bjpowernode", "root", "1127"); //3.获取预编译的数据库操作对象 // sql语句的框架中,一个?,表示一个占位符,一个?将来接收一个"值"。注意:占位符不要用单引号括起来 String sql = "select * from t_user where loginName = ? and loginPwd = ?"; // 程序执行到此处,会发送sql语句框架给DBMS,DBMS对sql语句框架进行预编译。 ps = conn.prepareStatement(sql); // 给占位符?传值,第一个?的下标是1,第二个?的下标是2(JDBC中下标都从1开始) ps.setString(1,userLoginInfo.get("loginName")); ps.setString(2,userLoginInfo.get("loginPwd")); rs = ps.executeQuery(); while (rs.next()) {
isSuccess = true; } } catch (ClassNotFoundException e) {
e.printStackTrace(); } catch (SQLException e) {
e.printStackTrace(); } finally {
if (rs != null) {
try {
rs.close(); } catch (SQLException e) {
e.printStackTrace(); } } if (ps != null) {
try {
ps.close(); } catch (SQLException e) {
e.printStackTrace(); } } if (conn != null) {
try {
conn.close(); } catch (SQLException e) {
e.printStackTrace(); } } } return isSuccess; } /** * 用户登录界面 * * @return 返回用户输入的登录名和登录密码 */ private static Map
initUI() {
HashMap
userLoginInfo = new HashMap<>(); Scanner scan = new Scanner(System.in); System.out.print("请输入登录名:"); String loginName = scan.nextLine(); System.out.print("请输入登录密码:"); String loginPwd = scan.nextLine(); userLoginInfo.put("loginName", loginName); userLoginInfo.put("loginPwd", loginPwd); return userLoginInfo; }}

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

你可能感兴趣的文章
Go在windows下执行命令行指令
查看>>
inotify
查看>>
inode
查看>>
Shell: sh,bash,csh,tcsh等shell的区别
查看>>
golang ubuntu 配置 笔记
查看>>
vim 常用命令
查看>>
golang 开源项目
查看>>
ubntu 开发服务进程
查看>>
linux 常用命令以及技巧
查看>>
记录1年免费亚马逊AWS云服务器申请方法过程及使用技巧
查看>>
golang文章
查看>>
linux的system () 函数详解
查看>>
在shell脚本的第一行中,必须写#!/bin/bash
查看>>
一句话##错误 'ASP 0116' 丢失脚本关闭分隔符
查看>>
文件上传漏洞之.htaccess
查看>>
常见网络安全设备默认口令
查看>>
VirtualBox虚拟机网络配置
查看>>
oracle vm virtualbox虚拟机下,CentOS7系统网络配置
查看>>
解决Linux CentOS中cp -f 复制强制覆盖的命令无效的方法
查看>>
wdcpv3升级到v3.2后,多PHP版本共存的安装方法
查看>>