1 /*
2 * @(#)CommonSql.java 2011-9-5
3 *
4 * Copyright 2011 Bianjing,All rights reserved.
5 */
6
7 import java.sql.Connection;
8 import java.sql.DatabaseMetaData;
9 import java.sql.DriverManager;
10 import java.sql.PreparedStatement;
11 import java.sql.ResultSet;
12 import java.sql.SQLException;
13 import java.sql.Statement;
14 import java.util.List;
15
16 import javax.naming.Context;
17 import javax.naming.InitialContext;
18 import javax.sql.DataSource;
19
20 /**
21 * 用于JDBC操作数据库的共通类
22 *
23 * @author Bianjing
24 * @version 1.0.0 2011-9-5
25 */
26 public class CommonSql {
27 /** 数据源 */
28 private DataSource dataSource;
29
30 /** 数据库连接对象 */
31 private Connection connection;
32
33 /** 数据库操作对象 */
34 private PreparedStatement ps;
35
36 /** 数据库操作对象 */
37 private Statement statement;
38
39 /** 返回的数据结果集对象 */
40 private ResultSet rs;
41
42 /** 是否自动提交事务,默认为true,如果该值为false则需要手动提交事务 */
43 private boolean autoCommit = true;
44
45 /** 数据库连接是否已经打开 */
46 private boolean openConnection;
47
48 /** JNDI名称 */
49 private String jndiName;
50
51 /** 数据库驱动 */
52 private String driver;
53
54 /** 数据库访问地址 */
55 private String url;
56
57 /** 用户名 */
58 private String user;
59
60 /** 密码 */
61 private String pwd;
62
63 public CommonSql() {
64
65 }
66
67 public CommonSql(DataSource dataSource) {
68 this.dataSource = dataSource;
69 }
70
71 public CommonSql(String jndiName) {
72 this.jndiName = jndiName;
73 }
74
75 public CommonSql(String driver, String url, String user, String pwd) {
76 this.driver = driver;
77 this.url = url;
78 this.user = user;
79 this.pwd = pwd;
80 }
81
82 /**
83 * 打开数据库连接并创建数据库连接对象<br/>
84 * 支持通过ICO注入数据源、数据库驱动、数据库驱动、JNDI名称、数据库访问地址和用户名、密码
85 *
86 * @return boolean true:连接成功,false:连接失败
87 */
88 public boolean openConnection() {
89 /**
90 * 通过数据源来获取数据库连接对象
91 */
92 if (dataSource != null) {
93 try {
94 connection = dataSource.getConnection();
95 // 数据库连接已经打开
96 openConnection = true;
97 } catch (SQLException e) {
98 closeAll();
99 // 所有的"System.out.println"都可以替换为"logger.error"
100 System.out.println("从数据源获取数据库连接失败!");
101 throw new RuntimeException(e);
102 }
103
104 return openConnection;
105 }
106 /**
107 * 通过JNDI来获取数据库连接对象
108 */
109 if (jndiName != null) {
110 try {
111 Context initContext = new InitialContext();
112 dataSource = (DataSource) initContext.lookup(jndiName);
113 connection = dataSource.getConnection();
114 // 数据库连接已经打开
115 openConnection = true;
116 } catch (Exception e) {
117 closeAll();
118 System.out.println("从JNDI获取数据库连接失败!");
119 throw new RuntimeException(e);
120 }
121
122 return openConnection;
123 }
124 /**
125 * 通过数据库驱动、数据库访问地址、用户名、密码来获取数据库连接对象
126 */
127 try {
128 Class.forName(driver);
129 connection = DriverManager.getConnection(url, user, pwd);
130 // 数据库连接已经打开
131 openConnection = true;
132 } catch (Exception e) {
133 closeAll();
134 System.out.println("数据库连接失败!");
135 throw new RuntimeException(e);
136 }
137
138 return openConnection;
139 }
140
141 /**
142 * 执行数据库的更新操作
143 *
144 * @param sql
145 * 要执行的SQL语句
146 * @return boolean true:执行成功,false:执行失败
147 */
148 public boolean execUpdate(String sql, Object... args) {
149 boolean isPassed = false;
150 // 判断连接数据库是否成功
151 if (openConnection) {
152 try {
153 ps = connection.prepareStatement(sql);
154 // 设置参数
155 if (args != null && args.length > 0) {
156 for (int i = 0; i < args.length; i++) {
157 ps.setObject(i + 1, args[i]);
158 }
159 }
160 ps.executeUpdate();
161
162 isPassed = true;
163 } catch (SQLException e) {
164 try {
165 if (autoCommit) {
166 connection.rollback();
167 }
168 } catch (SQLException e1) {
169 throw new RuntimeException(e1);
170 }
171 System.out.println("SQL:" + sql);
172 throw new RuntimeException(e);
173 } finally {
174 if (autoCommit) {
175 closeAll();
176 }
177 }
178 } else {
179 System.out.println("数据库连接对象没有打开!");
180 }
181
182 return isPassed;
183 }
184
185 /**
186 * 执行数据库的更新操作
187 *
188 * @param sql
189 * 要执行的SQL语句
190 * @return boolean true:执行成功,false:执行失败
191 */
192 public boolean execUpdate(String sql, List<?> args) {
193 return execUpdate(sql, args.toArray());
194 }
195
196 /**
197 * 执行批量更新数据库操作
198 *
199 * @param sql
200 * 要执行的SQL语句的字符串数组
201 * @return boolean true:执行成功,false:执行失败
202 */
203 public boolean execUpdate(Object[] sql) {
204 boolean flag = false;
205 // 判断连接数据库是否成功
206 if (openConnection) {
207 try {
208 statement = connection.createStatement();
209 for (int i = 0; i < sql.length; i++) {
210 statement.addBatch((String) sql[i]);
211 }
212 statement.executeBatch();
213
214 flag = true;
215 } catch (SQLException e) {
216 try {
217 if (autoCommit) {
218 connection.rollback();
219 }
220 } catch (SQLException e1) {
221 throw new RuntimeException(e1);
222 }
223 for (int i = 0; i < sql.length; i++) {
224 System.out.println("SQL " + (i + 1) + ":" + sql[i]);
225 }
226 throw new RuntimeException(e);
227 } finally {
228 if (autoCommit) {
229 closeAll();
230 }
231 }
232 } else {
233 System.out.println("数据库连接对象没有打开!");
234 }
235
236 return flag;
237 }
238
239 /**
240 * 执行批量更新数据库操作
241 *
242 * @param sql
243 * 要执行的SQL语句的集合
244 * @return boolean true:执行成功,false:执行失败
245 */
246 public boolean execUpdate(List<?> sql) {
247 return execUpdate(sql.toArray());
248 }
249
250 /**
251 * 执行数据库查询操作
252 *
253 * @param sql
254 * 要执行的SQL语句
255 * @param args
256 * 查询参数列表
257 * @return ResultSet 返回查询的结果集对象
258 */
259 public ResultSet execQuery(String sql, Object... args) {
260 rs = null;
261 // 判断连接数据库是否成功
262 if (openConnection) {
263 try {
264 ps = connection.prepareStatement(sql);
265 // 设置参数
266 if (args != null && args.length > 0) {
267 for (int i = 0; i < args.length; i++) {
268 ps.setObject(i + 1, args[i]);
269 }
270 }
271
272 rs = ps.executeQuery();
273 } catch (SQLException e) {
274 if (autoCommit) {
275 closeAll();
276 }
277 System.out.println("SQL:" + sql);
278 throw new RuntimeException(e);
279 }
280 } else {
281 System.out.println("数据库连接对象没有打开!");
282 }
283
284 return rs;
285 }
286
287 /**
288 * 执行数据库查询操作
289 *
290 * @param sql
291 * 要执行的SQL语句
292 * @param args
293 * 查询参数列表
294 * @return ResultSet 返回查询的结果集对象
295 */
296 public ResultSet execQuery(String sql, List<?> args) {
297 return execQuery(sql, args.toArray());
298 }
299
300 /**
301 * 根据标准SQL查询数据库,返回一个int值
302 *
303 * @param sql
304 * 要执行的SQL语句
305 * @param args
306 * 查询参数列表
307 * @return int值,如果出错则返回-1
308 */
309 public int findForInt(String sql, Object... args) {
310 ResultSet rs = execQuery(sql, args);
311 int count = -1;
312 try {
313 if (rs != null && rs.next()) {
314 count = rs.getInt(1);
315 }
316 } catch (SQLException e) {
317 throw new RuntimeException(e);
318 } finally {
319 if (autoCommit) {
320 closeAll();
321 }
322 }
323
324 return count;
325 }
326
327 /**
328 * 根据标准SQL查询数据库,返回一个int值
329 *
330 * @param sql
331 * 要执行的SQL语句
332 * @param args
333 * 查询参数列表
334 * @return int值,如果出错则返回-1
335 */
336 public int findForInt(String sql, List<?> args) {
337 return findForInt(sql, args.toArray());
338 }
339
340 /**
341 * 关闭所有数据库连接对象
342 */
343 public void closeAll() {
344 if (rs != null || ps != null || statement != null || connection != null) {
345 try {
346 if (rs != null) {
347 rs.close();
348 }
349 } catch (SQLException e) {
350 throw new RuntimeException(e);
351 } finally {
352 rs = null;
353 if (ps != null || statement != null || connection != null) {
354 try {
355 if (ps != null && !ps.isClosed()) {
356 ps.close();
357 }
358 } catch (SQLException e) {
359 throw new RuntimeException(e);
360 } finally {
361 ps = null;
362 if (statement != null || connection != null) {
363 try {
364 if (statement != null && !statement.isClosed()) {
365 statement.close();
366 }
367 } catch (SQLException e) {
368 throw new RuntimeException(e);
369 } finally {
370 statement = null;
371 try {
372 if (connection != null
373 && !connection.isClosed()) {
374 connection.close();
375 }
376 } catch (SQLException e) {
377 throw new RuntimeException(e);
378 } finally {
379 connection = null;
380 }
381 }
382 }
383 }
384 }
385 }
386 }
387 }
388
389 /**
390 * 提交事务并关闭数据库连接
391 */
392 public void commit() {
393 try {
394 if (!autoCommit) {
395 connection.commit();
396 }
397 } catch (SQLException e) {
398 throw new RuntimeException(e);
399 } finally {
400 autoCommit = true;
401 closeAll();
402 }
403 }
404
405 /**
406 * 回滚事务并关闭数据库连接
407 */
408 public void rollback() {
409 try {
410 if (!autoCommit) {
411 connection.rollback();
412 }
413 } catch (SQLException e) {
414 throw new RuntimeException(e);
415 } finally {
416 autoCommit = true;
417 closeAll();
418 }
419 }
420
421 public DataSource getDataSource() {
422 return dataSource;
423 }
424
425 public void setDataSource(DataSource dataSource) {
426 this.dataSource = dataSource;
427 }
428
429 public String getDriver() {
430 return driver;
431 }
432
433 public void setDriver(String driver) {
434 this.driver = driver;
435 }
436
437 public String getUrl() {
438 return url;
439 }
440
441 public void setUrl(String url) {
442 this.url = url;
443 }
444
445 public boolean getAutoCommit() {
446 return autoCommit;
447 }
448
449 public void setAutoCommit(boolean autoCommit) {
450 try {
451 connection.setAutoCommit(autoCommit);
452 } catch (SQLException e) {
453 closeAll();
454 throw new RuntimeException(e);
455 }
456 this.autoCommit = autoCommit;
457 }
458
459 public boolean getOpenConnection() {
460 return openConnection;
461 }
462
463 public String getJndiName() {
464 return jndiName;
465 }
466
467 public void setJndiName(String jndiName) {
468 this.jndiName = jndiName;
469 }
470
471 public String getUser() {
472 return user;
473 }
474
475 public void setUser(String user) {
476 this.user = user;
477 }
478
479 public String getPwd() {
480 return pwd;
481 }
482
483 public void setPwd(String pwd) {
484 this.pwd = pwd;
485 }
486
487 public Connection getConnection() {
488 return connection;
489 }
490
491 /**
492 * 测试数据库连接是否成功
493 *
494 * @param args
495 * @throws SQLException
496 */
497 public static void main(String[] args) throws SQLException {
498 String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
499 String url = "jdbc:sqlserver://127.0.0.1:1433;databaseName=demo";
500 String user = "sa";
501 String pwd = "sa";
502
503 CommonSql commonSql = new CommonSql(driver, url, user, pwd);
504 if (commonSql.openConnection()) {
505 System.out.println("数据库连接成功!");
506 DatabaseMetaData dbMetaData = commonSql.getConnection()
507 .getMetaData();
508 System.out
509 .print("当前连接的数据库是:" + dbMetaData.getDatabaseProductName());
510 System.out.println(" " + dbMetaData.getDatabaseProductVersion());
511 } else {
512 System.out.println("数据库连接失败!");
513 }
514
515 commonSql.closeAll();
516 }
517 }