jdbc连接池
1 import java.lang.reflect.InvocationHandler; 2 import java.lang.reflect.InvocationTargetException; 3 import java.lang.reflect.Method; 4 import java.lang.reflect.Proxy; 5 import java.sql.Connection; 6 import java.sql.Statement; 7 8 public class _Connection implements InvocationHandler { 9 private Connection conn = null; 10 private boolean coding = false; 11 // 指定是否进行字符串转码操作 12 _Connection(Connection conn, boolean coding){ 13 this.conn = conn; 14 this.coding = coding; 15 //initConnectionParam(this.conn); 16 } 17 18 /** 19 * Returns the conn. 20 * @return Connection 21 */ 22 23 public Connection getConnection() { 24 Class[] interfaces = conn.getClass().getInterfaces(); 25 if(interfaces==null||interfaces.length==0){ 26 interfaces = new Class[1]; 27 interfaces[0] = Connection.class; 28 29 } 30 31 Connection conn2 = (Connection)Proxy.newProxyInstance( 32 conn.getClass().getClassLoader(), interfaces,this); 33 return conn2; 34 35 } 36 37 /** 38 * @see java.lang.reflect.InvocationHandler#invoke 39 */ 40 public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { 41 String method = m.getName(); 42 // 调用相应的操作 43 Object obj = null; 44 try{ 45 obj = m.invoke(conn, args); 46 // 接管用于获取语句句柄实例的方法 47 if((CS.equals(method)||PS.equals(method))&&coding) 48 return new _Statement((Statement)obj,true).getStatement(); 49 50 } catch(InvocationTargetException e) { 51 throw e.getTargetException(); 52 } 53 return obj; 54 } 55 56 private final static String PS = "prepareStatement"; 57 private final static String CS = "createStatement"; 58 }
1 import java.sql.ResultSet; 2 import java.lang.reflect.InvocationHandler; 3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 7 public class _ResultSet implements InvocationHandler { 8 private ResultSet rs = null; 9 private boolean decode = false; 10 11 public _ResultSet(ResultSet rs,boolean decode) { 12 this.rs = rs; 13 this.decode = decode; 14 } 15 16 public ResultSet getResultSet(){ 17 Class[] interfaces = rs.getClass().getInterfaces(); 18 if(interfaces==null||interfaces.length==0){ 19 interfaces = new Class[1]; 20 interfaces[0] = ResultSet.class; 21 } 22 23 ResultSet rs2 = (ResultSet)Proxy.newProxyInstance(rs.getClass(). 24 getClassLoader(), interfaces,this); 25 return rs2; 26 27 } 28 /** 29 * 结果 getString 方法 30 */ 31 public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { 32 String method = m.getName(); 33 if(decode && GETSTRING.equals(method)){ 34 try{ 35 String result = (String)m.invoke(rs,args); 36 if(result!=null) 37 return new String(result.getBytes("8859_1")); 38 return null; 39 40 }catch(InvocationTargetException e){ 41 throw e.getTargetException(); 42 } 43 44 } 45 46 try{ 47 return m.invoke(rs, args); 48 }catch(InvocationTargetException e){ 49 throw e.getTargetException(); 50 } 51 } 52 53 private final static String GETSTRING = "getString"; 54 }
1 import java.lang.reflect.InvocationHandler; 2 import java.lang.reflect.InvocationTargetException; 3 import java.lang.reflect.Method; 4 import java.lang.reflect.Proxy; 5 import java.sql.ResultSet; 6 import java.sql.Statement; 7 8 public class _Statement implements InvocationHandler { 9 private Statement statement ; // 保存所接管对象的实例 10 private boolean decode = false; // 指定是否进行字符串转码 11 public _Statement(Statement stmt,boolean decode) { 12 this.statement = stmt; 13 this.decode = decode; 14 } 15 16 /** 17 * 获取一个接管后的对象实例 18 * @return 19 */ 20 public Statement getStatement() { 21 Class[] interfaces = statement.getClass().getInterfaces(); 22 if(interfaces==null||interfaces.length==0){ 23 interfaces = new Class[1]; 24 interfaces[0] = Statement.class; 25 } 26 Statement stmt = (Statement)Proxy.newProxyInstance( 27 statement.getClass().getClassLoader(), 28 interfaces,this); 29 return stmt; 30 31 } 32 33 /** 34 * 方法接管 35 */ 36 public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { 37 String method = m.getName(); // 接管 setString 方法 38 if(decode && SETSTRING.equals(method)) { 39 try{ 40 String param = (String)args[1]; 41 if(param!=null) 42 param = new String(param.getBytes(),"8859_1"); 43 return m.invoke(statement,new Object[]{args[0],param}); 44 } catch(InvocationTargetException e){ 45 throw e.getTargetException(); 46 47 } 48 } 49 50 // 接管 executeQuery 方法 51 52 if(decode && EXECUTEQUERY.equals(method)){ 53 try{ 54 ResultSet rs = (ResultSet)m.invoke(statement,args); 55 return new _ResultSet(rs,decode).getResultSet(); 56 57 }catch(InvocationTargetException e){ 58 throw e.getTargetException(); 59 } 60 } 61 62 try{ 63 return m.invoke(statement, args); 64 } catch(InvocationTargetException e) { 65 throw e.getTargetException(); 66 } 67 } 68 // 两个要接管的方法名 69 70 private final static String SETSTRING = "setString"; 71 private final static String EXECUTEQUERY = "executeQuery"; 72 }
1 import java.sql.Connection; 2 import java.sql.ResultSet; 3 4 5 /** 6 * @author zhangqh 7 * @version 2.0 8 */ 9 10 public class DatabasePoolTest { 11 12 public static void main(String[] args) { 13 14 DataConnectMgr mgr = DataConnectMgr.getInstance(); 15 //从数据库连接池中获取连接 16 Connection con = mgr.getConnection("Mysql"); 17 try { 18 System.out.println("正在使用刚刚获得的数据库连接MySQL"); 19 java.sql.Statement sm = con.createStatement(); 20 String sql = "SELECT * FROM mytable"; 21 ResultSet rs = sm.executeQuery(sql); 22 while (rs.next()) 23 { 24 System.out.println(rs.getString(1)); 25 } 26 rs.close(); 27 sm.close(); 28 } catch (java.sql.SQLException e) { 29 System.err.println("连接Mysql数据库出错!"+e.getMessage()); 30 } finally { 31 //释放连接到数据库连接池 32 mgr.freeConnection("Mysql", con); 33 } 34 Connection con2 = mgr.getConnection("Oracle"); 35 try { 36 System.out.println("正在使用刚刚获得的数据库连接Oracle"); 37 java.sql.Statement sm = con2.createStatement(); 38 String sql = "SELECT * FROM testtable"; 39 ResultSet rs = sm.executeQuery(sql); 40 while (rs.next()) 41 { 42 System.out.println(rs.getString(1)); 43 } 44 rs.close(); 45 sm.close(); 46 } catch (java.sql.SQLException e) { 47 System.err.println("连接Oracle数据库出错!"+e.getMessage()); 48 } finally { 49 //释放连接到数据库连接池 50 mgr.freeConnection("Oracle", con2); 51 } 52 mgr.release(); 53 } 54 }
1 import java.io.InputStream; 2 import java.sql.Connection; 3 import java.sql.Driver; 4 import java.sql.DriverManager; 5 import java.sql.SQLException; 6 import java.util.Date; 7 import java.util.Enumeration; 8 import java.util.Hashtable; 9 import java.util.Iterator; 10 import java.util.LinkedList; 11 import java.util.Map; 12 import java.util.Properties; 13 import java.util.StringTokenizer; 14 import java.util.Vector; 15 16 /** 17 * @author zhangqh 18 * @version 2.0 19 * 数据库连接管理器,能够管理不同种类数据库的连接池。 20 */ 21 public class DataConnectMgr { 22 //缺省的数据库连接池配置文件 23 public static final String DEFAULT_DB_PROPERTIES = "/conf/db.properties"; 24 // 唯一实例 25 static private DataConnectMgr instance; 26 // 当前连接到该数据连接管理器上的客户端数目 27 static private int clients; 28 //存放驱动类,对于每种数据库,都有一个驱动类 29 private Vector drivers = new Vector(); 30 //存放已经建立的连接池,每种数据库都有一个连接池 31 private Hashtable pools = new Hashtable(); 32 33 /** 34 * 构造函数私有,以防止其它对象创建本类实例 35 */ 36 private DataConnectMgr() { 37 init(); 38 } 39 private DataConnectMgr(LinkedList drivers, Hashtable jdbcs) { 40 init2(drivers, jdbcs); 41 } 42 43 /** 44 * 单例模式,返回唯一实例,如果是第一次调用此方法,则创建实例, 45 * 根据缺省的数据库连接池配置文件创建连接池 46 * @return DBConnectionManager 唯一实例 47 */ 48 public static synchronized DataConnectMgr getInstance() { 49 if (instance != null) { 50 clients++; 51 return instance; 52 } else { 53 instance = new DataConnectMgr(); 54 return instance; 55 } 56 } 57 /** 58 * 获取数据库连接管理器实例,如果不存在,便创建实例,并指定了创建连接池的参数 59 * @param jdbcInfo 连接数据库的参数 60 * @return 61 */ 62 public static synchronized DataConnectMgr getInstance(JDBCInfo jdbcInfo) { 63 if (instance != null) { 64 clients++; 65 return instance; 66 } 67 LinkedList drivers = new LinkedList(); 68 drivers.add(jdbcInfo.getDriver()); 69 Hashtable jdbcs = new Hashtable(); 70 jdbcs.put(jdbcInfo.getName(), jdbcInfo); 71 return getInstance(drivers, jdbcs); 72 } 73 74 /** 75 * 获取数据库连接管理器实例,如果不存在,便创建实例,可以一次创建多个连接池 76 * @param drivers 每个连接池的数据库驱动类 77 * @param jdbcs 每个连接池的连接参数 78 * @return 79 */ 80 public static synchronized DataConnectMgr getInstance(LinkedList drivers, 81 Hashtable jdbcs) { 82 if (instance == null) { 83 instance = new DataConnectMgr(drivers, jdbcs); 84 } 85 clients++; 86 return instance; 87 } 88 89 /** 90 * 读取缺省的数据库连接池配置文件,根据缺省值完成初始化,创建数据库连接池 91 */ 92 private void init() { 93 InputStream is = null; 94 Properties dbProps = new Properties(); 95 try { 96 is = getClass().getResourceAsStream(DEFAULT_DB_PROPERTIES); 97 dbProps.load(is); 98 } catch (Exception e) { 99 System.err 100 .println("不能够读取默认数据库连接池配置文件,请确认文件是否存在:" 101 + DEFAULT_DB_PROPERTIES); 102 return; 103 } 104 loadDrivers(dbProps); 105 createPools(dbProps); 106 } 107 108 /** 109 * 创建多个数据库连接池 110 * @param drivers 每个连接池的数据库驱动类 111 * @param jdbcInfo 每个连接池的连接参数 112 */ 113 private void init2(LinkedList drivers, Hashtable jdbcInfo) { 114 loadDrivers(drivers); 115 createPools(jdbcInfo); 116 } 117 118 /** 119 * 动态加载数据库连接驱动类 120 * @param mdrivers 121 */ 122 private void loadDrivers(LinkedList mdrivers) { 123 for (int i = 0; i < mdrivers.size(); i++) { 124 try { 125 //根据数据库连接驱动类,利用反射机制创建驱动类对象 126 Driver driver = (Driver) Class 127 .forName((String) mdrivers.get(i)).newInstance(); 128 DriverManager.registerDriver(driver); 129 drivers.addElement(driver); 130 System.out.println("成功加载数据库连接驱动: " 131 + mdrivers.get(i)); 132 } catch (Exception e) { 133 System.err.println("加载数据库连接驱动失败: " 134 + mdrivers.get(i) + ". 错误信息:" + e); 135 } 136 } 137 } 138 139 /** 140 * 装载和注册数据库连接配置文件中所有的JDBC驱动程序 141 * @param props 属性 142 */ 143 private void loadDrivers(Properties props) { 144 String driverClasses = null; 145 driverClasses = props.getProperty("drivers"); 146 147 StringTokenizer st = new StringTokenizer(driverClasses); 148 while (st.hasMoreElements()) { 149 String driverClassName = st.nextToken().trim(); 150 try { 151 // 新建驱动类 152 Driver driver = (Driver) Class.forName(driverClassName) 153 .newInstance(); 154 // 注册驱动 155 DriverManager.registerDriver(driver); 156 drivers.addElement(driver); 157 System.out.println("成功加载数据库连接驱动: " 158 + driverClassName); 159 } catch (Exception e) { 160 System.err.println("加载数据库连接驱动失败: " 161 + driverClassName + ". 错误信息: " + e); 162 } 163 } 164 } 165 166 /** 167 * 根据指定的数据库连接池配置文件创建连接池实例. 168 * @param props 连接池属性 169 */ 170 private void createPools(Properties props) { 171 Enumeration propNames = props.propertyNames(); 172 while (propNames.hasMoreElements()) { 173 String name = (String) propNames.nextElement(); 174 // 获得连接数据库的各种属性 175 if (name.endsWith(".url")) { 176 String poolName = name.substring(0, name.lastIndexOf(".")); 177 String url = props.getProperty(poolName + ".url"); 178 if (url == null) { 179 continue; 180 } 181 String user = props.getProperty(poolName + ".user"); 182 String password = props.getProperty(poolName + ".password"); 183 String maxconn = props.getProperty(poolName + ".maxconn", "0"); 184 185 int max; 186 try { 187 max = Integer.valueOf(maxconn).intValue(); 188 } catch (NumberFormatException e) { 189 System.err.println("最大连接数限制数错误: " 190 + maxconn + " .连接池名: " + poolName); 191 max = 0; 192 } 193 // System.out.println("准备创建数据库连接池:" + poolName); 194 DBConnectionPool pool = new DBConnectionPool(poolName, url, 195 user, password, max); 196 pools.put(poolName, pool); 197 // System.out.println("创建数据库连接池: " + poolName + "成功"); 198 } 199 } 200 } 201 202 /** 203 * 根据数据库连接池配置信息创建连接池 204 * @param jdbcInfos 205 */ 206 private void createPools(Hashtable jdbcInfos) { 207 208 Iterator it = jdbcInfos.entrySet().iterator(); 209 while (it.hasNext()) { 210 Map.Entry en = (Map.Entry) it.next(); 211 JDBCInfo info = (JDBCInfo) en.getValue(); 212 if (info.getUrl() == null) { 213 continue; 214 } 215 System.out.println("准备创建数据库连接池: " + (String) en.getKey()); 216 DBConnectionPool pool = new DBConnectionPool((String) en.getKey(), 217 info.getUrl(), info.getUser(), info.getPassword(), info 218 .getMaxconn()); 219 pools.put(en.getKey(), pool); 220 } 221 } 222 223 /** 224 * 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数 225 * 限制,则创建并返回新连接 226 * @param name 在属性文件中定义的连接池名字 227 * @return Connection 可用连接或null 228 */ 229 public Connection getConnection(String name) { 230 DBConnectionPool pool = (DBConnectionPool) pools.get(name); 231 if (pool != null) { 232 // System.out.println("从数据库连接池:" + pool.getName() + "获取一个连接!"); 233 return pool.getConnection(); 234 } 235 return null; 236 } 237 238 /** 239 * 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制, 240 * 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接. 241 * 242 * @param name 连接池名字 243 * @param time 以毫秒计的等待时间 244 * @return Connection 可用连接或null 245 */ 246 public Connection getConnection(String name, long time) { 247 DBConnectionPool pool = (DBConnectionPool) pools.get(name); 248 if (pool != null) { 249 return pool.getConnection(time); 250 } 251 return null; 252 } 253 254 /** 255 * 将连接对象返回给由名字指定的连接池 256 * @param name 在属性文件中定义的连接池名字,即数据源信息中的name字段 257 * @param con 连接对象 258 */ 259 public void freeConnection(String name, Connection con) { 260 DBConnectionPool pool = (DBConnectionPool) pools.get(name); 261 if (pool != null) { 262 // System.out.println("释放了一个数据库连接到连接池:" + pool.getName()); 263 pool.freeConnection(con); 264 } 265 } 266 267 /** 268 * 关闭所有连接,撤销驱动程序的注册 , 269 * 只有当连接到该数据库连接管理器的客户端数目为0时,才能够完成撤销。 270 */ 271 public synchronized void release() { 272 // 等待直到最后一个客户程序调用 273 // if (--clients != 0) { 274 // return; 275 // } 276 //释放连接池 277 Enumeration allPools = pools.elements(); 278 while (allPools.hasMoreElements()) { 279 DBConnectionPool pool = (DBConnectionPool) allPools.nextElement(); 280 System.out.println("准备关闭数据库连接池: " + pool.getName()); 281 pool.release(); 282 System.out.println("数据库连接池: " + pool.getName() + "已经被关闭!"); 283 } 284 //反注册已经注册的数据库连接驱动类 285 Enumeration allDrivers = drivers.elements(); 286 while (allDrivers.hasMoreElements()) { 287 Driver driver = (Driver) allDrivers.nextElement(); 288 try { 289 DriverManager.deregisterDriver(driver); 290 System.out.println("数据库连接驱动:" + driver.getClass().getName() + "已经被注销了!"); 291 } catch (SQLException e) { 292 } 293 } 294 } 295 296 /** 297 * 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最 298 * 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性. 299 */ 300 class DBConnectionPool { 301 private int checkedOut = 0;//当前已经被取走的数据库连接数,也就是正在被使用的连接数 302 private Vector freeConnections = new Vector();//该连接池中可用的数据库连接 303 private int maxConn;//该连接池允许的最大数据库连接数 304 private String name;//数据库连接池的名字 305 private String user;//连接数据库的用户名 306 private String password;//连接数据库的密码 307 private String URL;//数据库的URL 308 309 //默认构造函数 310 public DBConnectionPool() { 311 this.maxConn = 0; 312 this.password = ""; 313 this.URL = ""; 314 } 315 /**创建新的连接池 316 * @param name 连接池名字 317 * @param URL 数据库的JDBC URL 318 * @param user 数据库帐号,或 null 319 * @param password 密码,或 null 320 * @param maxConn 此连接池允许建立的最大连接数 321 */ 322 public DBConnectionPool(String name, String URL, String user, 323 String password, int maxConn) { 324 this.name = name; 325 this.URL = URL; 326 this.user = user; 327 this.password = password; 328 this.maxConn = maxConn; 329 this.initConnection(); 330 } 331 /** 332 * 创建新的连接 333 */ 334 private Connection newConnection() { 335 Connection con = null; 336 Connection conn = null; 337 try { 338 if (user == null) { 339 con = DriverManager.getConnection(URL.trim()); 340 } else { 341 con = DriverManager.getConnection(URL, user, password); 342 } 343 boolean coding = true; // 从配置或者其他地方读取是否进行转码的配置 344 // 接管数据库连接实例 345 _Connection _conn = new _Connection(con,coding); 346 // 获得接管后的数据库连接实例,以后直接使用 conn 而不是 con 347 conn = _conn.getConnection(); 348 // System.out.println("连接池" + this.name + "创建一个新的数据库连接, 目前共有" + this.checkedOut + "个连接在使用!"); 349 } catch (SQLException e) { 350 System.err.println(e.getMessage()); 351 return null; 352 } 353 return conn; 354 } 355 /** 356 * 预先打开一个连接 357 */ 358 private void initConnection() { 359 Connection con = getConnection(); 360 freeConnections.addElement(con); 361 } 362 /** 363 * 从连接池获得一个可用连接.如没有空闲的连接且当前使用的连接数小于最大连接 364 * 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之, 365 * 然后递归调用自己以尝试新的可用连接. 366 */ 367 public synchronized Connection getConnection() { 368 Connection con = null; 369 if (freeConnections.size() > 0) { 370 // 获取向量中第一个可用连接 371 con = (Connection) freeConnections.firstElement(); 372 freeConnections.removeElementAt(0); 373 try { 374 //如果存放的这个连接已经过期或者不可用,则继续获取 375 if ((con == null) || (con.isClosed())) { 376 con = getConnection(); 377 } 378 } catch (SQLException e) { 379 con = getConnection(); 380 } 381 } else if (maxConn == 0 || checkedOut < maxConn) { 382 //创建新的连接 383 // System.out.println("数据库连接池: " + this.name + "准备创建一个新的连接"); 384 con = newConnection(); 385 } else { 386 System.out.println("数据库连接池" + this.name + "没有可用的连接!"); 387 } 388 if (con != null){ 389 this.checkedOut++; 390 } 391 return con; 392 } 393 394 /** 395 * 从连接池获取可用连接.可以指定客户程序能够等待的最长时间 396 * 参见前一个getConnection()方法. 397 * 398 * @param timeout 以毫秒计的等待时间限制 399 */ 400 public synchronized Connection getConnection(long timeout) { 401 long startTime = new Date().getTime(); 402 Connection con; 403 while ((con = getConnection()) == null) { 404 try { 405 //等待一段时间,期待其他客户端释放连接。 406 wait(timeout); 407 } catch (InterruptedException e) { 408 } 409 if ((new Date().getTime() - startTime) >= timeout) { 410 // wait()返回的原因是超时,表示没有得到可用的连接,返回null 411 return null; 412 } 413 } 414 return con; 415 } 416 /** 417 * 将不再使用的连接返回给连接池 418 * @param con 客户程序释放的连接 419 */ 420 public synchronized void freeConnection(Connection con) { 421 // 将指定连接加入到向量末尾 422 freeConnections.addElement(con); 423 checkedOut--; 424 notifyAll(); 425 } 426 /** 427 * 关闭所有连接 428 */ 429 public synchronized void release() { 430 Enumeration allConnections = freeConnections.elements(); 431 while (allConnections.hasMoreElements()) { 432 Connection con = (Connection) allConnections.nextElement(); 433 try { 434 con.close(); 435 System.out.println("关闭了数据库连接池:" + this.name + "中的一个数据库连接!"); 436 } catch (SQLException e) { 437 System.err.println("无法关闭连接池" + this.name + "中的连接" 438 + e.getMessage()); 439 } 440 } 441 freeConnections.removeAllElements(); 442 } 443 /** 444 * 返回数据库连接池的名字 445 */ 446 public String getName(){ 447 return this.name; 448 } 449 } 450 }
1 public class JDBCInfo { 2 /**连接数据库的相关信息*/ 3 private String driver; //连接数据库的驱动类 4 private String url; //数据库的路径 5 private String user; //用户名 6 private String password;//密码 7 private String name; //数据库连接池的名字 8 private int maxconn; //最大连接数 9 10 public JDBCInfo() { 11 this.driver = ""; 12 this.url = ""; 13 this.name = ""; 14 this.maxconn = 0; 15 } 16 public JDBCInfo(String name, String driver, String url, 17 String user, String password, int maxconn) { 18 this.name = name; 19 this.driver = driver; 20 this.user = user; 21 this.password = password; 22 this.maxconn = maxconn; 23 this.url = url; 24 } 25 26 public String getDriver() { 27 return driver; 28 } 29 public void setDriver(String driver) { 30 this.driver = driver; 31 } 32 public int getMaxconn() { 33 return maxconn; 34 } 35 public void setMaxconn(int maxconn) { 36 this.maxconn = maxconn; 37 } 38 public String getPassword() { 39 return password; 40 } 41 public void setPassword(String password) { 42 this.password = password; 43 } 44 public String getUrl() { 45 return url; 46 } 47 public void setUrl(String url) { 48 this.url = url; 49 } 50 public String getUser() { 51 return user; 52 } 53 public void setUser(String user) { 54 this.user = user; 55 } 56 public String getName() { 57 return name; 58 } 59 public void setName(String name) { 60 this.name = name; 61 } 62 }
配置文件:db.properties
1 drivers=com.mysql.jdbc.Driver oracle.jdbc.driver.OracleDriver 2 Mysql.url=jdbc:mysql://127.0.0.1:3306/test 3 Mysql.user=testuser 4 Mysql.password=test 5 Mysql.maxconn=10 6 7 Oracle.url=jdbc:oracle:thin:@localhost:1521:orcl 8 Oracle.user=smsmain 9 Oracle.password=smsmain 10 Oracle.maxconn=10