JDBC中的遍历及安全问题

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 在执行查询SQL后,存放查询到的结果集数据;

JDBC遍历表的内容

ResultSet(结果集)

在执行查询SQL后,存放查询到的结果集数据;

接收结果集

ResultSet resultSet = statement.executeQuery(sql);

String sql = "select student_id,student_name,sex,birthday,phone,GradeId from stu";
ResultSet resultSet =  statement.executeQuery(sql);

遍历ResultSet中的数据

  • 数据行指针:初始位置在第一行数据前,每调用一次boolean next()方法,ResultSet中指针向下移动一行,结果为true,表示当前行有数据;
  • resultSet.getXxx("列名"); 根据列名获得数据
  • resultSet.getXxx(整数下标); 代表根据列的编号顺序获得,从1开始;
boolean next() throws SQLException;//判断resultSet结果集中下一行是否有数据
int getInt(int columnIndex) throws SQLException;//获得当前行的第N列的int值
int getInt(String columnLabel) throws SQLException;//获得当前行columnLabel列的int值
  • 列的编号从1开始;

查询案例

根据列名进行查询

/**
 * 方式一
 * 根据列名
 * JDBC查询数据库表的数据
 */
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class TestDQL {
   
    public static void main(String[] args) throws Exception{
   
        //1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.获得连接
        String url = "jdbc:mysql://localhost:3306/companydb?useUnicode = true&characterEncoding = utf8";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url,user,password);
        //3.获取执行的对象
        Statement statement = connection.createStatement();
        //4.编写SQL语句     查询
        String sql = "select student_id,student_name,sex,birthday,phone,GradeId from stu";
        ResultSet resultSet =  statement.executeQuery(sql);
        //5.处理结果
        while(resultSet.next()){
   //判断是否有下一行
            //1.根据列名获取当前行的每一列数据
            String student_id = resultSet.getString("student_id");
            String student_name = resultSet.getString("student_name");
            String sex = resultSet.getString("sex");
            String birthday = resultSet.getString("birthday");
            String phone = resultSet.getString("phone");
            String gradeId = resultSet.getString("gradeId");
            System.out.println(student_id+"\t"+student_name+"\t"+sex+"\t"+birthday+"\t"+phone+"\t"+gradeId);
        }
        //6.释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

根据列的下标进行查询

//方式二前面步骤如上:
//5.处理结果
        while(resultSet.next()){
   //判断是否有下一行
            //1.根据列名获取当前行的每一列数据
            String student_id = resultSet.getString(1);
            String student_name = resultSet.getString(2);
            String sex = resultSet.getString(3);
            String birthday = resultSet.getString(4);
            String phone = resultSet.getString(5);
            String gradeId = resultSet.getString(6);
            System.out.println(student_id+"\t"+student_name+"\t"+sex+"\t"+birthday+"\t"+phone+"\t"+gradeId);
        }

常见的错误

  • java.lang.ClassNotFoundException :找不到类(类名书写错误、没有导入jar包);
  • com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException :与SQL语句相关的错误(表名列名书写错误、约束错误、插入的值是String类型,但是没有加单引号)建议:在客户端工具中测试sql语句后,再粘贴到代码中来;
  • com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1003' for key 'PRIMARY' :主键值已存在,更改要插入的主键值;
  • com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:Unknown column 'password' in :可能输入的值的类型不对,确定插入元素时,对应的值的类型是否正确;

SQL注入问题


当用户输入的数据中有SQL关键字或语法时,并且参与了SQL语句的编译,导致SQL语句编译后条件结果为true,一直得到正确的结果。称为SQL注入;

  • 如:XXX‘ or 1 = 1;# 将后面部分注释

避免SQL注入

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

PreparedStatement


PreparedStatement接口继承了Statement接口。执行SQL语句的方法没有区别;

PreparedStatement的应用

  • 预编译SQL语句,效率高;
  • 安全,避免SQL注入;
  • 可以动态的填充数据,执行多个同构的SQL语句;

参数标记

//1.预编译SQL语句
 PreparedStatement preparedStatement = connection.prepareStatement(sql);
  • 应用PreparedStatement时,SQL字符串的参数都由?符号站位,被称为参数标记。在执行该SQL语句前,要为每个参数赋值;

动态参数绑定

preparedStatement.setXxx(下标,值);参数下标是从1开始,为指定占位符下标绑定值;

//2.为占位符下标赋值
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);

综合案例---登录

创建表并插入数据:

CREATE TABLE `user`(
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(20) NOT NULL,
    `password` VARCHAR(20) NOT NULL,
    phone VARCHAR(11)
)CHARSET = utf8;
INSERT INTO `user`(username, `password`,phone) VALUES ('kaka','123','12345678910');
INSERT INTO `user`(username, `password`,phone) VALUES ('tangtang','456',NULL);
SELECT * FROM `user`;

实现登录:

/**
 * 登录操作
 * 通过控制台,用户输入用户名和密码;
 * 用户输入的用户名和密码作为参数,编写查询SQL语句;
 * 如果查询到用户,则用户存在,提示登录成功,反之,提示失败;
 */

import java.util.Scanner;
import java.sql.*;
public class TestSafeLogin {
   
    public static void main(String[] args) throws Exception{
   
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = sc.next();
        System.out.println("请输入密码:");
        String password = sc.next();
        //1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.获得连接
        String url = "jdbc:mysql://localhost:3306/companydb?useUnicode = true&characterEncoding = utf8";
        Connection connection = DriverManager.getConnection(url,"root","root");
        //3.获取执行的对象
        String sql ="select * from user where username = ? and password = ?";
        //预编译
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        //为SQL语句赋值
        preparedStatement.setString(1,username);
        preparedStatement.setString(2,password);
        //4.执行SQL语句
        ResultSet resultSet =  preparedStatement.executeQuery();
        //5.处理结果
        if(resultSet.next()){
   
            System.out.println("登录成功");
        }else{
   
            System.out.println("登录失败");
        }
        //6.释放资源
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }
}
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
监控 druid Java
监控druid数据库连接池连接泄露的思路
监控druid数据库连接池连接泄露的思路
1230 2
|
5月前
|
安全 搜索推荐 Java
Java系统中的错误码设计问题之确保内外有别并避免暴露敏感数据如何解决
Java系统中的错误码设计问题之确保内外有别并避免暴露敏感数据如何解决
43 0
|
10天前
|
Java 调度
【JavaEE】——线程的安全问题和解决方式
【JavaEE】——线程的安全问题和解决方式。为什么多线程运行会有安全问题,解决线程安全问题的思路,synchronized关键字的运用,加锁机制,“锁竞争”,几个变式
|
30天前
|
SQL JavaScript 程序员
数据库LIKE查询屡试不爽?揭秘大多数人都忽视的秘密操作符!
本文分析了因数据库中的不可见空白字符导致的数据查询问题,探讨了问题的成因与特性,并提出了使用 SQL 语句修复问题的有效方案。同时,总结了避免类似问题的经验和注意事项。
32 0
|
3月前
|
安全 算法 Java
数据库信息/密码加盐加密 —— Java代码手写+集成两种方式,手把手教学!保证能用!
本文提供了在数据库中对密码等敏感信息进行加盐加密的详细教程,包括手写MD5加密算法和使用Spring Security的BCryptPasswordEncoder进行加密,并强调了使用BCryptPasswordEncoder时需要注意的Spring Security配置问题。
220 0
数据库信息/密码加盐加密 —— Java代码手写+集成两种方式,手把手教学!保证能用!
|
8月前
|
SQL Java 关系型数据库
JDBC技术【SQL注入、JDBC批量添加数据、JDBC事务处理、其他查询方式】(三)-全面详解(学习总结---从入门到深化)
JDBC技术【SQL注入、JDBC批量添加数据、JDBC事务处理、其他查询方式】(三)-全面详解(学习总结---从入门到深化)
103 0
|
SQL Java 关系型数据库
定位频繁创建对象导致内存溢出风险之JDBC MySQL
定位频繁创建对象导致内存溢出风险之JDBC MySQL
261 0
|
存储 SQL 安全
高效掌握JDBC技术(二)| 掌握ORM思想 | 定义连接数据库的工具类(上)
高效掌握JDBC技术(二)| 掌握ORM思想 | 定义连接数据库的工具类
85 1
|
Java 数据库连接 数据库
高效掌握JDBC技术(二)| 掌握ORM思想 | 定义连接数据库的工具类(下)
高效掌握JDBC技术(二)| 掌握ORM思想 | 定义连接数据库的工具类
125 1
|
SQL Java 关系型数据库
JDBC概念及获取数据库连接的5种方式
JDBC概念及获取数据库连接的5种方式
100 0