前言
在许许多多的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 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"
/>
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