用完的ResultSet、Statement怎么都不关闭?数据库连接Connection怎么也不关闭?数据库的SQLException就这么抛出去了?
解决方案 »
- java小程序
- 如何用弹出窗口控制一个进程?
- 想请问大家,为什么我的这个conn.java在执行javac conn.java时出错,说什么“SQL”不存在什么的。。。。
- 运行Java程序时, 运行中终端出现Killed字样, 然后程序就终止了.
- 现在里面还有没有 高手 了!有就快来吧!看看怎么办!帮个忙啊!!!急啊!
- 面向对象问题
- .net 有Crystal reports可以用,java 有吗?
- 急死了上火啊,自己租的两居现在还空一间,求志同道合的朋友合租
- 请问如何访问多层的 static 子类?
- java中能不能读取注册表中的数据??
- 关于Jni的方法声明
- 哈哈,又可以回到我的java的怀抱了
是啊,怎么对例外一点都不处理啊
try一下,然后把例外打印出来都可以啦
关闭resuldset
关闭statement
关闭connection
否则就要等死啊
数据库会死的
xiaohaiz(老土进城,两眼通红)老土哥,那你给一个比较全面的程序吧,关注!
不过关于数据库的使用倒是有几点确实应该是多加注意的.
(1) 第一是"事务(Transaction)"的概念,是一定要掌握的.事务这个东西其实是一个非常基础和重要的概念,当然不仅仅存在于数据库领域.围绕事务展开的业务可以说是多如过江之鲫.
(2) 第二一定要理解到数据库连接(java.sql.Connection)的释放问题,数据库是一个可以共享的东东,如果你在不使用的情况下长占某种资源可能会导致别人的无法使用.这是一件需要避免的事情.
(3) 第三需要知道数据库连接对象是重量级的对象,创建的开销比普通对象大得多,所以如果是性能关键的任务,应该考虑对象池技术来处理(也可以理解大家所言之"数据库连接池")俺见到过一种做法,可以和共享一下.其实对于JDBC连接的管理最基本的就是两种功能:
(1) 申请连接;
(2) 释放连接;
所以可以定义如下的接口:
<<
public interface ConnectionManager {
public Connection getConnection() throws Exception;
public void returnConnection(Connection conn);
}
>>
具体的数据库连接管理可以在其实现类来处理.可以使用数据库连接池技术,也可以不使用.:)比如:
下面只是一个示例实现而已.BTW,驱动的注册放在静态初始化的地方比较合适,在加载的时候就会注册JDBC驱动,如果发生异常会抛出RuntimeException.
<<
final class DefaultConnectionManager implements ConnectionManager {
private static final String DRIVER = "xxx";
private static final String URL = "xxx";
private static final String USER = "xxx";
private static final String PASS = "xxx";
static {
registerDriver();
}
private static void registerDriver() {
try {Class.forName(DRIVER);}
catch(ClassNotFoundException ex) {throw new RuntimeException(ex);}
} DefaultConnectionManager() {} public Connection getConnectionManager() throws SQLException {
return DriverManager.getConnection(URL, USER, PASS);
} public void returnConnection(Connection conn) {
if(conn==null) return;
try {conn.close();}
catch(SQLException ex) {}
}
}
>>
另外,为了方便使用ConnectionManager,通常情况下可以使用工厂类来实现,由工厂类来控制ConnectionManager的实例.
<<
public final class ConnectionManagerFactory {
private static final ConnectionManagerFactory INSTANCE = new ConnectionManagerFactory();
private ConnectionManagerFactory() {}
public static ConnectionManagerFactory getInstance() {return INSTANCE;} private final ConnectionManager defaultCM = new DefaultConnectionManager();
public ConnectionManager getConnectionManager() {
return defaultCM;
}
}
>>在这样的结构下,其实绝大部分SQL任务都是一样的结构,比如:
<<
ConnectionManager cm = ConnectionManagerFactory.getInstance().getConnectionManager();
Connection conn = null;
try {
conn = cm.getConnection();
} catch(SQLException ex) {
// 处理异常并且中断流程
}try {
// ... DO SQL TASK HERE
} catch(SQLException ex) {
// ... HANDLE SQLException
} finally {
cm.returnConnection(conn);
}
>>
使用这样的方式来保证申请的连接都一定被释放掉.
如果是手工执行事务,那么可以修改如下:
<<
try {
conn.setAutoCommit(false); // Begin transaction.
// ... DO YOUR SQL TASK conn.commit(); // commit transaction.
} catch(SQLException ex) {
try {conn.rollback();} catch(SQLException e) {} // rollback transaction.
// ... HANDLE SQL Exception
} finally {
cm.returnConnection(conn);
}
>>
不管做什么SQL任务,架子总是和上面的例子相差不远.所以俺见过使用TEMPLATE METHOD来建立SQLTask的方式,把这些步骤都在模板方法中定义死.
差不多先这些吧.
:)
registerDriver();
}我理解不了啊。
if(conn==null) return;
try {conn.close();}
catch(SQLException ex) {}
这个方法的功能是保持连接呢,还是掐掉连接呢?
是啊,怎么对例外一点都不处理啊
try一下,然后把例外打印出来都可以啦
关闭resuldset
关闭statement
关闭connection
否则就要等死啊
数据库会死的
----------------
这位大哥说的怎么都没有做呢?不用吗?
这只是一个示例的实现而已.这里实际上是断掉了连接.当然也可以委派数据库连接池的方法来实现returnConnection(Connection)方法.
import java.io.*;
import java.sql.*;
import java.util.*;
public class DbConnection { Connection conn = null;
Statement stmt = null;
ResultSet rset = null; public DbConnection() { }
/****************************************************************************
* 方法名称:openConnection
* 参数:无
* 返回值类型:boolean
* 说明:打开数据库Connection的方法,为了打开Connection,读取位于类路径下的
* db.properties
*/
public boolean openConnection(){
//------------------------------------------------------------------------
// STEP 1. 载入Properties文件
//------------------------------------------------------------------------
Properties prop = new Properties();
try {
InputStream is = getClass().getResourceAsStream("/db.properties");
prop.load(is);
if(is != null) is.close();
} catch (IOException e) {
System.out.println("[DbConnection]打开文件时出现错误");
}
//------------------------------------------------------------------------
// STEP 2. 从Properties文件中读取property
//------------------------------------------------------------------------
String jdbc = prop.getProperty("driver");
String url = prop.getProperty("url");
String user = prop.getProperty("user");
String password = prop.getProperty("password");
//------------------------------------------------------------------------
// STEP 3. 将输入的Property输出到Debugging
//------------------------------------------------------------------------
System.out.println("jdbc=["+jdbc+"]");
System.out.println("url=["+url+"]");
System.out.println("user=["+user+"]");
System.out.println("password=["+password+"]");
//------------------------------------------------------------------------
// STEP 4. 加载JDBC驱动
//------------------------------------------------------------------------
try{
Class.forName(jdbc).newInstance();
}catch(Exception e){
System.out.println("加载JDBC驱动程序出错"+e.getMessage());
return false;
}
//------------------------------------------------------------------------
// STEP 5. 打开数据库驱动
//------------------------------------------------------------------------
try{
this.conn = DriverManager.getConnection(url,user,password);
} catch(SQLException e) {
System.out.println("生成Connection过程中出现错误"+e.getMessage());
}
return true;
}
/***************************************************************************
* 方法名称:executeQuery
* 参数:query(sql查询语句)
* 返回值类型:java.sql.ResultSet
* 说明:查询方法
***************************************************************************/
public ResultSet myexecuteQuery(String query) throws SQLException {
this.stmt = conn.createStatement();
this.rset = stmt.executeQuery(query);
return rset;
}
/***************************************************************************
* 方法名称:executeUpdate
* 参数:query
* 返回值类型:void
* 说明:修改数据库的方法
***************************************************************************/
public void executeUpdate(String query) throws SQLException {
this.stmt = conn.createStatement();
stmt.executeUpdate(query);
if(stmt != null) stmt.close();
}
/***************************************************************************
* 方法名称:close
* 参数:无
* 返回值类型:void
* 说明:关闭相关的资源
***************************************************************************/
public void close() throws SQLException {
if(conn != null) conn.close();
if(stmt != null) stmt.close();
if(rset != null) rset.close();
}
/***************************************************************************
* 方法名称:finalize
* 参数:无
* 返回值类型:void
* 说明:从服务器回收资源
***************************************************************************/
public void finalize() throws SQLException {
this.finalize();
} }
this.finalize();
} }
从服务器回收资源这个方法不用实现吗?
----------------------
已安装了microsoft 驱动程序jdk1.4; win2000 server; MS sql2000;*/import java.sql.*;
class sql
{
public static void main(String[] agrs)
{
Connection cn=null;
Statement stmt=null;
String sql=null; try
{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
}
catch(ClassNotFoundException ex)
{
System.out.println("Not find the Driver!");
}try
{
String urls="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=webroot";//webroot 库名.TALBE 是表名;
String user="sa";
String password="password";
cn= DriverManager.getConnection(urls,user,password);//stmt=cn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
stmt=cn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);sql="select top 10 * from TABLE1";
ResultSet rs= stmt.executeQuery(sql);
while(rs.next())
{
System.out.println(rs.getString(2)+" "+rs.getString(3)); } rs.first();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" 1 "+rs.getString(3)); rs.last();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" 2 "+rs.getString(3)); rs.previous();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" 3 "+rs.getString(3)); rs.next();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" 4 "+rs.getString(3)); rs.absolute(2);
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" 5 "+rs.getString(3));
/*
rs.afterLast();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" "+rs.getString(3));
System.out.print(rs.isAfterLast()); rs.beforeFirst();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" "+rs.getString(3));
*/ String sql1="update TABLE1 set 题目=? where id=? ";
PreparedStatement stmt1 = cn.prepareStatement(sql1);
String stat = new String("盛夏话足部保健");
String stat1 = UnicodeToGB(stat);//解决中文问题
stmt1.setString(1,stat1);
stmt1.setInt(2,3423);
stmt1.executeUpdate();
cn.commit(); //System.out.println(stat1);
//System.exit(0); //cn.setAutoCommit(false);
stmt.addBatch("update TABLE1 set 题目='盛夏话足部保健1' where id='3407'");
stmt.addBatch("update TABLE1 set 题目='夏季预防中暑膳食1' where id='3408'");
stmt.addBatch("INSERT INTO TABLE1 VALUES('11','12','13','','')");
stmt.addBatch("INSERT INTO TABLE1 VALUES('12','12','13','','')");
stmt.addBatch("INSERT INTO TABLE1 VALUES('13','12','13','','')");
stmt.addBatch("INSERT INTO TABLE1 VALUES('14','12','13','','')");
stmt.addBatch("INSERT INTO TABLE1 VALUES('15','12','13','','')");
stmt.addBatch("INSERT INTO TABLE1 VALUES('16','12','13','','')");
stmt.addBatch("INSERT INTO TABLE1 VALUES('17','12','13','','')");
stmt.addBatch("INSERT INTO TABLE1 VALUES('18','12','13','','')");
int [] updateCounts=stmt.executeBatch();
cn.commit();
stmt.close();
cn.close();
}
catch(SQLException e)
{
System.out.println("The SQLException error!");
}}
/*
*/public static String UnicodeToGB(String strIn){
byte[] b;
String strOut = null;
if(strIn == null || (strIn.trim()).equals(""))
return strIn;
try{
b = strIn.getBytes("GBK");
strOut = new String(b,"ISO8859_1");
}
catch(Exception e){
System.out.println("unicodeToGB exception : " + e.getMessage() + "\n");
}
return strOut;
}
/*
*/
}