动态切换数据库数据源的简单示例

该项目演示了如何在系统运行时动态修改数据库连接配置,以达到不关闭系统即切换数据源的目的。
源码的三个类均存放在com.le包下,请自行创建一个java项目并创建com.le类包,并复制代码片段中的三个java类到对应包下。
运行项目前请自行引入classes12.jar,oracle驱动依赖包,并且目前项目只支持连接oracle,如想连接其他数据库请自行修改数据库连接部分代码。

项目搭建完毕后直接运行Test.java里面的Main函数即可!


[1].[文件] Test.java ~ 5KB    下载(3) 跳至 [1] [2] [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
/**
  * @ProjectName ChangeDBSourceDEMO
  * @Package com.le
  * @ClassName Test
  * @Description 测试类,直接运行Main函数即可测试动态切换数据连接配置功能
  * @Author LE
  * @CreateDate 2015-09-10
  * @Version 1.0
  */
 
package com.le;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
 
public class Test {
     private static final String C_OPERATE_MSG = "请输入您要进行的操作 \n%s \n%s \n%s \n%s \n%s \n%s \n%s \n%s" ;
     private static final String C_OPE_MSG_RESET_CONFIG = "0:重置用户配置" ;
     private static final String C_OPE_MSG_CHANGE_HOST = "1:更改主机地址" ;
     private static final String C_OPE_MSG_CHANGE_PORT = "2:更改端口号" ;
     private static final String C_OPE_MSG_CHANGE_DB_NAME = "3:更改数据库实例名" ;
     private static final String C_OPE_MSG_CHANGE_UNAME = "4:更改数据库用户名" ;
     private static final String C_OPE_MSG_CHANGE_PWD = "5:更改数据库密码" ;
     private static final String C_OPE_MSG_CHANGE_DB_SOURCE = "8:更改数据源" ;
     private static final String C_OPE_MSG_EXIT = "9:退出系统" ;
 
     // 初始化用户配置
     private static final int I_OPE_LIST_RESET_USER_CONFIG = 0 ;
     // 更改主机地址
     private static final int I_OPE_LIST_CHANGE_HOST = 1 ;
     // 更改端口号
     private static final int I_OPE_LIST_CHANGE_PORT = 2 ;
     // 更改数据库实例名
     private static final int I_OPE_LIST_CHANGE_DB_NAME = 3 ;
     // 更改用户名
     private static final int I_OPE_LIST_CHANGE_UNAME = 4 ;
     // 更改密码
     private static final int I_OPE_LIST_CHANGE_PWD = 5 ;
     // 更改数据源
     private static final int I_OPE_LIST_CHANGE_DB_SOURCE = 8 ;
     // 退出系统
     private static final int I_OPE_LIST_EXIT = 9 ;
 
     private static final int [] I_OPE_LIST = { 0 , 1 , 2 , 3 , 4 , 5 , 8 , 9 };
 
     public static void main(String[] args) {
         DBUtil dbu = new DBUtil();
         // 操作提示信息
         String sOpeMsg = String.format(C_OPERATE_MSG, C_OPE_MSG_RESET_CONFIG,
                 C_OPE_MSG_CHANGE_HOST, C_OPE_MSG_CHANGE_PORT,
                 C_OPE_MSG_CHANGE_DB_NAME, C_OPE_MSG_CHANGE_UNAME,
                 C_OPE_MSG_CHANGE_PWD, C_OPE_MSG_CHANGE_DB_SOURCE,
                 C_OPE_MSG_EXIT);
         // 创建数据流接收对象
         BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
         String sInput = "" ;
         // 一直循环调用,直至选择退出
         int iOpe = - 1 ;
         boolean bExitFlag = false ;
         System.out.println( "系统已启动" );
         while ( true ) {
             switch (iOpe) {
             case I_OPE_LIST_RESET_USER_CONFIG:
                 dbu.initUserConfig();
                 break ;
             case I_OPE_LIST_CHANGE_HOST:
                 sInput = inputIP(br);
                 dbu.setsHostUser(sInput);
                 break ;
             case I_OPE_LIST_CHANGE_PORT:
                 sInput = inputPort(br);
                 dbu.setsPortUser(sInput);
                 break ;
             case I_OPE_LIST_CHANGE_DB_NAME:
                 sInput = inputDBName(br);
                 dbu.setsDBNameUser(sInput);
                 break ;
             case I_OPE_LIST_CHANGE_UNAME:
                 sInput = inputUName(br);
                 dbu.setsUNameUser(sInput);
                 break ;
             case I_OPE_LIST_CHANGE_PWD:
                 sInput = inputPWD(br);
                 dbu.setsPWDUser(sInput);
                 break ;
             case I_OPE_LIST_CHANGE_DB_SOURCE:
                 if (dbu.changeDBSourceByUser()) {
                     System.out.println( "数据源切换成功!!!" );
                 } else {
                     System.out.println( "数据源切换失败,请核对您的配置是否正确!!!" );
                 }
                 break ;
             case I_OPE_LIST_EXIT:
                 int nExit = GlobalUtil.readInt(br, "您确定要退出系统?1:是 2:否" , false ,
                         new int [] { 1 , 2 });
                 if (nExit == 1 ) {
                     bExitFlag = true ;
                 }
                 break ;
             }
             // 如果用户选择了确认退出,则退出循环
             if (bExitFlag) {
                 System.out.println( "系统已正常关闭" );
                 break ;
             }
             // 未选择退出则重复等待用户选择操作
             iOpe = GlobalUtil.readInt(br, sOpeMsg, false , I_OPE_LIST);
         }
     }
 
     /**
      * 等待控制台输入一个数据库密码
      *
      * @param br
      *            数据接收对象
      * @return 用户输入的密码
      */
     public static String inputPWD(BufferedReader br) {
         return GlobalUtil.readString(br, "请输入数据库密码" , false );
     }
 
     /**
      * 等待控制台输入一个数据库用户名
      *
      * @param br
      *            数据接收对象
      * @return 用户输入的用户名
      */
     public static String inputUName(BufferedReader br) {
         return GlobalUtil.readString(br, "请输入数据库用户名" , false );
     }
 
     /**
      * 等待控制台输入一个数据库实例名
      *
      * @param br
      *            数据接收对象
      * @return 用户输入的数据库实例名
      */
     public static String inputDBName(BufferedReader br) {
         return GlobalUtil.readString(br, "请输入数据库实例名" , false );
     }
 
     /**
      * 等待控制台输入一个合法的IP地址
      *
      * @param br
      *            数据接收对象
      * @return 一个合法的IP地址或空字符串
      */
     public static String inputIP(BufferedReader br) {
         String sHost = "" ;
         // 循环等待用户输入一个合法的IP地址
         while ( true ) {
             // 接收控制台输入的字符串
             sHost = GlobalUtil.readString(br, "请输入一个合法的IP地址" , false );
             // 如果不是一个合法的IP地址,则让用户重新输入,直至输入一个合法的IP地址
             if (!GlobalUtil.isValiIP(sHost)) {
                 continue ;
             }
             break ;
         }
         return sHost;
     }
 
     /**
      * 等待控制台输入一个合法的端口号
      *
      * @param br
      *            数据接收对象
      * @return 一个合法的端口或空字符串
      */
     public static String inputPort(BufferedReader br) {
         int nPort = 0 ;
         // 循环等待用户输入一个合法的端口
         while ( true ) {
             // 接收控制台输入的字符串
             nPort = GlobalUtil.readInt(br, "请输入一个合法的数据库端口" , false , null );
             // 如果不是一个合法的数据库端口,则让用户重新输入,直至输入一个合法的数据库端口
             if (!GlobalUtil.isValiPort(nPort)) {
                 continue ;
             }
             break ;
         }
         return nPort + "" ;
     }
 
}

[2].[文件] GlobalUtil.java ~ 4KB    下载(2) 跳至 [1] [2] [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
/**
  * @ProjectName ChangeDBSourceDEMO
  * @Package com.le
  * @ClassName GlobalUtil
  * @Description 常用工具类,主要提供一些公用的方法
  * @Author LE
  * @CreateDate 2015-09-10
  * @Version 1.0
  */
 
package com.le;
 
import java.io.BufferedReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class GlobalUtil {
 
     //合法端口号起始值
     public static final int N_PORT_BEGIN = 1024 ;
     //合法端口号结束值
     public static final int N_PORT_END = 65535 ;
 
     /**
      * 在命令行接收一个字符串
      *
      * @param br
      *            数据接收对象
      * @param sPromptMsg
      *            提示信息
      * @param allowNull
      *            是否允许录入空字符串
      * @return 控制台录入的字符串
      */
     public static String readString(BufferedReader br, String sPromptMsg,
             boolean allowNull) {
         // 如果为空则初始化一个提示
         if (sPromptMsg == null || "" .equals(sPromptMsg)) {
             sPromptMsg = "请输入一个字符串" ;
         }
         System.out.println(sPromptMsg);
         String result = "" ;
         try {
             // 循环读取数据
             while ( true ) {
                 result = br.readLine();
                 // 如果不允许为空,则一直输入,直到输入一个非空字符串为止
                 if (allowNull) {
                     break ;
                 }
                 // 如果不为空,则不允许空或空格输入
                 if ( "" .equals(result) || "" .equals(result.trim())) {
                     System.out.println(sPromptMsg);
                     continue ;
                 } else {
                     break ;
                 }
             }
         } catch (Exception e) {
             result = "" ;
         }
         return result;
     }
 
     /**
      * 在控制台接收一个int输入值
      *
      * @param br
      *            数据接收对象
      * @param sPromptMsg
      *            提示信息
      * @param allowNull
      *            是否允许输入空值
      * @return
      */
 
     public static int readInt(BufferedReader br, String sPromptMsg,
             boolean allowNull, int [] iRange) {
         // 如果为空则初始化一个提示
         if (sPromptMsg == null || "" .equals(sPromptMsg)) {
             sPromptMsg = "请输入一个数字" ;
         }
         System.out.println(sPromptMsg);
         int result = 0 ;
         String sResult = "" ;
         try {
             // 读取一行数据
             while ( true ) {
                 boolean bRange = true ;
                 sResult = br.readLine();
                 // 如果当前输入为空,并且不允许为空的话,继续输入
                 if ( "" .equals(sResult) && !allowNull) {
                     System.out.println(sPromptMsg);
                     continue ;
                 } else if (!isNumeric(sResult)) {
                     // 如果不允许为空并且不是一个有效的数字则让用户重新输入
                     System.out.println(sPromptMsg);
                     continue ;
                 }
                 result = Integer.parseInt(sResult);
                 // 判断是否在指定范围内
                 if (iRange != null ) {
                     bRange = false ;
                     for ( int i = 0 ; i < iRange.length; i++) {
                         if (result == iRange[i]) {
                             bRange = true ;
                             break ;
                         }
                     }
                     // 如果有输入范围限制并且当前输入值不在范围内,则让用户重新输入
                     if (!bRange) {
                         System.out.println(sPromptMsg);
                         continue ;
                     }
                 }
                 break ;
             }
         } catch (Exception e) {
             result = 0 ;
         }
         return result;
     }
 
     /**
      * 判断参数是否可以转换成数字
      *
      * @param str
      *            需要判断的参数
      * @return true:可以 false:不可以
      */
     public static boolean isNumeric(String str) {
         for ( int i = str.length(); --i >= 0 ;) {
             if (!Character.isDigit(str.charAt(i))) {
                 return false ;
             }
         }
         return true ;
     }
 
     /**
      * 验证参数是否为一个合法的IP地址
      *
      * @param sIP
      *            需要判断的参数
      * @return true:参数为一个合法的IP false:参数不是一个合法的IP
      */
     public static boolean isValiIP(String sIP) {
         String reg = "(([1-9])|([1-9]\\d)|([1]\\d{2})|([2][0-4]\\d)|([2][5][0-5]))"
                 + "(\\.((\\d)|([1-9]\\d)|([1]\\d{2})|([2][0-4]\\d)|([2][5][0-5]))){3}" ;
         Matcher matcher = Pattern.compile(reg).matcher(sIP);
         if (matcher.matches()) {
             return true ;
             // System.out.println("hi, match");
         } else {
             return false ;
             // System.out.println("not match...");
         }
     }
 
     /**
      * 验证参数是否为一个可用的端口
      *
      * @param nPort
      *            需要判断的端口号
      * @return true:端口号合法 false:端口号不合法
      */
     public static boolean isValiPort( int nPort) {
         return nPort >= N_PORT_BEGIN && nPort <= N_PORT_END;
     }
}

[3].[文件] DBUtil.java ~ 5KB    下载(2) 跳至 [1] [2] [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
/**
  * @ProjectName ChangeDBSourceDEMO
  * @Package com.le
  * @ClassName DBUtil
  * @Description 数据库工具类,主要提供获取数据库连接以及更改数据连接配置的功能
  * @Author LE
  * @CreateDate 2015-09-10
  * @Version 1.0
  */
 
package com.le;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
 
public class DBUtil {
 
     private static final String DRIVER = "oracle.jdbc.driver.OracleDriver" ;
     // jdbc:oracle:thin:@127.0.0.1:1521:ORCL
     private static final String URL = "jdbc:oracle:thin:@%s:%s:%s" ;
 
     private String sHost = "127.0.0.1" ;
     private String sPort = "1521" ;
     private String sDBName = "ORCL" ;
     private String sUName = "UserName" ;
     private String sPWD = "password" ;
 
     // 用户缓存的变量
     private String sHostUser = "127.0.0.1" ;
     private String sPortUser = "1521" ;
     private String sDBNameUser = "ORCL" ;
     private String sUNameUser = "UserName" ;
     private String sPWDUser = "password" ;
 
     /**
      * 初始化用户配置信息
      */
     public void initUserConfig() {
         this .sHostUser = this .sHost;
         this .sPortUser = this .sPort;
         this .sDBNameUser = this .sDBName;
         this .sUNameUser = this .sUName;
         this .sPWDUser = this .sPWD;
     }
 
     /**
      * 使用用户配置切换数据源
      *
      * @return true:切换成功 false:切换失败
      */
     public boolean changeDBSourceByUser() {
         return this .changeDBSource(sHostUser, sPortUser, sDBNameUser,
                 sUNameUser, sPWDUser);
     }
 
     /**
      * 切换数据源
      *
      * @param sHost
      *            新数据源主机
      * @param sPort
      *            新数据源端口
      * @param sDBName
      *            新数据源数据库名
      * @param sUName
      *            新数据源用户名
      * @param sPWD
      *            新数据源密码
      * @return true:切换成功 false:切换失败
      */
     public boolean changeDBSource(String sHost, String sPort, String sDBName,
             String sUName, String sPWD) {
         if ( this .checkConnConfig(sHost, sPort, sDBName, sUName, sPWD)) {
             this .sHost = sHost;
             this .sPort = sPort;
             this .sDBName = sDBName;
             this .sUName = sUName;
             this .sPWD = sPWD;
             return true ;
         } else {
             return false ;
         }
     }
 
     /**
      * 使用传入的字符串获取一个数据库连接
      *
      * @param sHost
      *            主机
      * @param sPort
      *            端口
      * @param sDBName
      *            数据库名
      * @param sUName
      *            用户名
      * @param sPWD
      *            密码
      * @return 数据库连接对象,如果获取失败返回null
      */
 
     public Connection getConn(String sHost, String sPort, String sDBName,
             String sUName, String sPWD) {
         try {
             // 使用变量拼接连接串
             String sUrl = String.format(URL, sHost, sPort, sDBName);
             // 初始化驱动 这里只支持oracle,可以做兼容其他数据库,通过配置增加对应代码即可
             Class.forName(DRIVER);
             // 获取连接
             return DriverManager.getConnection(sUrl, sUName, sPWD);
         } catch (Exception e) {
             e.printStackTrace();
             return null ;
         }
     }
 
     /**
      * 根据预定连接串获取一个数据库连接
      *
      * @return 数据库连接对象,如果获取失败返回null
      */
     public Connection getConn() {
         try {
             // 使用变量拼接连接串
             String sUrl = String.format(URL, sHost, sPort, sDBName);
             // 初始化驱动 这里只支持oracle,可以做兼容其他数据库,通过配置增加对应代码即可
             Class.forName(DRIVER);
             // 获取连接
             return DriverManager.getConnection(sUrl, sUName, sPWD);
         } catch (Exception e) {
             return null ;
         }
     }
 
     /**
      * 根据传入的参数,验证连接是否可用
      *
      * @param sHost
      *            主机
      * @param sPort
      *            端口
      * @param sDBName
      *            数据库名称
      * @param sUName
      *            用户名
      * @param sPWD
      *            密码
      * @return true:数据库连接正常 false:数据库连接异常
      */
     public boolean checkConnConfig(String sHost, String sPort, String sDBName,
             String sUName, String sPWD) {
         Connection conn = null ;
         try {
             conn = this .getConn(sHost, sPort, sDBName, sUName, sPWD);
             return conn != null ;
         } finally {
             if (conn != null ) {
                 try {
                     conn.close();
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
         }
     }
 
     /**
      * 验证当前数据库连接配置是否可用
      *
      * @return true:数据库连接正常 false:数据库连接异常
      */
     public boolean checkConnConfig() {
         Connection conn = null ;
         try {
             conn = this .getConn();
             return conn != null ;
         } finally {
             if (conn != null ) {
                 try {
                     conn.close();
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
         }
     }
 
     public String getsHostUser() {
         return sHostUser;
     }
 
     public void setsHostUser(String sHostUser) {
         this .sHostUser = sHostUser;
     }
 
     public String getsPortUser() {
         return sPortUser;
     }
 
     public void setsPortUser(String sPortUser) {
         this .sPortUser = sPortUser;
     }
 
     public String getsDBNameUser() {
         return sDBNameUser;
     }
 
     public void setsDBNameUser(String sDBNameUser) {
         this .sDBNameUser = sDBNameUser;
     }
 
     public String getsUNameUser() {
         return sUNameUser;
     }
 
     public void setsUNameUser(String sUNameUser) {
         this .sUNameUser = sUNameUser;
     }
 
     public String getsPWDUser() {
         return sPWDUser;
     }
 
     public void setsPWDUser(String sPWDUser) {
         this .sPWDUser = sPWDUser;
     }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值