1.对比Statement与PreparedStatement
①Statement存在sql注入问题,PreparedStatement解决了sql注入问题。
②Statement是编译一次执行一次,PreparedStatement是编译一次,可执行n次。PreparedStatement效率较高一些。
③PreparedStatement会在编译阶段做类型的安全检查。
综上所述,PreparedStatement使用较多,只有极少的情况下会使用Statement。
什么情况下要使用Statement呢?
业务方面要求必须支持sql注入的时候。Statement支持sql注入,凡是业务方面要求需要进行sql语句拼接的,必须使用Statement。
2.PreparedStatement完成增加
package test;
import java.sql.*;
import java.util.ResourceBundle;
public class jdbcTest07 {
public static void main(String[] args) {
//使用资源绑定器绑定属性配置文件
ResourceBundle bundle = ResourceBundle.getBundle("JDBC");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection con = null;
PreparedStatement ps = null;
try {
//1.注册驱动
Class.forName(driver);
//2.获得连接
con = DriverManager.getConnection(url, user, password);
//3.获取预编译的数据库操作对象
String sql = "insert into test(神魔恋) values(?)";
ps = con.prepareStatement(sql);
ps.setString(1,"大明都亡了!");
//4.执行sql语句
int count = ps.executeUpdate();
System.out.println(count == 1 ? "修改成功" : "修改失败");
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try {
if(ps != null)
ps.close();
}
catch (SQLException e) {
e.printStackTrace();
}
try {
if(con != null)
con.close();
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
}
3.PreparedStatement完成修改
只需要更改少量代码:
//3.获取预编译的数据库操作对象
String sql = "update test set 神魔恋=? where id=?";
ps = con.prepareStatement(sql);
ps.setString(1,"你好");
ps.setInt(2,7);
完成删除原理一样,在此不再赘述。
4.JDBC事物机制
自动提交是很不安全的,我们要将自动提交转换为手动提交。
5.JDBC工具类,简化JDBC编程
package test.utils;
import com.mysql.cj.AppendingBatchVisitor;
import java.sql.*;
/**
* JDBC工具类,简化JDBC编程
*/
public class DBUtil {
/**
* 工具类中的构造方法都是私有的
* 因为工具类当中的方法都是静态的,不需要new对象,直接采用类名调用。
*/
//静态代码块在类加载时执行,并且只执行一次
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接对象
* @return 连接对象
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:mysql://192.168.8.120:3306/ourleetcode?" +
"useUnicode=true&characterEncoding=utf8&serverTimezone=GMT","root", "10086");
}
/**
* 关闭资源
* @param con 连接对象
* @param stmt 数据库操作对象
* @param rs 结果集
*/
public static void close(Connection con, Statement stmt, ResultSet rs) {
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
6.测试DBUtil是否好用
package test;
import test.utils.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class jdbcTest08 {
public static void main(String[] args) {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//获取连接
con = DBUtil.getConnection();
//获取预编译的数据库操作对象
String sql = "update test set 神魔恋=? where id=?";
ps = con.prepareStatement(sql);
ps.setString(1,"你sei呀?");
ps.setInt(2,7);
//执行sql语句
int count = ps.executeUpdate();
System.out.println(count == 1 ? "修改成功" : "修改失败");
}
catch (Exception e) {
e.printStackTrace();
}
finally {
//释放资源
DBUtil.close(con, ps, rs);
}
}
}
可以看到,简化了非常多的代码。
但是请注意:用这个的前提是你默写的十分熟练了(在IDEA中不算,要达到在记事本中默写的一字不差才可以)!!!!!