1、背景:当写sql语句的参数是界面上输入的数据时,使用Statement时需要组合字符串,如下,这样操作易出错,且不好分析,则引入了PreparedStatement。
Statement stmt=conn.createStatement();
int count=stmt.executeUpdate("insert into employee values("+Integer.parseInt(id.getText())+",'"+name.getText()+"',27,15000,'欧洲',101)");
2、PreparedStatement是把sql预编译出来,使用?把要赋值的字段表示出来,按顺序把?替换成实际的值,这样方便跟踪,代码也比较清晰。代码如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
public class PreparedStatementDemo {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/sh?characterEncoding=utf-8&user=sh&password=123456");
//预编译SQL,也称动态SQL,跟方法一样,使用时传参数就可以
//1 使用?把要赋值的字段表示出来
//2 按顺序把?替换成实际的值
String sql="update employee set name=?,age=? where id=?";
//给pstmt设置?的值 必须全部按照顺序赋值
PreparedStatement pstmt=conn.prepareStatement(sql);
pstmt.setString(1,"djw");//第一个参数是参数索引,从1开始,把第一个参数替换为'djw'
pstmt.setInt(2,19);
pstmt.setInt(3,109);
int count=pstmt.executeUpdate();
if(count==0){
System.out.println("数据更新失败");
}else{
System.out.println("成功更新数据:"+count+"条");
}
String sql1="insert into employee values(?,?,?,?,?,?)";
//给pstmt设置?的值 必须全部按照顺序,且必须是数据库定义的数据类型赋值
PreparedStatement pstmt1=conn.prepareStatement(sql1);
pstmt1.setInt(1,111);
pstmt1.setString(2,"que");
pstmt1.setInt(3,18);
pstmt1.setInt(4,16000);
pstmt1.setString(5,"db");
pstmt1.setInt(6,101);
int count1=pstmt1.executeUpdate();
if(count1==0){
System.out.println("数据添加失败");
}else{
System.out.println("成功添加数据:"+count+"条");
}
pstmt.close();
pstmt1.close();
conn.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
3、使用PreparedStatement把数据库连接、增删改查的公共方法封装在一个类中,把需要执行的sql和要赋值的字段进行参数化:
特殊说明:对要赋值的字段进行参数化用到特殊方法:java的不定向参数,用法参考:
//java 不定向参数:int ... numbers,传0-n个整形的参数,相当于一个int不定长的数组
public void add(int ... numbers){
for(int i=0;i<numbers.length;i++){
}
}
封装方法参考如下代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DBUtil {
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/sh";
private static final String NAME = "sh";
private static final String password = "123456";
private Connection conn;
public DBUtil() {
try {
Class.forName(DRIVER);
conn = DriverManager.getConnection(URL, NAME, password);
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 执行所有查询的方法 (String sql:代表预编译的SQL语句;Object...params:代表向SQL语句设置数值的集合)
public ResultSet executeQuery(String sql, Object... params) {
ResultSet rs = null;
try {
PreparedStatement psSelect = conn.prepareStatement(sql);
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
psSelect.setObject(i + 1, params[i]);
}
}
rs = psSelect.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
//执行所有更新的方法:增加/修改/删除( String sql:代表预编译的SQL语句 Object...params:代表向SQL语句设置数值的集合)
public int executeUpdate(String sql, Object... params) {
int column = 0;
try {
PreparedStatement psSelect = conn.prepareStatement(sql);
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
psSelect.setObject(i + 1, params[i]);
}
}
column = psSelect.executeUpdate();
psSelect.close();
} catch (SQLException e) {
e.printStackTrace();
}
return column;
}
}
调用方法:
import java.sql.ResultSet;
import java.sql.SQLException;
public class Test {
public static void main(String[] args) {
DBUtil du = new DBUtil();
ResultSet rs = du.executeQuery("select * from employee where age>=? and salary>?", 20, 12000);
du.executeUpdate("insert into employee values(?,?,?,?,?,?)", 118, "李",27, 15000, "俄罗斯", 101);
try {
while (rs.next()) {
System.out.print(rs.getInt(1) + " ");// 把第一列的数据取出,转换为整型
System.out.print(rs.getString(2) + " ");
System.out.print(rs.getInt(3) + " ");
}
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}