• dljd_006_关于jdbc关闭连接问题的发散


    一、数据库连接的示例  

    package edu.aeon.jdbc;
    import java.sql.Connection;
    import java.sql.Driver;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    /**
     * [说明]:使用jdbc连接mysql数据库
     * @author aeon
     * 连接mysql数据库的步骤:
     *     一、准备工作
     *         1.1新建一个java项目
     *         1.2在该项目下新建一个lib(外部类库)文件夹(new->folder)
     *         1.3将我们的mysql驱动放到lib文件夹下
     *         1.4将mysql驱动(即这个jar文件)添加(右键->build path->add to build path)到eclipse的构建路径里(作用同我们的环境变量)
     *             这样的话eclipse可以识别mysql驱动中的字节码文件。
     *         1.5建包和类
     *     二、正式步骤
     *         2.1加载/注册驱动驱动(目的是让jvm可以使用驱动类)
     *         2.2获取和数据库服务器的连接(java程序是客户端    mysql是个服务器)
     *             2.2.1指定要连接到mysql服务器的相关信息(用户名&&密码&&url+端口+数据库名)
     *         2.3连接服务器
     *         2.4通过连接对象获取执行sql语句的对象
     *         2.5通过获取到的sql语句对象来执行sql
     *         2.6遍历输出结果
     *         2.7关闭流    遵循原则:后打开的先关闭
     */        
    public class TestJdbc {
        public static void main(String[] args) {
            Connection connection=null;
            Statement statement=null;
            ResultSet resultSet=null;
            try {
                //2.1加载/注册驱动
                //driver是jdbc声明的标准接口、com.mysql.jdbc.Driver是mysql数据库厂商根据这个标准做的实现、注意这两个Driver是有区别的。
                Driver driver=new com.mysql.jdbc.Driver(); //接口声明引用指向实现类的对象
                DriverManager.registerDriver(driver);
                //2.2获取和数据库服务器的连接(java程序是客户端    mysql是个服务器)
                String username="root"; //用户名
                String password="root";    //密码
                //url中的jdbc:mysql说明:jdbc是由sun公司制定的一套网络协议  jdbc:mysql是指jdbc协议下的mysql子协议。
                String url="jdbc:mysql://localhost:3306/db_test";
                //2.3连接服务器     Connection是jdbc规范中声明的接口
                connection=DriverManager.getConnection(url, username, password);
                //2.4通过连接对象获取执行sql语句的对象
                statement=connection.createStatement();
                String sql="select * from user";
                //2.5通过获取到的sql语句对象来执行sql
                resultSet=statement.executeQuery(sql);//executeQuery对应的去执行DQL语句
                //2.6遍历输出结果
                System.out.println("用户id	用户名	用户密码");
                while(resultSet.next()){//初始时指向表前面、和游标相似 .next()方法表示移动到下一条记录并判断有没有数据。如果有则结果为true。否则false
                    //resultSet.getString(1);//根据记录下标来获取该下标所对应的字段值、不推荐
                    int userId=resultSet.getInt("userId");//根据表字段名获取该行记录上的字段名所对应的字段值
                    String userName=resultSet.getString("userName");
                    String userPw=resultSet.getString("userpw");//数据库中的字段不区分大小写
                    System.out.println(userId+"	"+userName+"	"+userPw);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                //2.7关闭流    遵循原则:后打开的先关闭
                if(null!=resultSet){
                    try {
                        resultSet.close();
                    } catch (SQLException e) {
                        System.out.println("关闭流失败!--->resultSet");
                        e.printStackTrace();
                    }
                }
                if(null!=statement){
                    try {
                        statement.close();
                    } catch (SQLException e) {
                        System.out.println("关闭流失败!--->statement");
                        e.printStackTrace();
                    }
                }
                if(null!=connection){
                    try {
                        connection.close();
                    } catch (SQLException e) {
                        System.out.println("关闭流失败!--->connection");
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    二、关于try...catch的思考

      1.为什么注册数据库驱动、拿到数据库的连接、连接获得执行SQL的对象、然后用获得SQL的对象去执行SQL得到结果集、遍历结果集会放到一个try{ //some code }catch(SQLException e ){//some code}?

        因为如果出现注册数据库驱动失败、我们能拿到数据库的连接吗?既然拿不到连接我们能根据连接获得执行SQL的对象吗?能得到结果集吗? 肯定不能啊、所以这种有前后因果关系的异常我们总体处理。这样当其中某一环节出现问题时,那么下面的环节就没必要去执行了、直接进入catch...finally环节。

      2.为什么关闭数据库资源要单独进行分批处理?可不可以放到一个try...catch里面总体处理?

        如果第一个问题你理解透彻了,那么这个问题就简单了,因为这个问题是建立在第一个问题基础上的。

        为什么要进行单独处理?因为哪怕是你resultSet关闭失败了,我也要去关闭其它两个连接资源啊,不用了,所以我要去关闭啊,如果合起来总体处理的话,当resultSet关闭失败了,直接进入catch...finally环节,那么其它两个资源关闭问题就直接跳过了呀,学过try catch语句块的都应该知道这个问题。所以这两个就一直占用着资源、我们知道服务器是放置在网络上被大部分用户去访问的,那么这成百上千的都占用这点资源呢?上亿的也占用这点资源呢?服务器能受得了?虽然关闭连接这个过程很少出现关闭资源失败的情况,但是我们作为开发人员应该要考虑到千千万万种可能。所以关闭数据库资源方面我们不能合起来处理,最好单独处理。

      3.关闭数据库资源之前要判断这个资源是否为null、如果不为null,我们才可以close(),如果为null,那么接下来会执行null.close()这种nullpointexception异常代码块,应该过滤掉这种可能。

      

    如有任何疑问可联系邮箱: 给我发邮件、或直接联系QQ:1584875179 || 点返回首页

  • 相关阅读:
    UITextField editingDidEnd 不调用(不响应)
    修改 Navigation Bar 返回按钮文字和图片
    HTTPS抓包
    brew 基本使用方法
    Linux基本命令
    AR 初探
    汇编学习
    ios GCD ---- (1)
    axios导出或者下载
    Vue绑定图片src出现的问题
  • 原文地址:https://www.cnblogs.com/aeon/p/10068866.html
Copyright © 2020-2023  润新知