zoukankan      html  css  js  c++  java
  • 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("学号	姓名	老师");
        while(rs.next())
        {
            System.out.println(rs.getInt(1)+"	"+rs.getString(2)+"	"+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)+"	"+rs.getString(2)+"	"+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

    常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。

    昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。
  • 相关阅读:
    ssh_jar包选择
    去js校验
    CSS
    html(HyperText Markup Language)--超文本标记语言
    Java compiler level does not match解决方法
    linux上面是否有安装redis,redis启动
    mybatis 详解(九)------ 一级缓存、二级缓存
    mybatis 详解(八)------ 懒加载
    mybatis 详解(六)------通过mapper接口加载映射文件
    mybatis 详解(七)------一对一、一对多、多对多
  • 原文地址:https://www.cnblogs.com/htj10/p/13910225.html
Copyright © 2011-2022 走看看