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

前言
在许许多多的B/S架构系统中都涉及到了数据库的链接,那么对于数据库连接的方式有哪些?可能出现的问题是什么?

目录
1.普通连接方式
2.单例模式
3.连接池

分析
普通连接:
下面是我们一般使用的普通连接方式的代码(jsp)
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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;
         }
}

普及:
[Java]  纯文本查看  复制代码
?
1
2
3
4
5
6
7
try {
//可能出现异常的代码
} catch (Execption e){
//如果发生异常处理的代码
} finally {
//无论是否异常都会执行的代码
try catch finally java中异常处理机制

我们来分析一下写一段代码,其中 Update 方法是用来更新数据的,其中我们可以看到 try 中包含了 getConn ()方法用来获取 Connection 连接对象,到最后我们可以在 finally 代码块中看到 Close() 方法用来关闭创建的 Connection 对象以及 PreparedStatement 对象,这么消耗我们很大的内存空间。
如果用户 同时 点注册按钮那么服务器首先执行打开数据库连接 Connection 多个用户注册就会打开多个 Connection 那么并且同时添加到数据库,服务器就会在执行添加的时候就会发生异常。 分不清楚 用户注册的信息。举个例子:
左边的三个人同时对另一人喊不同的一个字,右边的一个人就会分不清,左边三个人喊了什么?(可以做真人实例)

总结:
从分析中,我们看到普通的连接方式中无法处理并发问题!如果你想知道解决方法那么请继续看下去。

单例连接:
下面一段单利模式中的数据库连接代码
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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 从而大大提高了安全性。这种连接方式适合: 个人开发和国家单位开发(安全性高)

连接池:
下面一段连接池数据库连接代码
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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 不需要创建,这样就简化编程模式,这样 减少了连接的创建时间 ,连接池能够使性能最大化,同事还能将资源利用控制在一定的水平之下,如果超过该水平,应用程序将崩溃而不仅仅是变慢。

原文链接:http://bbs.ichunqiu.com/thread-8784-1-1.html?from=jiuge
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值