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

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

    昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。
  • 相关阅读:
    Git 基础
    SharePoint 2013 对象模型操作"网站设置"菜单
    SharePoint 2013 隐藏部分Ribbon菜单
    SharePoint 2013 Designer系列之数据视图筛选
    SharePoint 2013 Designer系列之数据视图
    SharePoint 2013 Designer系列之自定义列表表单
    SharePoint 2013 设置自定义布局页
    SharePoint 2013 "通知我"功能简介
    SharePoint 2013 创建web应用程序报错"This page can’t be displayed"
    SharePoint 禁用本地回环的两个方法
  • 原文地址:https://www.cnblogs.com/htj10/p/13910225.html
Copyright © 2011-2022 走看看