首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

一个常见的JDBC封装导致的有关问题

2012-12-22 
一个常见的JDBC封装导致的问题大家看一个数据库封装类操作一次没问题,操作两次就报错com.mysql.jdbc.excep

一个常见的JDBC封装导致的问题
大家看一个数据库封装类
操作一次没问题,操作两次就报错
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.


Debug调试,发现connection不能真正关掉,使用connection完后,调用close()方法,下次getConnection()时候
instance不为null



public class ConnectionUtil {private final static String  url="jdbc:mysql://localhost:3306/qq?useUnicode=true&characterEncoding=UTF-8";private final static String  username="root";private final static String  password="root";private  static Connection   instance=null;private ConnectionUtil(){if(instance==null){try {Class.forName("org.gjt.mm.mysql.Driver");instance=DriverManager.getConnection(url, username, password);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}}}public static Connection getConnection(){if(instance==null){new ConnectionUtil();}return instance;}public static void close(Connection con,PreparedStatement ps,ResultSet rs){if(con!=null){try {con.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{con=null;}}if(ps!=null){try {ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{ps=null;}}if(rs!=null){try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{rs=null;}}}public static void close(Connection con,PreparedStatement ps){if(con!=null){try {con.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{con=null;}}if(ps!=null){try {ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{ps=null;}}}public static void close(Connection con){if(con!=null){try {con.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{con=null;}}}}



结贴了。。。。有其他结贴方式吗?//sb=null;
sb.append(" -- added twice");
}
}

class Demo
{
String s = "initial string value";
}</pre>
<p>?</p>
<p>结果:</p>
<p>?</p>
<pre name="code" name="code">public class ConnectionUtil {private static Connection instance=null;}

这儿:instance是ConnectionUtil 类的静态变量。

public static void close(Connection con){if(con!=null){try {con.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{con=null;}}}}

这儿:close()方法中,置空的con=null,是方法参数。ConnectionUtil.instance 并没有受到影响。


正解,Java的参数都是值传递,非引用传递public class ConnectionUtil {private final static String url="jdbc:mysql://localhost:3306/qq?useUnicode=true&characterEncoding=UTF-8";private final static String username="root";private final static String password="root";private static Connection instance=null;private ConnectionUtil(){if(instance==null){try {Class.forName("org.gjt.mm.mysql.Driver");instance=DriverManager.getConnection(url, username, password);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}}}public static Connection getConnection(){if(instance==null){new ConnectionUtil();}return instance;}public static void close(Connection con,PreparedStatement ps,ResultSet rs){if(con!=null){try {con.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{con=null;}}if(ps!=null){try {ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{ps=null;}}if(rs!=null){try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{rs=null;}}}public static void close(Connection con,PreparedStatement ps){if(con!=null){try {con.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{con=null;}}if(ps!=null){try {ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{ps=null;}}}public static void close(Connection con){if(con!=null){try {con.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{con=null;}}}}
一个connetion.close掉了就不可以用了,你这里if(instance==null),第二次用的时候install不为null,是一个connection对象,但他的状态时closed,所以下面的if语句块,不会执行。今天没认真看代码,罪过,罪过...

结贴了。。。。有其他结贴方式吗?
53 楼 wingok 2011-05-16   非常常用的功能,建议先找找有没通用的开源实现
http://commons.apache.org/dbutils/ 54 楼 tom&jerry 2011-05-17   悲剧了 写道gaosheng08 写道close()中还要加一句instance = null;

调用的时候传进来的就是instance ,这个connection是通过这个类的getConnection()得到的

instance 和 con 是一个对象的两个引用,假设对象为A, B和C为到A的引用,C=null只是切断了C到A的联系,B与A的联系依然存在。 55 楼 Technoboy 2011-05-17   ecokozhangtao 写道你这个单例写的,有可能产生死锁
连同步都没有,还能出来死锁.... 56 楼 Technoboy 2011-05-17   悲剧了 写道kakaluyi 写道悲剧了 写道gaosheng08 写道close()中还要加一句instance = null;

调用的时候传进来的就是instance ,这个connection是通过这个类的getConnection()得到的
lz你难道不知道java通过close方法传递进去的instance只是个引用吗,真正的instance是不会置为null的??





哥们我明白了

con,intance 两个引用指向同一个栈,con为空但intance不为空,开始是以为传进去的是intance

Connection con=instance
con=null
但intance不为空

哎,悲剧,估计又要挨骂了


+1
new ConnectionUtil 匿名对象 57 楼 jekyll 2011-05-17   没发现搂主 instance=null 的语句 58 楼 sebatinsky 2011-05-17   这个单列写的。。。。。。。我看着似乎不敢发言了。 59 楼 fatesymphony 2011-05-18   kakaluyi 写道算了解释一下,发现楼主还是云里雾里
public void static main(String args[])
{
int i=3;
changevalue(i);
System.out.println(i);
//你以为i现在是2吧,错了,i还是3!不好意思楼主,你理解错误了。这个是很容易搞错的概念
}
public void changevalue(int i)
{
i=2;
}

朋友很热心,但是你却没有明白Java的基本数据类型与引用类型的区别。
你这样会对人造成误导的,不是楼主搞错了而是你搞错了。


楼主的代码写得确实很混乱。

热点排行