一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - JDBC數據源連接池配置及應用

JDBC數據源連接池配置及應用

2020-05-15 11:01kingxss JAVA教程

這篇文章主要介紹JDBC建立數據庫連接的兩種方式,使用配置數據源的方式連接數據庫,效率更高,推薦使用,希望能給大家做一個參考。

使用JDBC建立數據庫連接的兩種方式:

1.在代碼中使用DriverManager獲得數據庫連接。這種方式效率低,并且其性能、可靠性和穩定性隨著用戶訪問量得增加逐漸下降。

2.使用配置數據源的方式連接數據庫,該方式其實質就是在上述方法的基礎上增加了數據庫連接池,這種方式效率高。

數據源連接池的方式連接數據庫與在代碼中使用DriverManager獲得數據庫連接存在如下差別:

1)數據源連接池的方式連接數據庫是在程序中,通過向一個JNDI(Java Naming and  Directory Interface)服務器查詢,即調用Context接口的lookup()方法,來得到DataSource對象,然后調用DataSource對象的getConnection()方法建立連接

2)為了能重復利用數據庫連接對象,提高對請求的響應時間和服務器的性能,采用連接池技術.連接池技術預先建立多個數據庫連接對象,然后將連接對象保存到連接池中,當客戶請求到來時,從池中取出一個連接對象為客戶服務,當請求完成時,客戶程序調用close()方法,將連接對象放回池中.

3)在代碼中使用DriverManager獲得數據庫連接的方式中,客戶程序得到的連接對象是物理連接,調用連接對象的close()方法將關閉連接,而采用連接池技術,客戶程序得到的連接對象是連接池中物理連接的一個句柄,調用連接對象的close()方法,物理連接并沒有關閉,數據源的實現只是刪除了客戶程序中的連接對象和池中的連接對象之間的聯系.

為了測試方便可以在數據庫(這里以mysql 5為例)中建立一個USER表:

?
1
2
3
4
5
6
7
CREATE TABLE `user` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `username` varchar(50) DEFAULT NULL,
 `password` varchar(50) DEFAULT NULL,
 `email` varchar(50) DEFAULT NULL,
 PRIMARY KEY (`id`),
);

導入數據庫的驅動的jar包到tomcat的lib目錄下(這里以mysql5為例,所用到的jar包為:mysql-connector-java-5.0.8-bin.jar)。

1.在代碼中使用DriverManager獲得數據庫連接。這種方式效率低,并且其性能、可靠性和穩定性隨著用戶訪問量得增加逐漸下降。

oracle數據庫連接的Java代碼如下:

?
1
2
3
4
5
6
7
8
9
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
import java.sql.Connection;
import java.sql.DriverManager;
/**
 * 獲取數據庫連接
 */
public class DBConnection {
  
 /** Oracle數據庫連接URL*/
 private final static String DB_URL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
  
 /** Oracle數據庫連接驅動*/
 private final static String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
  
 /** 數據庫用戶名*/
 private final static String DB_USERNAME = "root";
  
 /** 數據庫密碼*/
 private final static String DB_PASSWORD = "admin";
  
 /**
  * 獲取數據庫連接
  * @return
  */
 public Connection getConnection(){
  /** 聲明Connection連接對象*/
  Connection conn = null;
  try{
   /** 使用Class.forName()方法自動創建這個驅動程序的實例且自動調用DriverManager來注冊它*/
   Class.forName(DB_DRIVER);
   /** 通過DriverManager的getConnection()方法獲取數據庫連接*/
   conn = DriverManager.getConnection(DB_URL,DB_USERNAME,DB_PASSWORD);
  }catch(Exception ex){
   ex.printStackTrace();
  }
  return conn;
 }
  
 /**
  * 關閉數據庫連接
  *
  * @param connect
  */
 public void closeConnection(Connection conn){
  try{
   if(conn!=null){
    /** 判斷當前連接連接對象如果沒有被關閉就調用關閉方法*/
    if(!conn.isClosed()){
     conn.close();
    }
   }
  }catch(Exception ex){
   ex.printStackTrace();
  }
 }
  
}

mysql數據庫連接的JSP代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<%@page import="java.sql.*, com.mysql.jdbc.Driver"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<body> 
 <%
 //com.mysql.jdbc.Driver
 Class.forName(Driver.class.getName()).newInstance();
 String url = "jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF8";
 String user = "root";
 String password = "123";
  
 Connection conn = DriverManager.getConnection(url, user, password);
 Statement stmt = conn.createStatement();
  
 String sql = "select * from user";
 ResultSet rs = stmt.executeQuery(sql);
  
 while(rs.next()) {
  out.print("<br />" + "====================" + "<br />");
  out.print(rs.getLong("id") + " ");
  out.print(rs.getString("username") + " ");
  out.print(rs.getString("password") + " ");
  out.print(rs.getString("email") + " ");
 }
 %>
</body>
</html>

2.使用配置數據源的方式連接數據庫,該方式其實質就是在上述方法的基礎上增加了數據庫連接池,這種方式效率高。

1)mysql數據庫數據源連接池的JSP代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<%@page import="java.sql.*, javax.naming.*, javax.sql.DataSource"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<body>
 <%
 Context initCtx = new InitialContext();
 DataSource ds = (DataSource)initCtx.lookup("java:comp/env/jdbc/demoDB");
 Connection conn = ds.getConnection();
  
 Statement stmt = conn.createStatement();
  
 String sql = "select * from user";
 ResultSet rs = stmt.executeQuery(sql);
  
 while(rs.next()) {
  out.print("<br />" + "====================" + "<br />");
  out.print(rs.getLong("id") + " ");
  out.print(rs.getString("username") + " ");
  out.print(rs.getString("password") + " ");
  out.print(rs.getString("email") + " ");
 }
 %>
</body>
</html>

2) 添加如下代碼到tomcat的conf目錄下的server.xml中:

?
1
2
3
4
5
6
7
8
9
10
11
<Context>
 <Resource name="jdbc/demoDB" auth="Container"
 type="javax.sql.DataSource"
 driverClassName="com.mysql.jdbc.Driver"
 url="jdbc:mysql://localhost:3306/demo"
 username="root"
 password="123"
 maxActive="50"
 maxIdle="30"
 maxWait="10000" />
</Context>

3)在web工程目錄下的web.xml的根節點下配置如下內容:

?
1
2
3
4
5
6
<resource-ref>
 <description>mysqlDB Connection</description>
 <res-ref-name>jdbc/demoDB</res-ref-name>
 <res-type>javax.sql.DataSource</res-type>
 <res-auth>Container</res-auth>
</resource-ref>

完成上述步驟數據源的連接池配置已經完成,但是為了提高項目的可移植性,最好將上述第二步的內容放入到工程的META-INF目錄的context.xml中(這個文件需要自行建立):

?
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <Resource name="jdbc/demoDB" auth="Container"
  type="javax.sql.DataSource"
  driverClassName="com.mysql.jdbc.Driver"
  url="jdbc:mysql://localhost:3306/demo"
  username="root"
  password="123"
  maxActive="50"
  maxIdle="30"
  maxWait="10000" />
</Context>

3.使用配置數據源的數據庫連接池時的數據庫操作工具類

代碼如下:

?
1
2
3
4
5
6
7
8
9
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
package db.utils;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import javax.naming.InitialContext;
import javax.sql.DataSource;
 
//import org.apache.log4j.Logger;
 
/**
 * 數據庫操作輔助類
 */
public class DbUtils {
  
 //private static Logger logger = Logger.getLogger("DbUtils");
  
 /**
  * 該語句必須是一個 SQL INSERT、UPDATE 或 DELETE 語句
  * @param sql
  * @param paramList:參數,與SQL語句中的占位符一一對應
  * @return
  * @throws Exception
  */
 public int execute(String sql, List<Object> paramList) throws Exception {
  if(sql == null || sql.trim().equals("")) {
   //logger.info("parameter is valid!");
  }
 
  Connection conn = null;
  PreparedStatement pstmt = null;
  int result = 0;
  try {
   conn = getConnection();
   pstmt = DbUtils.getPreparedStatement(conn, sql);
   setPreparedStatementParam(pstmt, paramList);
   if(pstmt == null) {
    return -1;
   }
   result = pstmt.executeUpdate();
  } catch (Exception e) {
   //logger.info(e.getMessage());
   throw new Exception(e);
  } finally {
   closeStatement(pstmt);
   closeConn(conn);
  }
 
  return result;
 }
  
 /**
  * 將查詢數據庫獲得的結果集轉換為Map對象
  * @param sql:查詢語句
  * @param paramList:參數
  * @return
  */
 public List<Map<String, Object>> getQueryList(String sql, List<Object> paramList) throws Exception {
  if(sql == null || sql.trim().equals("")) {
   //logger.info("parameter is valid!");
   return null;
  }
 
  Connection conn = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  List<Map<String, Object>> queryList = null;
  try {
   conn = getConnection();
   pstmt = DbUtils.getPreparedStatement(conn, sql);
   setPreparedStatementParam(pstmt, paramList);
   if(pstmt == null) {
    return null;
   }
   rs = getResultSet(pstmt);
   queryList = getQueryList(rs);
  } catch (RuntimeException e) {
   //logger.info(e.getMessage());
   System.out.println("parameter is valid!");
   throw new Exception(e);
  } finally {
   closeResultSet(rs);
   closeStatement(pstmt);
   closeConn(conn);
  }
  return queryList;
 }
  
 private void setPreparedStatementParam(PreparedStatement pstmt, List<Object> paramList) throws Exception {
  if(pstmt == null || paramList == null || paramList.isEmpty()) {
   return;
  }
  DateFormat df = DateFormat.getDateTimeInstance();
  for (int i = 0; i < paramList.size(); i++) {
   if(paramList.get(i) instanceof Integer) {
    int paramValue = ((Integer)paramList.get(i)).intValue();
    pstmt.setInt(i+1, paramValue);
   } else if(paramList.get(i) instanceof Float) {
    float paramValue = ((Float)paramList.get(i)).floatValue();
    pstmt.setFloat(i+1, paramValue);
   } else if(paramList.get(i) instanceof Double) {
    double paramValue = ((Double)paramList.get(i)).doubleValue();
    pstmt.setDouble(i+1, paramValue);
   } else if(paramList.get(i) instanceof Date) {
    pstmt.setString(i+1, df.format((Date)paramList.get(i)));
   } else if(paramList.get(i) instanceof Long) {
    long paramValue = ((Long)paramList.get(i)).longValue();
    pstmt.setLong(i+1, paramValue);
   } else if(paramList.get(i) instanceof String) {
    pstmt.setString(i+1, (String)paramList.get(i));
   }
  }
  return;
 }
  
 /**
  * 獲得數據庫連接
  * @return
  * @throws Exception
  */
 private Connection getConnection() throws Exception {
  InitialContext cxt = new InitialContext();
  DataSource ds = (DataSource) cxt.lookup(jndiName);
  if ( ds == null ) {
   throw new Exception("Data source not found!");
  }
   
  return ds.getConnection();
 }
  
 private static PreparedStatement getPreparedStatement(Connection conn, String sql) throws Exception {
  if(conn == null || sql == null || sql.trim().equals("")) {
   return null;
  }
  PreparedStatement pstmt = conn.prepareStatement(sql.trim());
  return pstmt;
 }
  
 /**
  * 獲得數據庫查詢結果集
  * @param pstmt
  * @return
  * @throws Exception
  */
 private ResultSet getResultSet(PreparedStatement pstmt) throws Exception {
  if(pstmt == null) {
   return null;
  }
  ResultSet rs = pstmt.executeQuery();
  return rs;
 }
  
 /**
  * @param rs
  * @return
  * @throws Exception
  */
 private List<Map<String, Object>> getQueryList(ResultSet rs) throws Exception {
  if(rs == null) {
   return null;
  }
  ResultSetMetaData rsMetaData = rs.getMetaData();
  int columnCount = rsMetaData.getColumnCount();
  List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();
  while (rs.next()) {
   Map<String, Object> dataMap = new HashMap<String, Object>();
   for (int i = 0; i < columnCount; i++) {
    dataMap.put(rsMetaData.getColumnName(i+1), rs.getObject(i+1));
   }
   dataList.add(dataMap);
  }
  return dataList;
 }
  
 /**
  * 關閉數據庫連接
  * @param conn
  */
 private void closeConn(Connection conn) {
  if(conn == null) {
   return;
  }
  try {
   conn.close();
  } catch (SQLException e) {
   //logger.info(e.getMessage());
  }
 }
  
 /**
  * 關閉
  * @param stmt
  */
 private void closeStatement(Statement stmt) {
  if(stmt == null) {
   return;
  }
  try {
   stmt.close();
  } catch (SQLException e) {
   //logger.info(e.getMessage());
  }
 }
  
 /**
  * 關閉
  * @param rs
  */
 private void closeResultSet(ResultSet rs) {
  if(rs == null) {
   return;
  }
  try {
   rs.close();
  } catch (SQLException e) {
   //logger.info(e.getMessage());
  }
 }
  
  
 private String jndiName = "java:/comp/env/jdbc/demoDB";
 
 public void setJndiName(String jndiName) {
  this.jndiName = jndiName;
 }
}

總結:使用配置數據源的方式連接數據庫,這種方式效率高且性能穩定,推薦使用。查看更多Java的語法,希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 四虎影视永久在线精品免费 | 久久性综合亚洲精品电影网 | 亚洲系列国产精品制服丝袜第 | 91粉色视频在线导航 | 东北老妇露脸xxxxx | 欧美日韩精品乱国产 | 国产一卡2卡3卡四卡精品网 | 丝瓜秋葵番茄绿巨人在线观看 | 国模大胆一区二区三区 | 亚洲视频一区在线播放 | 欧美一级片免费在线观看 | 天天操精品视频 | 日本三级欧美三级人妇英文 | 国产欧美一区二区三区久久 | 艹的好爽| 男女真实无遮挡xx00动态图软件 | 蜜柚精彩在线观看 | 日本高清在线看 | 国产真实乱子伦xxxxchina | 日韩高清一区 | 51国产午夜精品免费视频 | 538免费精品视频搬运工 | 国产精品久久久久久久久ktv | 精品亚洲永久免费精品 | 岛国免费大片 | 黄瓜视频黄 | 513热点网深夜影院影院诶 | 免费看60分钟大片视频播放 | www.男人天堂 | 精品午夜中文字幕熟女人妻在线 | 五月天精品视频播放在线观看 | 亚洲国产欧美在线人成aaa | 兽皇日本 | 日本一区二区三区久久精品 | 操美女网址 | 日韩成人一区ftp在线播放 | 欧美生活一级片 | 91制片厂制作传媒破解版免费 | 免费视频精品一区二区三区 | 天堂樱桃bt在线www | 亚洲六月丁香婷婷综合 |