1. ResultSet[结果集] 827
1.1 基本介绍
1.表示数据库结果集的数据表,通常通过执行查询数据库的语生成
2.ResultSet对象保持一个光标指向其当前的数据行。最初, 光标位于第一行之前
3. next方法将光标移动到下一行,并且由于在ResultSet对象中没有更多行时返回false,因此可以在while循环中使用循环来遍历结果集
1.2 应用实例
代码在com.stulzl.resultset_.
ResultSet_
package com.stulzl.resultset_;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
//演示select语句返回ResultSet,并取出结果 827
@SuppressWarnings({"all"})
public class ResultSet_ {
public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
//通过 Properties 对象获取配置文件的信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\mysql.properties"));
//获取相关值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
//1.注册驱动
Class.forName(driver);//建议写上
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
//System.out.println("方式5="+connection);
//3.得到Statement
Statement statement = connection.createStatement();
//4.组织sql语句
String sql = "select id,name,sex,borndate from actor";
//执行给定的 SQL 语句,该语句返回单个 ResultSet 对象
/*
+----+-----------+-----+---------------------+
| id | name | sex | borndate |
+----+-----------+-----+---------------------+
| 2 | 刘德华 | 男 | 1970-12-12 00:00:00 |
| 3 | jack | 男 | 1990-11-11 00:00:00 |
+----+-----------+-----+---------------------+
*/
ResultSet resultSet = statement.executeQuery(sql);
//5.使用while循环取出数据
while(resultSet.next()){//next()可以让光标向后移动,如果没有更多行则返回false
int id = resultSet.getInt(1);//获取改行第一列
String name = resultSet.getString(2);//获取改行第二列
String sex = resultSet.getString(3);//获取改行第三列
Date date = resultSet.getDate(4);//获取该行第四列
System.out.println(id+"\t"+name+"\t"+sex+"\t"+date);
}
//关闭连接
resultSet.close();
statement.close();
connection.close();
}
}
配置文件再src下面 mysql.properties
user=root
password=lzl
url=jdbc:mysql://localhost:3306/hsp_db02
driver=com.mysql.jdbc.Driver
数据库E:\java学习\初级\course168\db_
actor_
-- 创建测试表 演员表 822
CREATE TABLE actor ( -- 演员表
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(32) NOT NULL DEFAULT '',
sex CHAR(1) NOT NULL DEFAULT '女',
borndate DATETIME,
phone VARCHAR(12));
SELECT * FROM actor
-- 增加两条记录,用于测试ResultSet
INSERT INTO actor
VALUES(NULL,'刘德华','男','1970-12-12','110');
INSERT INTO actor
VALUES(NULL,'jack','男','1990-11-11','112');
2. Statement 828
2.1 基本介绍
1. Statement对象用于执行静态SQL语句并返回其生成的结果的对象
2.在连接建立后,需要对数据库进行访问,执行命名或是SQL语句,可以通过
Statement [存在SQL注入问题]
PreparedStatement [预处理]
CallableStatement [存储过程]
3. Statement对象执行SQL 语句,存在SQL注入风险
4. SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的SQL语句段或命令,恶意攻击数据库。sql injection.sql
5.要防范SQL注入,只要用PreparedStatement(从Statement扩展而来)取代Statement就可以了,一会用java演示下.
2.1.1 演示sql注入问题 828
代码在E:\java学习\初级\course169\db_
sql_injection
#演示sql注入问题 828
-- 创建一张表
CREATE TABLE admin ( -- 管理员表
NAME VARCHAR(32) NOT NULL UNIQUE,
pwd VARCHAR(32) NOT NULL DEFAULT '') CHARACTER SET utf8
-- 添加数据
INSERT INTO admin VALUES('tom','123');
-- 查询某个管理是否存在
SELECT *
FROM admin
WHERE NAME = 'tom' AND pwd = '123'
-- SQL注入
-- 输入用户名 为 1' or
-- 输入万能密码 为 or '1'= '1
SELECT *
FROM admin
WHERE NAME = '1' OR' AND pwd = 'OR '1'= '1'
2.1.2 用java演示statement注入问题 829
代码在com.stulzl.statement_
Statement_
package com.stulzl.statement_;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
import java.util.Scanner;
//演示statement的注入问题 829
@SuppressWarnings({"all"})
public class Statement_ {
public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
Scanner scanner = new Scanner(System.in);
//让用户输入管理员名和密码
//输入用户名 为 1' or
//输入万能密码 为 or '1'= '1
System.out.println("请输入管理员名字");//next(): 当接收到 空格或者 '就是表示结束
String admin_name = scanner.nextLine();//说明,如果希望看到 SQL 注入,这里需要用 nextLine回车代表结束
System.out.println("请输入密码");
String admin_pwd = scanner.nextLine();
//通过 Properties 对象获取配置文件的信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\mysql.properties"));
//获取相关值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
//1.注册驱动
Class.forName(driver);//建议写上
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
//System.out.println("方式5="+connection);
//3.得到Statement
Statement statement = connection.createStatement();
//4.组织sql语句
String sql = "select name , pwd from admin where name='"
+admin_name+"' and pwd = '"+admin_pwd+"'";
ResultSet resultSet = statement.executeQuery(sql);
if(resultSet.next()){//如果查询到一条记录存在,则说明该管理存在
System.out.println("恭喜登录成功");
}else {
System.out.println("对不起登陆失败");
}
//关闭连接
resultSet.close();
statement.close();
connection.close();
}
}
3. PreparedStatement(预处理) 830
3.1 基本介绍
1. PreparedStatement执行的SQL语句中的参数用问号(?)来表示,调用PreparedStatement对象的setXxx()方法来设置这些参数. setXxx()方法有两个参数,第一个参数是要设置的SQL语句中的参数的索引(从1开始),第二个是设置的SQL语句中的参数的值
2.调用executeQuery(),返回ResultSet对象
3.调用executeUpdate():执行更新,包括增、删、修改
3.2 预处理好处
1.不再使用+拼接sq|语句,减少语法错误
2.有效的解决了sq|注入问题!
3.大大减少了编译次数,效率较高
代码在com.stulzl.preparedstatement_
PreparedStatement_
package com.stulzl.preparedstatement_;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.*;
import java.util.Properties;
import java.util.Scanner;
//演示PreparedStatement预处理的使用 830
@SuppressWarnings({"all"})
public class PreparedStatement_ {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
//让用户输入管理员名和密码
//输入用户名 为 1' or
//输入万能密码 为 or '1'= '1
System.out.println("请输入管理员名字");//next(): 当接收到 空格或者 '就是表示结束
String admin_name = scanner.nextLine();//说明,如果希望看到 SQL 注入,这里需要用 nextLine回车代表结束
System.out.println("请输入密码");
String admin_pwd = scanner.nextLine();
//通过 Properties 对象获取配置文件的信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\mysql.properties"));
//获取相关值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
//1.注册驱动
Class.forName(driver);//建议写上
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
//3.组织sql语句
//3.1这里的?相当于占位符
String sql = "select name , pwd from admin where name= ? and pwd = ? ";
//3.2 preparedStatement 对象实现了 PreparedStatement 接口的实现类的对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//3.3给?赋值
preparedStatement.setString(1,admin_name);//用户名
preparedStatement.setString(2,admin_pwd);//密码
//4. 执行 select 语句使用 executeQuery
// 如果执行的是 dml(update, insert ,delete)使用 executeUpdate()
// 这里执行 executeQuery ,不要在写 sql
ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next()){//如果查询到一条记录存在,则说明该管理存在
System.out.println("恭喜登录成功");
}else {
System.out.println("对不起登陆失败");
}
//关闭连接
resultSet.close();
preparedStatement.close();
connection.close();
}
}
3.3 演示preparedStatement的executeUpdate()方法 831
代码在com.stulzl.preparedstatement_02
executeUpdate_
package com.stulzl.preparedstatement_02;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.Scanner;
//演示preparedStatement的executeUpdate()方法 831
@SuppressWarnings({"all"})
public class executeUpdate_ {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
//让用户输入管理员名和密码
//输入用户名 为 1' or
//输入万能密码 为 or '1'= '1
System.out.println("请输入管理员名字");//next(): 当接收到 空格或者 '就是表示结束
String admin_name = scanner.nextLine();//说明,如果希望看到 SQL 注入,这里需要用 nextLine回车代表结束
// System.out.println("请输入密码");
// String admin_pwd = scanner.nextLine();
//通过 Properties 对象获取配置文件的信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\mysql.properties"));
//获取相关值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
//1.注册驱动
Class.forName(driver);//建议写上
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
//3.组织sql语句
//3.1这里的?相当于占位符
//添加记录
//String sql = "insert into admin values(?, ?)";
//修改记录
//String sql = "update admin set pwd=? where name=?";
//删除记录
String sql = "delete from admin where name= ?";
//3.2 preparedStatement 对象实现了 PreparedStatement 接口的实现类的对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//3.3给?赋值
//添加
//preparedStatement.setString(1,admin_name);//用户名
//preparedStatement.setString(2,admin_pwd);//密码
//这个是修改操作这么些因为要保证pwd和name对应
//preparedStatement.setString(1,admin_pwd);//用户名
//preparedStatement.setString(2,admin_name);//密码
//删除对应因为只需要name对应就行了
preparedStatement.setString(1,admin_name);//用户名
// 执行的是 dml(update, insert ,delete)使用 executeUpdate()
int rows = preparedStatement.executeUpdate();
System.out.println(rows>0?"执行成功":"执行失败");
//关闭连接
preparedStatement.close();
connection.close();
}
}