Java中的JDBC

JDBC:Java Database Connectivity

JDBC Statement与PreparedStatement的区别

参考:https://www.jianshu.com/p/8afaf935d073  https://www.jianshu.com/p/d73e83bb5d7d

1、 PreparedStatement接口继承Statement, PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。

2、作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。三种方法 execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数

3、使用“?”占位符提升代码的可读性和可维护性. 

4、使用 PreparedStatement 最重要的一点好处是它拥有更佳的性能优势,SQL语句会预编译在数据库系统中。执行计划同样会被缓存起来,它允许数据库做参数化查询。

5、PreparedStatement可以防止SQL注入式攻击。在使用参数化查询的情况下,数据库系统(eg:MySQL)不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有破坏性的指令,也不会被数据库所运行

作者:疯癫的猪猪猪
链接:https://www.jianshu.com/p/d73e83bb5d7d
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 
1.PreparedStatement接口继承了Statement,PreparedStatement实例包含已编译的SQL语句,所以其执行速度要快于Statement对象。
2.作为Statement的子类,PreparedStatment继承了Statement的所有功能。三种方法execute,executeQuery和executeUpdate已被更改以使之不再需要参数。
3.在JDBC应用中,在任何时候都不要是使用Statement,原因如下:
  1)、代码的可读性和可维护性。Statement需要不断地拼接,而PreparedStatement不会。
  2)、PreparedStatement尽最大可能提高性能。DB有缓存机制,相同的预编译语句再次被调用不会再次需要编译。
  3)、最重要的一点是极大的提高了安全性。Statement容易被SQL注入,而PreparedStatement传入的内容和参数不会和sql语句发生任何匹配关系。

例子

1. Statement的例子
// JDBC 的简单使用例子(Statement)
Properties props = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
props.load(loader.getResourceAsStream("db.properties"));
String driver = props.getProperty("db.driver");
String url = props.getProperty("db.url");
String dbUser = props.getProperty("db.user");
String dbPassword = props.getProperty("db.password");

String sql = "select s.id,s.name,t.name from tb_teachers t, tb_students s where t.id = s.teacher_id";

Connection conn = null;
Statement stm = null;
ResultSet rs = null;
try{
    //1. 使用反射,加载驱动
    Class.forName(driver);
    //2. 使用DriverManager 获取数据库连接
    conn = DriverManager.getConnection(url, dbUser, dbPassword);
    //3. 使用Connection 来创建一个Statement对象
    stm = conn.createStatement();
    //4. 执行sql语句 (有三种:execute, excuteQuery, excuteUpdate)
    rs = stm.executeQuery(sql);
    //5. 遍历查询结果
    System.out.println("学号\t姓名\t老师");
    while(rs.next())
    {
        System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
    }
}catch(Exception e){
    e.printStackTrace();
}finally{
    // 释放资源
    if(rs!=null){
        try {
            rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    if(stm!=null){
        try {
            stm.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    if(conn!=null){
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

}
View Code

2. PrepareStatement的例子

Properties props = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
props.load(loader.getResourceAsStream("db.properties"));
String driver = props.getProperty("db.driver");
String url = props.getProperty("db.url");
String dbUser = props.getProperty("db.user");
String dbPassword = props.getProperty("db.password");

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
    //1. 使用反射,加载驱动
    Class.forName(driver);
    //2. 使用DriverManager 获取数据库连接
    conn = DriverManager.getConnection(url, dbUser, dbPassword);
    //3. 使用Connection 来创建一个PreparedStatement对象
    ps = conn.prepareStatement("insert into tb_students(id,name,teacher_id) values(?,?,?)");
//            ps.setInt(1, 3);
    ps.setString(1, "4");
    ps.setString(2, "马丁2");
    ps.setString(3, "1001");
    //4. 执行sql语句 
    ps.executeUpdate();//INSERT, UPDATE or DELETE 语句
    
}catch(Exception e){
    e.printStackTrace();
}finally{
    // 释放资源
    if(rs!=null){
        try {
            rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    if(ps!=null){
        try {
            ps.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    if(conn!=null){
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
View Code

3. 使用自己封装的工具类

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
    //1. 获取数据库连接
    conn = JDBCUtil.getConnection();
    //2. 使用Connection 来创建一个PreparedStatement对象
    ps = conn.prepareStatement("select * from tb_students where id=? and name=?");
    ps.setInt(1, 2);
    ps.setString(2, "Wang");
    //3. 执行sql语句 
    rs = ps.executeQuery();
    //4. 遍历查询结果
    while(rs.next())
    {
        System.out.println(rs.getString(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
    }
}catch(Exception e){
    e.printStackTrace();
}finally{
    // 释放资源
    JDBCUtil.closeAll(rs, ps, conn);
}
View Code
JDBCUtil类:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ResourceBundle;

public class JDBCUtil {
    private JDBCUtil(){}
    
    private static String driverClass;
    private static String url;
    private static String username;
    private static String password;
    
    static{
        //此对象是用于加载properties文件数据的
        //命名格式为:配置文件名_语言代码_国家代码.properties,在没有加“语言代码_国家代码”的情况下
        //ResourceBundle默认读取的是系统所使用地区码的配置文件,
        //例子中,系统默认为zh_CN,所以读取的就是zh_CN结尾的配置文件。
        ResourceBundle rb = ResourceBundle.getBundle("db");//在classpath下,先找 db_zh_CN.properties, 若无, 再找 db.properties, 再无,异常。
        driverClass = rb.getString("db.driver");
        url = rb.getString("db.url");
        username = rb.getString("db.user");
        password = rb.getString("db.password");
        try {
            Class.forName(driverClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    
    //得到连接的方法
    public static Connection getConnection() throws Exception{
        return DriverManager.getConnection(url, username, password);
    }
    
    //关闭资源的方法
    public static void closeAll(ResultSet rs,Statement stmt,Connection conn){
        //关闭资源
        if(rs!=null){
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if(stmt!=null){
            try {
                stmt.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            stmt = null;
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}
View Code

配置文件db.properties 放在src下,内容如下

# mysql驱动
db.driver=com.mysql.jdbc.Driver
# 数据库url
db.url=jdbc:mysql://127.0.0.1:3306/shop
# 数据库用户名   密码 
db.user=root
db.password=123456

 

posted @ 2020-11-01 17:03  htj10  阅读(152)  评论(0编辑  收藏  举报
TOP