自定义数据源

步骤:

  1. 解析配置文件,获得连接的参数。
  2. 创建一个集合[连接池]。
  3. 用户到连接池获取连接
    – 连接池空:创建连接,通过动态代理绑定连接,返回代理对象给用户。
    – 连接池中有连接:直接拿一个返回给用户。
  4. 用户操作完成,调用close方法。
  5. 判断用户调用的是close方法,检查连接池最大可以保持数,如果没有到最大可保存数,将连接放入集合,不执行close方法。如果已经到最大可保存数,直接调用close方法关闭连接。

代码实现

MyDataSourceTest类:

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
package com.自定义数据源;

import java.sql.Connection;
import java.sql.SQLException;

public class MyDataSourceTest {

public static void main(String[] args) {

try {
//创建连接对象
MyDataSource dataSource = new MyDataSource();

//指定数据库连接
dataSource.setDriverClassName("com.mysql.jdbc.Driver");

//指定数据库的url地址
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/booksys");

//数据库的账号
dataSource.setUserName("root");

//数据库的密码
dataSource.setPassword("root");

//设置最大活跃数
dataSource.setMaxActive(3);

//设置最大保留数
dataSource.setMaxIdle(2);

//从连接池中获取连接
Connection con1 = dataSource.getConnection();
Connection con2 = dataSource.getConnection();
Connection con3 = dataSource.getConnection();

System.out.println("con1:"+con1);
System.out.println("con2"+con2);
System.out.println("con3"+con3);

con1.close();
con2.close();
con3.close();

System.out.println("-----------------------------");

Connection con4 = dataSource.getConnection();
Connection con5 = dataSource.getConnection();
Connection con6 = dataSource.getConnection();

System.out.println("con1:"+con4);
System.out.println("con2"+con5);
System.out.println("con3"+con6);

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

MyDataSource:自定义数据源

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
package com.自定义数据源;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class MyDataSource {

private String driverClassName;// 指定数据库连接
private String url;// 指定数据库的url地址
private String userName;// 数据库的账号
private String password;// 数据库的密码
private int maxActive;// 指定最大活动数
private int maxIdle;// 设置最大保留数
public static int activeNow = 0;// 当前活动数,默认为0

// 定义集合用来充当连接池的角色
private static Set<Connection> sets = new HashSet<Connection>();

//定义set,get方法用于在代理类中获取集合的长度---连接的个数
public static void setSets(Set<Connection> sets){
MyDataSource.sets = sets;
}
public static Set<Connection> getSets(){
return sets;
}

// 自定义获取连接的方法
public Connection getConnection() {

try {
// 比较当前活动数与最大活动数,
if (activeNow < maxActive) {
// 可以拿连接

// 判断连接池是否有连接,
if (!sets.isEmpty()) {
// 连接池有连接
Iterator<Connection> iterator = sets.iterator();
Connection con = iterator.next();
activeNow++; // 当前活动数+1
sets.remove(con);
return ConnectionProxy.bindObj(con,maxIdle);
}

// 连接池没有连接,通过jdbc从数据库中拿

// 注册驱动
Class.forName(driverClassName);

// 获取连接
Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/booksys", "root", "root");

//当前活动数 + 1
activeNow++;

return ConnectionProxy.bindObj(con,maxIdle);

}

return null;

} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;

}

public MyDataSource() {
super();
}

public MyDataSource(String driverClassName, String url, String userName, String password, int MaxActive,
int maxIdle, int activeNow) {
super();
this.driverClassName = driverClassName;
this.url = url;
this.userName = userName;
this.password = password;
this.maxActive = MaxActive;
this.maxIdle = maxIdle;
this.activeNow = activeNow;
}

public String getDriverClassName() {
return driverClassName;
}

public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public int getMaxActive() {
return maxActive;
}

public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}

public int getMaxIdle() {
return maxIdle;
}

public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}

public static int getActiveNow() {
return activeNow;
}

public static void setActiveNow(int activeNow) {
MyDataSource.activeNow = activeNow;
}

}

代理类:

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
package com.自定义数据源;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.Set;

public class ConnectionProxy {

static Set<Connection> sets = MyDataSource.getSets();
@SuppressWarnings("unchecked")
public static Connection bindObj(Connection t,int maxIdle) {


return (Connection)Proxy.newProxyInstance(t.getClass().getClassLoader(),t.getClass().getInterfaces(),new InvocationHandler() {

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

if(method.getName().equals("close")) {
//获取当前活动数
int active = MyDataSource.getActiveNow();
//调用连接对象的close方法
if(sets.size()<maxIdle) {
//连接池中连接数<最大保留数,回收连接
active--;//当前活动数-1
MyDataSource.setActiveNow(active);
sets.add(t);

}else {
//关闭连接
Object result = method.invoke(t, args);
active--;//当前活动数-1
MyDataSource.setActiveNow(active);
return result;

}
}else {
//执行的是除close()的其他方法
Object result = method.invoke(t, args);
return result;

}
return null;

}
});
}

}

-------------本文结束感谢您的阅读-------------