`
悲剧了
  • 浏览: 144328 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

一个常见的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 block
				e.printStackTrace();
			}finally{
				con=null;
			}
		}
		if(ps!=null){
			try {
				ps.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				ps=null;
			}
		}
		if(rs!=null){
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.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 block
				e.printStackTrace();
			}finally{
				con=null;
			}
		}
		if(ps!=null){
			try {
				ps.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				ps=null;
			}
		}
		
		
	}
	
	public static void close(Connection con){
		if(con!=null){
			try {
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				con=null;
			}
		}
	}

}



结贴了。。。。有其他结贴方式吗?
分享到:
评论
39 楼 悲剧了 2011-05-16  
shanga 写道
在23行代码中,楼主做了创造主,创造了无数的逃逸对象,但他只握住了女娲,是何等的专一,使我想起了中国警察的故事。这些逃逸对象做的事(楼主说得instance存在),但是实际上抛出connection close错误,因为楼主只记住女娲,其他人一个也没放眼里。



哥们,我语文不太好,真没看懂
38 楼 shanga 2011-05-16  
在23行代码中,楼主做了创造主,创造了无数的逃逸对象,但他只握住了女娲,是何等的专一,使我想起了中国警察的故事。这些逃逸对象做的事(楼主说得instance存在),但是实际上抛出connection close错误,因为楼主只记住女娲,其他人一个也没放眼里。
37 楼 悲剧了 2011-05-16  
uin57 写道
楼主的基础太差了,封装的错误太多 也不好一一指出...建议参考hibernate的sessionFactory


一个错误,在发帖到自己发现错误,回复的人十几个,看出来的就一两个

我知道在我发现错误的时候,肯定一大号人说你基础太差什么的,这就是网络
36 楼 悲剧了 2011-05-16  
mtnt2008 写道

呵呵,可能楼主这个错误比较的典型

1.为什么要用单例,而且单例写的有问题

2.如果没有实现连接池的话,应该分为2个类,一个类是getConnection(),close(),一个类是一些常用的操作



用单例是由于数据库操作特别少,自己就想用单例写着玩,就过就出来这个悲剧
35 楼 mtnt2008 2011-05-16  

呵呵,可能楼主这个错误比较的典型

1.为什么要用单例,而且单例写的有问题

2.如果没有实现连接池的话,应该分为2个类,一个类是getConnection(),close(),一个类是一些常用的操作
34 楼 uin57 2011-05-16  
楼主的基础太差了,封装的错误太多 也不好一一指出...建议参考hibernate的sessionFactory
33 楼 悲剧了 2011-05-16  
fangin 写道
非基本类型当形参的时候,操作传入的句柄和操作原有的句柄也没什么分别。反正实际操作的都是句柄指向的对象。

句柄置空操作算是比较特殊。只是把此句柄指向了null,对对象没什么影响。

其他情况下其实用起来是没什么差别的,也不能怪楼主吧



public class Test01 {

	public static void main(String args[]){
		int i=1;
		change(i);
		System.out.println(i);
		
		String str="aaa";
		change(str);
		System.out.println(str);
		
		Demo d=new Demo();
		change(d.s);
		System.out.println(d.s);
		
		
	}
	
	
	public static void change(int i){
		i=0;
	}
	public static void change(String str){
		str="bbb";
		
	}
}

class Demo{
	String s="demo";
}




结果如下
1
aaa
demo
32 楼 fangin 2011-05-16  
非基本类型当形参的时候,操作传入的句柄和操作原有的句柄也没什么分别。反正实际操作的都是句柄指向的对象。

句柄置空操作算是比较特殊。只是把此句柄指向了null,对对象没什么影响。

其他情况下其实用起来是没什么差别的,也不能怪楼主吧
31 楼 ericslegend 2011-05-16  
悲剧了 写道
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;
}



恩,明白了,谢了

都说楼主不理解,我看回答问题的没几个理解的(当然,我也很菜),传个String试试,传个其它引用对象试试,看看是不是改的原有对象,基本类型和引用类型是不一样的。
30 楼 悲剧了 2011-05-16  
laolinshi 写道
楼主JAVA基础不牢固,导致代码出现问题。



居然出现这问题,我自己都感觉很受打击
29 楼 laolinshi 2011-05-16  
楼主JAVA基础不牢固,导致代码出现问题。
28 楼 悲剧了 2011-05-16  
kakaluyi 写道
悲剧了 写道
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不为空

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


正解,
java也没有多少难点,恭喜你突破了一个


哈哈,谢了。
27 楼 kakaluyi 2011-05-16  
悲剧了 写道
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不为空

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


正解,
java也没有多少难点,恭喜你突破了一个
26 楼 tear11 2011-05-16  
close方法中的connection参数值传递
25 楼 悲剧了 2011-05-16  
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;
}



恩,明白了,谢了
24 楼 悲剧了 2011-05-16  
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不为空

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

23 楼 mavlarn 2011-05-16  

public static Connection getConnection(){
if(instance==null){
new ConnectionUtil();
}
return instance;

}

你这是什么意思?instance为空的时候,创建了Util对象,instance本来就是个静态类,你创建100个对象,里面的instance还是一个,还是空。
22 楼 gaosheng08 2011-05-16  
lz的java基础太不扎实了,先把基本功打好吧
21 楼 kakaluyi 2011-05-16  
算了解释一下,发现楼主还是云里雾里
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;
}
20 楼 gaosheng08 2011-05-16  
kakaluyi 写道
悲剧了 写道
gaosheng08 写道
close()中还要加一句instance = null;


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

lz你难道不知道java通过close方法传递进去的instance只是个引用吗,真正的instance是不会置为null的??


在类的定义中既然有了
private  static Connection   instance=null;  


close()方法中就不要传Connection进去了 

相关推荐

    原创的JDBC封装可支持各种数据库

    通过以上步骤,我们可以创建一个高度可配置、易于使用的JDBC封装库,支持多种数据库。在实际项目中,只需在配置文件中更改数据库相关参数,就能轻松切换到不同的数据库系统,极大地提高了代码的可维护性和可扩展性。...

    游戏服务器 数据库连接池 jdbc 简单封装

    在`nebula-jdbc-master`这个项目中,我们可以看到一个名为Nebula JDBC的实现,它可能就是对JDBC和数据库连接池的一个自定义封装。通过分析该项目的源码,我们可以学习如何自定义数据库连接池组件,如何优化JDBC的...

    jdbc-utils.rar_Utils_jdbc_jdbc封装

    这个文件很可能是封装好的一个基类,为具体的DAO(Data Access Object)提供通用的方法。可能包含以下功能: - 连接管理:自动获取和释放连接,通常会利用`PoolManager`来获取连接池中的连接。 - SQL执行:提供...

    jdbc封装的代码

    这个例子展示了如何使用封装后的JDBC工具类来执行一个查询操作,无需关心连接的创建与关闭,SQL参数的设置以及结果集的处理,大大提高了代码的可读性和易用性。这就是JDBC封装的主要目的和实现方式。

    自己写一个DAO 实现对jdbc dbcp封装 开源小组件

    本组件"自己写的一个DAO 实现对jdbc dbcp封装 开源小组件"是作者学习研究的成果,适用于小型项目,同时也是初学者了解和实践DAO设计模式、JDBC以及Apache DBCP连接池的好材料。 1. JDBC(Java Database ...

    有关于jdbc的基本封装

    JDBC是Java平台上的一个API,允许Java开发者与各种类型的数据库进行交互。它提供了一组接口和类,使得程序员可以编写数据库独立的代码,从而不必关心底层数据库的具体实现。 2. 基本CRUD操作: - 创建(Create)...

    JDBC 工具类JdbcUtils封装与测试应用(针对mysql)

    因此,JdbcUtils还可以进一步封装这些操作,例如添加一个执行SQL查询的方法: ```java // 执行SQL查询,返回结果集 public static ResultSet executeQuery(String sql) { Connection conn = getConnection(); ...

    SQL封装

    在IT行业中,SQL封装是Java开发中常见的一个实践,它能帮助我们更高效、更安全地操作数据库。本文将深入探讨“SQL封装”这一主题,尤其是对于初学者来说,掌握好这一技能对于提升JDBC(Java Database Connectivity)...

    Oracle jdbc 单例 工具类

    本示例中的"Oracle jdbc 单例 工具类"着重讨论了单例模式的应用,单例模式是一种设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在数据库连接管理中,使用单例模式可以避免频繁创建和关闭连接,提高...

    sharding-jdbc按月分表样例

    【标题】"sharding-jdbc按月分表样例"是一个关于使用Sharding-JDBC进行数据库分片的示例项目,旨在展示如何根据月份动态地将数据分散到不同的表中,以实现数据的水平扩展和负载均衡。Sharding-JDBC是阿里巴巴开源的...

    spring+jdbc整合

    "spring+jdbc整合"是一个常见的话题,尤其对于初学者而言,理解这两者的结合是提升开发效率的关键。下面我们将详细探讨Spring如何与JDBC进行整合,以及这种整合在实际项目中的应用。 首先,Spring框架通过其JDBC...

    JDBC知识点总结

    所有对数据库的操作都需要在一个有效的连接上进行。 3. **Statement**:用于执行 SQL 语句,并获取执行结果。 4. **ResultSet**:存储 SQL 查询结果的集合,通常被视为一张虚拟表。 #### 三、JDBC 的准备工作 1. *...

    SpringJDBC注解事务.zip

    Spring JDBC提供了一个JdbcTemplate类,它封装了常见的JDBC操作,如执行SQL查询、更新、调用存储过程等,减少了代码量和出错的可能性。此外,它还处理了诸如打开和关闭连接、结果集遍历等繁琐任务。 2. **注解驱动...

    JDBC数据库访问工具类 强大 精巧 高效

    总结来说,一个强大的JDBC数据库访问工具类是Java项目中必不可少的一部分,它通过封装和优化JDBC操作,降低了开发难度,提高了代码的可读性和维护性,同时提升了系统的运行效率。在设计和实现这样的工具类时,我们...

    jdbc分页查询源码

    在给定的源码中,可能包含了一个封装好的分页查询工具类,这个类通常会有以下方法: - `queryByPage(Connection conn, String sql, int pageNum, int pageSize)`:接收数据库连接、基础SQL语句以及分页参数,返回...

    Spring与JDBC整合

    - 在执行SQL时,需要提供一个Map或SqlParameterSource对象来传递参数值。 3. **事务管理**: - Spring提供了PlatformTransactionManager接口,如DataSourceTransactionManager,用于管理事务。 - 可以使用@...

    JDBC学习笔记

    - 将每条记录封装为一个Map,然后存储到List中。 #### 二十五、Java反射技术入门 - **概念**:反射是在运行时分析类和对象的能力。 - **应用**:使用反射技术根据结果集元数据动态创建Java对象,实现查询结果的...

    效率很高的java jdbc类

    2. **迭代器模式**:提供一个迭代器接口,使得遍历结果集更加灵活且节省内存,避免一次性加载所有数据导致内存溢出。 3. **类型转换**:根据需要自动将数据库中的值转换为适当的Java类型,例如将字符串转换为日期、...

    JSP+JDBC_假分页

    - **传递数据到JSP**:将ResultSet封装到一个集合对象(如ArrayList),然后通过请求转发或者模型视图适配器(MVC)模式传递到JSP页面。 - **JSP页面处理**:在JSP页面上,使用JavaScript或者jQuery等前端技术,...

    JDBC代码详解.docx

    JDBC的接口由数据库提供商实现,这意味着只要有一个支持JDBC的驱动程序,就可以使用相同的Java代码来访问不同的数据库。 #### JDBC入门案例详解 ##### 1.2.1 流程分析 假设我们的需求是查询数据库中的数据并在...

Global site tag (gtag.js) - Google Analytics