为了防止用户使用sql语句注入攻击数据库,可以使用Statement接口的子接口
java.sql.PreparedStatement extends Statement
该接口表示预编译的 SQL 语句的对象,SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。
如何获取PreparedStatement的实现类对象呢?
Users类
java.sql.PreparedStatement extends Statement
该接口表示预编译的 SQL 语句的对象,SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。
如何获取PreparedStatement的实现类对象呢?
使用Connection接口中的方法PreparedStatement prepareStatement(String sql) 创建一个 PreparedStatement 对象将SQL 语句发送到数据库。
prepareStatement方法返回的是 PreparedStatement接口的实现类对象,由mysql驱动提供
代码实现一个用户登录案例:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
public class Login {
public static void main(String[] args) {
/**
* 创建键盘录入
*/
Scanner sc = new Scanner(System.in);
System.out.print("请输入用户名:");
String username = sc.nextLine();
System.out.print("请输入密码:");
String password = sc.nextLine();
/**
* 使用工具类JDBCUtils中的方法getConnection获取数据库连接对象
*/
Connection conn = JDBCUtils.getConnection();
/**
* 获取预编译的执行者对象,需要传递的sql语句中可以使用?占位符代替实际参数
*/
String sql = "SELECT * FROM users WHERE username=? AND PASSWORD = ?";
/**
* 使用PreparedStatement接口中的方法,设置?占位符的实际参数
* void setObject(int parameterIndex,Object x)
* 参数:
* int parameterIndex:要设置的第几个?占位符;1,2,3.....
* Object x:给?占位符设置的实际参数
* 注意:
* 必须保证给所有的?占位符都设置实际参数,有几个?占位符就调用几次setObject方法
*/
PreparedStatement pst = null;
ResultSet rs = null;
try {
pst = conn.prepareStatement(sql);
pst.setObject(1, username);
pst.setObject(2, password);
rs = pst.executeQuery();
/**
* 处理查询结果
*/
if (rs.next()) {
System.out.println("登录成功!");
System.out.println(rs.getString("username") + "\t" + rs.getString("password"));
} else {
System.out.println("您输入的用户名或者密码有误!");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs, pst, conn);
sc.close();
}
}
}
使用PreparedStatement预编译的执行者对象对数据库进行增删改查
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class Demo03 {
public static void main(String[] args) throws Exception {
/**
* 获取数据库连接对象
*/
Connection conn = JDBCUtils.getConnection();
/**
* 方法调用实现相应功能
*/
insert(conn);
update(conn);
delete(conn);
/**
* 开发中常用方式
*/
select(conn);
}
/**
* 把数据库中查询出来的每一行记录,存储到一个javabean对象中
* 把多个javabean对象存储到一个集合中
*/
private static void select(Connection conn) throws SQLException {
/**
* 使用?占位符拼接select语句
*/
String sql = "SELECT * FROM users WHERE username IN(?,?,?)";
/**
* 获取预编译的执行者对象
*/
PreparedStatement pst = conn.prepareStatement(sql);
/**
* 设置?占位符的实际参数
*/
pst.setObject(1, "java");
pst.setObject(2, "python");
pst.setObject(3, "golang");
/**
* 执行sql语句,获取查询结果集
*/
ResultSet rs = pst.executeQuery();
/**
* 定义一个存储Users对象的集合
*/
ArrayList<Users> list = new ArrayList<Users>();
while (rs.next()) {
/**
* 取出结果
*/
int uid = rs.getInt("uid");
String username = rs.getString("username");
String password = rs.getString("password");
/**
* 把数据库中查询出来的每一行记录,存储到一个javabean对象中
*/
Users u = new Users(uid, username, password);
/**
* 把对象存储到集合中
*/
list.add(u);
}
/**
* 可以把这个集合传递到前台的页面上,给用户遍历显示
*/
for (Users u : list) {
System.out.println(u);
}
/**
* 释放资源
*/
JDBCUtils.close(rs, pst, conn);
}
/**
* 使用java程序对数据库表的数据进行删除
*/
private static void delete(Connection conn) throws SQLException {
//使用?占位符拼接delete语句
String sql = "DELETE FROM users WHERE uid IN (?,?)";
//获取预编译的执行者对象
PreparedStatement pst = conn.prepareStatement(sql);
//设置?占位符的实际参数
pst.setObject(1, 1);
pst.setObject(2, 2);
//使用预编译的执行者对象,执行sql语句
int row = pst.executeUpdate();
//处理结果集
if(row>0){
System.out.println(row+"行数据,删除成功!");
}else{
System.out.println("数据删除失败!");
}
//释放资源
JDBCUtils.close(null, pst, conn);
}
/**
* 使用java程序对数据库表的数据进行修改
*/
private static void update(Connection conn) throws SQLException {
//使用?占位符拼接update语句
String sql = "UPDATE users SET PASSWORD=? WHERE username=?";
//获取预编译的执行者对象
PreparedStatement pst = conn.prepareStatement(sql);
//设置?占位符的实际参数
pst.setObject(1, "马云");
pst.setObject(2, "马化腾");
//使用预编译的执行者对象,执行sql语句
int row = pst.executeUpdate();
//处理结果集
System.out.println(row);
//7.释放资源
JDBCUtils.close(null, pst, conn);
}
/*
* 使用java程序对数据库表进行添加数据
*/
private static void insert(Connection conn) throws SQLException {
//使用?占位符拼接insert语句
String sql = "INSERT INTO users(username,PASSWORD) VALUES(?,?)";
//获取预编译的执行者对象
PreparedStatement pst = conn.prepareStatement(sql);
//设置?占位符的实际参数
pst.setObject(1, "乔布斯");
pst.setObject(2, "比尔盖茨");
//使用预编译的执行者对象,执行sql语句
int row = pst.executeUpdate();
//处理结果集
System.out.println(row);
//释放资源
JDBCUtils.close(null, pst, conn);
}
}
Users类
import java.io.Serializable;
/**
* javabean:数据库中表与java中类对应
* users表-->Users类
* 表中的列(cid,username,password)-->类中的成员变量
* 表中的行-->Users对象(多行数存储在一个集合中)
*
* 包含:
* 1.私有的成员变量
* 2.公共的get/set方法
* 3.空参数构造方法
* 4.toString方法
* 5.实现序列化接口
*
*/
public class Users implements Serializable {
private static final long serialVersionUID = 5169686823386234072L;
private int uid;
private String username;
private String password;
public Users() {
super();
}
public Users(int uid, String username, String password) {
super();
this.uid = uid;
this.username = username;
this.password = password;
}
@Override
public String toString() {
return "Users [uid=" + uid + ", username=" + username + ", password=" + password + "]";
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}