小弟在一个系统里面有许多使用java查询sqlserver的地方。所以我写了下面几个类,感觉有些问题,想请教一下高人,欢迎大家指导。
下面我先介绍一下我的几个类,然后是代码示例。
(看在偶写了这么多的份上,希望能有高人愿意指点小弟一下,谢谢:)
===========================
下面共有三个类,connectdb,AutoMonitorDB,AutoMonitor
connectdb是链接数据库类,包含一个方法getConnection,其作用是从数据库中得到一个链接,并存储在成员变量conn,然后返回这个成员遍历。AutoMonitorDB类是封装了业务逻辑类AutoMonitor类中所有数据库操作方法的类。
在构造类的时候得到connectdb类的实例。
有一个ReleaseConn()方法,用来释放类成员变量中的链接的。
还包含两个操作
GetRealRiverDataAndLevel() 返回一个ResultSet集合,共AutoMonitor类里面的方法使用。因为要返回ResultSet集合,所以不能关闭数据库链接。我的做法是在方法中使用AutoMonitorDB的成员变量的conn链接对象,AutoMonitor类中在使用完该函数返回的ResultSet集合后再调用AutoMonitorDB的ReleaseConn方法,释放AutoMonitorDB的成员变量链接conn。
ChangeValleyAlarmInfo()方法是一个update操作,因为不用返回resultset集合,所以我在此方法中从成员connectionDB独立得到一个新的链接,使用完后再释放。 问题是在AutoMonitor类中某个方法当使用要上面类的第一个方法返回ResultSet后还没有调用ReleaseConn方法释放链接,就又需要调用AutoMonitorDB的其他方法,这样就又会创建新的链接。如果是ChangeValleyAlarmInfo()这一类的方法话,在调用后会释放链接。 我最初的想法是这样同时多个嵌套调用会申请多个链接,释放也会依次释放,应该没有问题。但现在webLogic总是报连接池没有释放链接。并且还存在ResultSet在使用时被关闭的问题。但我的代码也不是不能运行,在webLogic上一般都可以正常运行一段时间,只是报连接池的链接没有释放,被gc释放的warning。然后就会报一些链接不够,程序就开始出现问题。 我可以保证我的所以链接都对应有释放,并且都是finally里面。但很多申请和释放链接都是嵌套的(这就是我现在担心的地方)。
有的朋友建议对DB类共用一个链接对象。也就时在AutoMonitorDB里面所有的操作都不申请也不释放链接,而是共用类成员变量里面的链接对象。然后在整个业务逻辑开始时初始化DB类,并为其申请一个链接。在最后释放掉这个链接,中间所有使用DB类的操作的时候都不释放链接。请问这种方法可行吗?
====================== =====public class connectdb {
private Connection conn = null; public Connection getConnection() {
try {
Context ctx = new InitialContext();
javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup("LYDS");
conn = ds.getConnection();
} catch (Exception e) {
System.out.println(e.toString());
}
return conn;
}
}
==================================================
public class AutoMonitorDB {
private connectdb connectionDB;
private Connection conn;
private PreparedStatement ps; public AutoMonitorDB() {
connectionDB = new connectdb() ;
}
/**
*
* 释放类中的数据库链接
*
* @return 释放成功true ,异常false
* */ public boolean ReleaseConn() {
try{
if(ps!=null)
ps.close() ;
if(conn!=null)
conn.close() ;
}
catch(Exception e){
System.out.println(e.toString() );
return false;
}
return true;
} /**
*
* @return 的ResultSet集合
* */
public ResultSet GetRealRiverDataAndLevel() {
conn = this.connectionDB.getConnection();
ResultSet result = null;
String sql;
try {
sql = "SELECT VNO FROM ST_WLVALUE_R,ST_WLSN";
ps = conn.prepareStatement(sql);
result = ps.executeQuery();
} catch (Exception e) {
System.out.println(e.toString());
return null;
}
return result;
}
/**
* 使用update语句操作数据库
*
* @param vno 流域编号
* @param bj 要修改的新的报警级别
* @return 成功true,失败false
* * */
public boolean ChangeValleyAlarmInfo(String vno) {
Connection conn = this.connectionDB.getConnection();
PreparedStatement ps = null;
String sql;
try {
sql = "update TBL_VALLEYINFO where VNO = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, vno);
ps.execute();
} catch (Exception e) {
System.out.println(e.toString());
return false;
} finally {
try {
ps.close();
conn.close();
} catch (Exception e1) {
System.out.println(e1.toString());
}
}
return true;
}
}
=================================
public class AutoMonitor implements ActionListener {
AutoMonitorDB am= new AutoMonitorDB() ;
//使用AutoMonitorDB类的GetRealRiverDataAndLevel()函数,即使用ResultSet集合
public void RainMonitor(){
ResultSet rs = am.GetRealRiverDataAndLevel() ;
try{
while(rs.next() ){
String valleyNo=rs.getString("VNO");
//使用AutoMonitorDB类的ChangeValleyAlarmInfo函数
boolean b=am.ChangeValleyAlarmInfo("aaa");
}
rs.close() ; } catch (Exception e1) {
System.out.println(e1.toString());
} finally {
am.ReleaseConn();
}
}
下面我先介绍一下我的几个类,然后是代码示例。
(看在偶写了这么多的份上,希望能有高人愿意指点小弟一下,谢谢:)
===========================
下面共有三个类,connectdb,AutoMonitorDB,AutoMonitor
connectdb是链接数据库类,包含一个方法getConnection,其作用是从数据库中得到一个链接,并存储在成员变量conn,然后返回这个成员遍历。AutoMonitorDB类是封装了业务逻辑类AutoMonitor类中所有数据库操作方法的类。
在构造类的时候得到connectdb类的实例。
有一个ReleaseConn()方法,用来释放类成员变量中的链接的。
还包含两个操作
GetRealRiverDataAndLevel() 返回一个ResultSet集合,共AutoMonitor类里面的方法使用。因为要返回ResultSet集合,所以不能关闭数据库链接。我的做法是在方法中使用AutoMonitorDB的成员变量的conn链接对象,AutoMonitor类中在使用完该函数返回的ResultSet集合后再调用AutoMonitorDB的ReleaseConn方法,释放AutoMonitorDB的成员变量链接conn。
ChangeValleyAlarmInfo()方法是一个update操作,因为不用返回resultset集合,所以我在此方法中从成员connectionDB独立得到一个新的链接,使用完后再释放。 问题是在AutoMonitor类中某个方法当使用要上面类的第一个方法返回ResultSet后还没有调用ReleaseConn方法释放链接,就又需要调用AutoMonitorDB的其他方法,这样就又会创建新的链接。如果是ChangeValleyAlarmInfo()这一类的方法话,在调用后会释放链接。 我最初的想法是这样同时多个嵌套调用会申请多个链接,释放也会依次释放,应该没有问题。但现在webLogic总是报连接池没有释放链接。并且还存在ResultSet在使用时被关闭的问题。但我的代码也不是不能运行,在webLogic上一般都可以正常运行一段时间,只是报连接池的链接没有释放,被gc释放的warning。然后就会报一些链接不够,程序就开始出现问题。 我可以保证我的所以链接都对应有释放,并且都是finally里面。但很多申请和释放链接都是嵌套的(这就是我现在担心的地方)。
有的朋友建议对DB类共用一个链接对象。也就时在AutoMonitorDB里面所有的操作都不申请也不释放链接,而是共用类成员变量里面的链接对象。然后在整个业务逻辑开始时初始化DB类,并为其申请一个链接。在最后释放掉这个链接,中间所有使用DB类的操作的时候都不释放链接。请问这种方法可行吗?
====================== =====public class connectdb {
private Connection conn = null; public Connection getConnection() {
try {
Context ctx = new InitialContext();
javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup("LYDS");
conn = ds.getConnection();
} catch (Exception e) {
System.out.println(e.toString());
}
return conn;
}
}
==================================================
public class AutoMonitorDB {
private connectdb connectionDB;
private Connection conn;
private PreparedStatement ps; public AutoMonitorDB() {
connectionDB = new connectdb() ;
}
/**
*
* 释放类中的数据库链接
*
* @return 释放成功true ,异常false
* */ public boolean ReleaseConn() {
try{
if(ps!=null)
ps.close() ;
if(conn!=null)
conn.close() ;
}
catch(Exception e){
System.out.println(e.toString() );
return false;
}
return true;
} /**
*
* @return 的ResultSet集合
* */
public ResultSet GetRealRiverDataAndLevel() {
conn = this.connectionDB.getConnection();
ResultSet result = null;
String sql;
try {
sql = "SELECT VNO FROM ST_WLVALUE_R,ST_WLSN";
ps = conn.prepareStatement(sql);
result = ps.executeQuery();
} catch (Exception e) {
System.out.println(e.toString());
return null;
}
return result;
}
/**
* 使用update语句操作数据库
*
* @param vno 流域编号
* @param bj 要修改的新的报警级别
* @return 成功true,失败false
* * */
public boolean ChangeValleyAlarmInfo(String vno) {
Connection conn = this.connectionDB.getConnection();
PreparedStatement ps = null;
String sql;
try {
sql = "update TBL_VALLEYINFO where VNO = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, vno);
ps.execute();
} catch (Exception e) {
System.out.println(e.toString());
return false;
} finally {
try {
ps.close();
conn.close();
} catch (Exception e1) {
System.out.println(e1.toString());
}
}
return true;
}
}
=================================
public class AutoMonitor implements ActionListener {
AutoMonitorDB am= new AutoMonitorDB() ;
//使用AutoMonitorDB类的GetRealRiverDataAndLevel()函数,即使用ResultSet集合
public void RainMonitor(){
ResultSet rs = am.GetRealRiverDataAndLevel() ;
try{
while(rs.next() ){
String valleyNo=rs.getString("VNO");
//使用AutoMonitorDB类的ChangeValleyAlarmInfo函数
boolean b=am.ChangeValleyAlarmInfo("aaa");
}
rs.close() ; } catch (Exception e1) {
System.out.println(e1.toString());
} finally {
am.ReleaseConn();
}
}
解决方案 »
- java Applet 小程序 的图片无法在网页上显示
- 我的在线实时编程构想
- 难题,关于1.5中的泛型的设想
- 谁有JDK下载地址,网上搜索搞不到
- 关于eclipse的问题
- 问一个简单的例子,在java 中怎么样排版,比如在下面的程序中放一个label和textField后就换行,怎么做
- 做了个小应用程序用visulage ,但后来在可视界面上打开却看不见所有控件了
- (希望大家不要见笑)为什么在JBuilder中不能调整Button的大小????
- 关于SUBSTRING 问题
- 求助:"错误:com/borland/jbcl/layout/XYLayout"应如何解决?
- udp丢包问题
- 如何解决Jbuilder9的光标问题
而你现在遇到的问题是有ResultSet结果集返回,所以连接不能及时关闭。所以我建议不要直接返回ResultSet结果集,这也是一个好习惯问题,所有数据库操作层使用的东西最好不要在业务层直接使用,我们可以把ResultSet结果集里的数据封装成数据对象,把数据对象存放在集合里,返回集合供业务层使用。我们要求在各个操作层之间传递的是对象,这也符合我们面向对象编程的思想。
连接的打开和关闭不要对外提供