直接使用JDBC访问数据库时,需要避免以下隐患:
1. 每一次数据操作请求都需要建立数据库连接、打开连接、存取数据和关闭连接等步骤。而建立和打开数据库连接是一件既耗资源又费时的过程,如果频繁发生这种数据库操作,势必会使系统性能下降。
2. 连接对象代表着数据库系统的连接进程,是有限的资源。如果系统的使用用户非常多,有可能超出数据库服务器的承受极限,造成系统的崩溃。
数据库连接池是解决上述问题最常用的方法。所谓连接池,即可以创建并持有数据库连接的组件。连接池可以预先创建并封装一些连接对象并将其缓存起来,当需要使用连接对象时可以向连接池“借”一个连接,用完之后将其“归还”到连接池中。
数据库连接池的主要功能如下:
1. 连接池对象的创建和释放。
2. 服务器启动时,创建指定数量的数据库连接。
3. 为用户请求提供可用连接。如果没有空闲连接,且连接数没有超出最大值,创建一个新的数据库连接。
4. 将用户不再使用的连接标识为可用连接,等待其他用户请求。
5. 当空闲的连接数过多时,释放连接对象。
连接池组件一般都需要实现JDBC规范中的javax.sql.DataSource接口。DataSource接口定义了获取连接的方法getConnection方法。
常用的连接池组件有DBCP、c3p0和proxool等,我这里是以Apache的DBCP组件为例来实现数据库连接池。
新建一个java项目,以及配置文件,如下:
在当前工程下,导入使用DBCP组件所需的jar包,包括commons-dbcp.jar以及commons-pool.jar两个jar包,这两个jar包的名字可能会因为版本的不同,名字的最后为版本信息,例如:commons-dbcp-1.2.1.jar。
工具类DBUtility:
1 package com.daliu.jdbc;
2
3 import java.io.IOException;
4 import java.sql.Connection;
5 import java.sql.SQLException;
6 import java.util.Properties;
7
8 import org.apache.commons.dbcp.BasicDataSource;
9 /**
10 * 工具类
11 * @author daliu_it
12 *
13 */
14 public class DBUtility {
15 private static BasicDataSource dataSource = null;
16
17 public DBUtility() {
18 }
19 public static void init() {
20
21 Properties dbProps = new Properties();
22 // 取配置文件可以根据实际的不同修改
23 try {
24 dbProps.load(DBUtility.class.getClassLoader().getResourceAsStream(
25 "com/daliu/jdbc/db.properties"));
26 } catch (IOException e) {
27 e.printStackTrace();
28 }
29
30 try {
31 String driveClassName = dbProps.getProperty("jdbc.driverClassName");
32 String url = dbProps.getProperty("jdbc.url");
33 String username = dbProps.getProperty("jdbc.username");
34 String password = dbProps.getProperty("jdbc.password");
35
36 String initialSize = dbProps.getProperty("dataSource.initialSize");
37 String minIdle = dbProps.getProperty("dataSource.minIdle");
38 String maxIdle = dbProps.getProperty("dataSource.maxIdle");
39 String maxWait = dbProps.getProperty("dataSource.maxWait");
40 String maxActive = dbProps.getProperty("dataSource.maxActive");
41
42 dataSource = new BasicDataSource();
43 dataSource.setDriverClassName(driveClassName);
44 dataSource.setUrl(url);
45 dataSource.setUsername(username);
46 dataSource.setPassword(password);
47
48 // 初始化连接数
49 if (initialSize != null)
50 dataSource.setInitialSize(Integer.parseInt(initialSize));
51
52 // 最小空闲连接
53 if (minIdle != null)
54 dataSource.setMinIdle(Integer.parseInt(minIdle));
55
56 // 最大空闲连接
57 if (maxIdle != null)
58 dataSource.setMaxIdle(Integer.parseInt(maxIdle));
59
60 // 超时回收时间(以毫秒为单位)
61 if (maxWait != null)
62 dataSource.setMaxWait(Long.parseLong(maxWait));
63
64 // 最大连接数
65 if (maxActive != null) {
66 if (!maxActive.trim().equals("0"))
67 dataSource.setMaxActive(Integer.parseInt(maxActive));
68 }
69 } catch (Exception e) {
70 e.printStackTrace();
71 System.out.println("创建连接池失败!请检查设置!!!");
72 }
73 }
74
75 /**
76 * 数据库连接
77 * @return
78 * @throws SQLException
79 */
80 public static synchronized Connection getConnection() throws SQLException {
81 if (dataSource == null) {
82 init();
83 }
84 Connection conn = null;
85 if (dataSource != null) {
86 conn = dataSource.getConnection();
87 }
88 return conn;
89 }
90
91 /**
92 * 关闭数据库
93 * @param conn
94 */
95 public void closeConnection(Connection conn){
96 if(conn!=null){
97 try {
98 conn.close();
99 } catch (SQLException e) {
100 System.out.println("关闭资源失败");
101 e.printStackTrace();
102 }
103 }
104 }
105
106 }
重构db.properties文件,在该文件中添加创建数据库连接池所需的信息,包括初始化连接数、最大空闲连接数、大小空闲连接数、最大连接数量以及超时回收时间。该文件内容如下所示:
1 #Oracle
2 #jdbc.driverClassName=oracle.jdbc.OracleDriver
3 #jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl
4 #jdbc.username=root
5 #jdbc.password=123456
6
7 #Mysql
8 jdbc.driverClassName=com.mysql.jdbc.Driver
9 jdbc.url=jdbc:mysql://localhost:3306/csdn
10 jdbc.username=root
11 jdbc.password=123456
12
13 dataSource.initialSize=10
14 dataSource.maxIdle=20
15 dataSource.minIdle=5
16 dataSource.maxActive=50
17 dataSource.maxWait=1000
测试类testCase:
1 package com.daliu.test;
2
3 import java.sql.SQLException;
4
5 import org.junit.Test;
6
7 import com.daliu.jdbc.DBUtility;
8
9
10 public class testCase {
11
12 /**
13 * 测试是否连接
14 * @throws SQLException
15 */
16 @Test
17 public void testgetConnection() throws SQLException{
18 DBUtility db=new DBUtility();
19 System.out.println(db.getConnection());
20 }
21 }
操作数据库EmpDAO类:
1 package com.daliu.jdbc;
2 import java.sql.Connection;
3 import java.sql.ResultSet;
4 import java.sql.SQLException;
5 import java.sql.Statement;
6
7 public class EmpDAO {
8 public static void main(String[] args) {
9 EmpDAO dao = new EmpDAO();
10 dao.findAll();
11 }
12
13 /**
14 * 查询数据库表中的所有信息
15 */
16 public void findAll() {
17
18 Connection con = null;
19 Statement stmt = null;
20 ResultSet rs = null;
21
22
23 try {
24 //1.获得连接
25 con = DBUtility.getConnection();
26 //2.通过Connection的createStatement()方法获取数据库操作对象Statement。
27 stmt = con.createStatement();
28 //3.通过调用Statement对象的executeQuery方法来执行SQL语句。
29 rs = stmt
30 .executeQuery("select empno, ename, sal, hiredate from emp");
31 //4.ResultSet 对象没有下一行时返回 false,因此可以在 while 循环中使用它来迭代结果集
32 while (rs.next()) {
33 System.out.println(rs.getInt("empno") + ","
34 + rs.getString("ename") + "," + ","
35 + rs.getDouble("sal") + "," + rs.getDate("hiredate"));
36 }
37
38
39 } catch (SQLException e) {
40 System.out.println("数据库访问异常!");
41 throw new RuntimeException(e);
42 } finally {
43 try {
44
45 //5.在finally块中,依次关闭ResultSet对象、Statement对象以及Connection对象。
46 if (rs != null) {
47 rs.close();
48 }
49 if (stmt != null) {
50 stmt.close();
51 }
52 if (con != null) {
53 con.close();
54 }
55 } catch (SQLException e) {
56 System.out.println("释放资源时发生异常");
57 }
58 }
59 }
60 }
Mysql脚本:
1 create database csdn;
2
3 use csdn;
4
5 CREATE TABLE emp(
6 empno int(4),
7 ename VARCHAR(10),
8 job VARCHAR(9),
9 mgr int(4),
10 hiredate DATE,
11 sal double(7,2),
12 comm double(7,2),
13 deptno double(2,0)
14 );
15
16 INSERT INTO emp VALUES(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
17 INSERT INTO emp VALUES(7499,'ALLEN','SALESMAN',7698,'1981-2-20',1600,300,30);
18 INSERT INTO emp VALUES(7521,'WARD','SALESMAN',7698,'1981-2-22',1250,500,30);
19 INSERT INTO emp VALUES(7566,'JONES','MANAGER',7839,'1981-4-2',2975,NULL,20);
20 INSERT INTO emp VALUES(7654,'MARTIN','SALESMAN',7698,'1981-9-21',1250,1400,30);
21 INSERT INTO emp VALUES(7698,'BLAKE','MANAGER',7839,'1981-5-1',2850,NULL,30);
22 INSERT INTO emp VALUES(7782,'CLARK','MANAGER',7839,'1981-6-9',2450,NULL,10);
23 INSERT INTO emp VALUES(7788,'SCOTT','ANALYST',7566,'1987-4-19',3000,NULL,20);
24 INSERT INTO emp VALUES(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
25 INSERT INTO emp VALUES(7844,'TURNER','SALESMAN',7698,'1981-9-8',1500,0,30);
26 INSERT INTO emp VALUES(7876,'ADAMS','CLERK',7788,'1987-5-27',1100,NULL,20);
27 INSERT INTO emp VALUES(7900,'JAMES','CLERK',7698,'1981-12-1',950,NULL,30);
28 INSERT INTO emp VALUES(7902,'FORD','ANALYST',7566,'1981-12-3',3000,NULL,20);
29 INSERT INTO emp VALUES(7934,'MILLER','CLERK',7782,'1982-1-23',1300,NULL,10);
30
31 select * from emp;
转载请标明:http://www.iyunv.com/liuhongfeng/p/4174661.html |