• 浅析B/S架构数据库连接方式


    前言
    在许许多多的B/S架构系统中都涉及到了数据库的链接,那么对于数据库连接的方式有哪些?可能出现的问题是什么?
     
    目录
    1.普通连接方式
    2.单例模式
    3.连接池
     
    分析
    普通连接:
    下面是我们一般使用的普通连接方式的代码(jsp)
    package com.jdbc.dao;
    import java.sql.*;
     
    public class BaseDAO {
            //打开数据库链接
            public Connection getConn()
            {
                    Connection conn = null;
                    try {
                            //加载驱动
                            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
                            //打开链接
                            conn = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;DatabaseName = epetDB","sa","sa");
                    } catch (ClassNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                    } catch (SQLException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                    }
                    return conn;
            }
            //(重写)关闭链接
            public void Close(Connection conn,PreparedStatement pstmt,ResultSet rs)
            {
                    try {
                            //关闭结果集
                            if (rs != null) {
                                    rs.close();
                            }
                            //关闭PerparedStatement对象
                            if (pstmt != null) {
                                    pstmt.close();
                            }
                            //关闭链接
                            if (conn != null) {
                                    conn.close();
                            }
                    } catch (Exception e) {
                            // TODO: handle exception
                    }
            }
            //(重写)关闭链接
            public void Close(Connection conn,PreparedStatement pstmt)
            {
                    try {
                            //关闭PerparedStatement对象
                            if (pstmt != null) {
                                    pstmt.close();
                            }
                            //关闭链接
                            if (conn != null) {
                                    conn.close();
                            }
                    } catch (Exception e) {
                            // TODO: handle exception
                    }
            }
            //增删改操作
            public int Update(String sql,Object[] parm)
            {
                    int iRet = 0;
                    Connection conn = null;
                    PreparedStatement pstmt = null;
                    try {
                            conn = getConn();
                            pstmt = conn.prepareStatement(sql);
                            //循环赋值参数
                            for (int i = 0; i < parm.length; i++) {
                                    //为预编译sql设置参数
                                    pstmt.setObject(i+1, parm);
                            }
                            //执行SQL语句
                            iRet = pstmt.executeUpdate();
                    } catch (Exception e) {
                            e.printStackTrace();
                    }
                    finally
                    {
                            Close(conn,pstmt);
                    }
                    return iRet;
            }
    }

    普及:

    try{
    //可能出现异常的代码
    }catch(Execption e){
    //如果发生异常处理的代码
    }finally{
    //无论是否异常都会执行的代码
    try catch finally java中异常处理机制

    我们来分析一下写一段代码,其中Update方法是用来更新数据的,其中我们可以看到try中包含了getConn()方法用来获取Connection连接对象,到最后我们可以在finally代码块中看到Close()方法用来关闭创建的Connection对象以及PreparedStatement对象,这么消耗我们很大的内存空间。

    如果用户同时点注册按钮那么服务器首先执行打开数据库连接Connection多个用户注册就会打开多个Connection那么并且同时添加到数据库,服务器就会在执行添加的时候就会发生异常。分不清楚用户注册的信息。

    举个例子:

    左边的三个人同时对另一人喊不同的一个字,右边的一个人就会分不清,左边三个人喊了什么?(可以做真人实例)
     
    总结:
    从分析中,我们看到普通的连接方式中无法处理并发问题!如果你想知道解决方法那么请继续看下去。
     
    单例连接:
    下面一段单利模式中的数据库连接代码
    package dao;
     
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
     
    public class BaseDao {
            private String className = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
            private String url = "jdbc:sqlserver://localhost:1433;databasename=SQLTMP";
            private String user = "sa";
            private String pwd = "sa";
            private static Connection conn = null;
             
            private BaseDao(){
                    try {
                            Class.forName(className);
                            conn = DriverManager.getConnection(url,user,pwd);
                    } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                    } catch (SQLException e) {
                            e.printStackTrace();
                    }
                     
            }
             
            public static Connection getConn(){
                    if(conn != null){
                            return conn;
                    }else{
                            new BaseDao();
                            return conn;
                    }
            }
    }
     
    普及:
    构造方法:访问修饰符(public|private) 类名
    构造方法在实例化的时候就会调用
     
    我们分析一下这一段代码中Connection在构造方法中创建用过getConn方法获取连接。
     
     
    我们从图片中和代码中可以看到全程中只有一个Connection连接,那么这样就可以降低服务器的压力,解决并发问题
     
    总结:
     
    从分析中,我们看到单例模式,可以减轻服务器的压力,解决并发问题,如果够仔细的话大家会发现getConn方法是一个静态方法,而且其他属性和方法都是private从而大大提高了安全性。这种连接方式适合:个人开发和国家单位开发(安全性高)
     
    连接池:
    下面一段连接池数据库连接代码
    context.xml
            <Resource  
                    name="news"
                    auth="Container"
                    type="javax.sql.DataSource"
                    maxActive="100"
                    maxIdle="30"
                    maxWait="1000"
                    username="sa"
                    password="sa"
                    driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
                    url="jdbc:sqlserver://localhost:1433;DatabaseName=NewsManagerSystem"
                    /> 
    Web.xml
    <resource-ref>
        <description>news DataSource</description>
        <res-ref-name>news</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
      </resource-ref>   
     
    package com.news.dao;
    import java.sql.*;
     
    import javax.naming.*;
    import javax.sql.DataSource;
     
    public class BaseDao {
            /**
             * 创建连接池
             * */
            public Connection getConn(){
                    Connection conn = null;
                    try {
                            Context ctx = new InitialContext();
                            DataSource ds = (DataSource)ctx.lookup("java:comp/env/news");
                            conn = ds.getConnection();
                    } catch (NamingException e) {
                            e.printStackTrace();
                    } catch (SQLException e) {
                            e.printStackTrace();
                    }
                    return conn;
            }
    }

    普及:

    连接池:连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要他们的线程使用。
     
    我们可以直接使用getConn方法获得Connection并且执行数据操作,执行完成之后连接池会回收Connection这样就解决了普通模式中的并发问题.
     
    总结:
    从分析中,我们看到Connection不需要创建,这样就简化编程模式,这样减少了连接的创建时间,连接池能够使性能最大化,同事还能将资源利用控制在一定的水平之下,如果超过该水平,应用程序将崩溃而不仅仅是变慢。
     
    写在最后
    清楚的了解B/S架构中的数据库连接方式,在合适的情况下使用合适的连接方式感觉还是棒棒哒 ~ ~!
     

    文章首链:http://bbs.ichunqiu.com/thread-8784-1-1.html


    感谢您的阅读,如果您学到了,请点赞(码字不易)!


    欢迎热心园友补充!

    作者:0nise

     
  • 相关阅读:
    Mysql数据库基本操作
    Entity Framework 实践系列 —— 搞好关系 单相思(单向一对一,onetoone)
    ADO.NET最佳实践
    C++试题1
    SQL操作(初级、中级、高级)
    存储过程入门与提高
    数据库学习笔记
    触发器设计技巧与实例
    UML在关系型数据库设计中的应用
    数据库设计的一些构想
  • 原文地址:https://www.cnblogs.com/ichunqiu/p/5740885.html
Copyright © 2020-2023  润新知