在三层架构DAL层多次开启和关闭Connection对象好吗?

问题描述

在DAL层中,每次执行查询以后都会关闭prepareStatement对象和Connection对象,请问这样做合适吗?我的SQLHelper写成是静态的了,DAL层每个查询都从SQLHelper中获取一个PrepareStatement对象,然后每次执行完对应的查询后都会关闭pstmt对象和connection对象,然而这只是在DAL层,在BLL层中一般会调用1-5个DAL的方法,也就是说,一轮业务逻辑下来,Connection对象会开启和关闭1-5次,这样对性能有影响吗?有没有高手帮我改一下,不胜感激!主要是性能方面的问题,其他的没什么!!!就怕性能不足!!!但是又不想让BLL层接触数据库的东西,达到分层效果。[color=#FF0000][/color]下面是我的SQLHelper代码:importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;/***数据库通用逻辑组件**/publicclassSQLHelper{/**声明数据库三大连接对象*/publicstaticConnectionconn=null;//数据库连接对象publicstaticStatementstmt=null;//数据库命令执行对象publicstaticPreparedStatementpStmt=null;//数据库预编译命令执行对象publicstaticResultSetrs=null;//数据库结果集对象/**不允许实例化该类*/privateSQLHelper(){}/**连接数据库语句*///设置数据库连接驱动,默认使用JDBC4进行连接privatestaticStringdbDrive="com.microsoft.sqlserver.jdbc.SQLServerDriver";//数据库连接地址以及连接的数据库名privatestaticStringdbLocate="localhost";privatestaticStringdbName="sq_a1076";privatestaticStringdbPort="1433";privatestaticStringdbURL="jdbc:sqlserver://"+dbLocate+":"+dbPort+";DatabaseName="+dbName+"";//数据库帐号和密码privatestaticStringdbUser="";//忽略这个吧,我删掉了privatestaticStringdbPwd="";//============================================================//获取各种连接对象,用于内部使用//============================================================/**获取Connection连接对象*/privatestaticConnectiongetConnection(){Connectionconn=null;try{Class.forName(dbDrive);conn=DriverManager.getConnection(dbURL,dbUser,dbPwd);}catch(Exceptione){e.printStackTrace();}//判断是否成功生成conn连接对象if(conn==null){System.err.println("警告:数据库连接失败!");}returnconn;}//method/***获取Statement对象**@return返回一个指针可滚动、可更新的SQL语句执行对象*/publicstaticStatementgetStatement(){conn=getConnection();if(conn==null){returnnull;}try{returnconn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);}catch(Exceptione){//TO-DO是否需要关闭Connection?e.printStackTrace();returnnull;}}/***获取PrepareStatement对象**@paramsql特定的带'?'的SQL执行语句*示例:Stringsql="select*fromgoodswheregoodsName=?andgoodsType=?";**@return返回一个预编译指针可滚动、可更新SQL语句执行对象*/publicstaticPreparedStatementgetPreparedStatement(Stringsql){conn=getConnection();if(conn==null){returnnull;}try{returnconn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);//使用第一个方法}catch(Exceptione){e.printStackTrace();returnnull;}}/**关闭数据库连接*/publicstaticvoidcloseConnection()throwsException{//关闭连接对象try{if(conn!=null){conn.close();}}catch(Exceptione){throwe;}}//method}//class

下面是DAL层中其中一个SQL原子执行语句:publicUserfindUserByUserName(StringuserName)throwsException{Useruser=null;//一个可以指向用户对象的变量Stringsql="selectuserName,userTypeId,personIdfrom[User]whereuserName=?";pstmt=SQLHelper.getPreparedStatement(sql);pstmt.setString(1,userName);ResultSetrs=pstmt.executeQuery();while(rs.next()){user=newUser();user.setUserName(rs.getString(1));user.setUserTypeId(rs.getInt(2));user.setPersonId(rs.getInt(3));}pstmt.close();SQLHelper.closeConnection();returnuser;}

感激各位大神的帮助

解决方案

本帖最后由 u011688498 于 2015-01-04 17:50:16 编辑
解决方案二:
主要是性能方面的问题,其他的没什么!!!就怕性能不足!!!但是又不想让BLL层接触数据库的东西,达到分层效果。
解决方案三:
不要这么做,我在CSDN强调过不下10次了,不要把Connection等JDBC对象弄成静态的,这会产生非常严重的问题。JDBCconnection讨论Connection能设置成静态的吗
解决方案四:
引用2楼bao110908的回复:

不要这么做,我在CSDN强调过不下10次了,不要把Connection等JDBC对象弄成静态的,这会产生非常严重的问题。JDBCconnection讨论Connection能设置成静态的吗

还是不是很懂,连接泄漏这方面的问题,那应该怎么做?在三层架构里面,我不想DAL和BAL耦合太大,求支招!
解决方案五:
一个Connection的开启和关闭一般用于代表一个事务,对于Connection,设置为一个成员变量的时候,当出现多线程调用这个Connection成员变量,如果不处理同步问题,则可能你在线程1中调用这个Connection成员变量的时候,发现这个是一个空指针,于是就新建了一个Connection,但是如果同时线程2也在跑,也同时发现这个是一个空指针,同样新建了一个Connection(多线程就是这样的,因为你没有处理异步问题),这样你的Connection关闭就很有问题了,并且可能会很快占用完数据库连接(new了太多Connection)!所以最佳的做法就是,每次操作数据库之前都独立获取一个Connection对象,并且操作完之后对其进行关闭!也就很好地保证了事务的一致性以及代码的同步操作。
解决方案六:
引用4楼u010097361的回复:

一个Connection的开启和关闭一般用于代表一个事务,对于Connection,设置为一个成员变量的时候,当出现多线程调用这个Connection成员变量,如果不处理同步问题,则可能你在线程1中调用这个Connection成员变量的时候,发现这个是一个空指针,于是就新建了一个Connection,但是如果同时线程2也在跑,也同时发现这个是一个空指针,同样新建了一个Connection(多线程就是这样的,因为你没有处理异步问题),这样你的Connection关闭就很有问题了,并且可能会很快占用完数据库连接(new了太多Connection)!所以最佳的做法就是,每次操作数据库之前都独立获取一个Connection对象,并且操作完之后对其进行关闭!也就很好地保证了事务的一致性以及代码的同步操作。

可以把每次单独获取Connection和prepareStatement的代码写到一起提供复用。多次开启和关闭独立的Connection是没有问题的,一般都是这么做的,如果想更加优化,一般推荐使用连接池!
解决方案七:
你的代码都不是性能问题了,是肯定会出多线程问题。除非你能保证,同一时间SqlHelper只有一个线程被调用。A线程调用了getPreparedStatement,B线程也调用了getPreparedStatement。。。这时候A先调用结束然后调用了closeConnection关掉了Connection,那么等B线程调用结束后如何关掉B线程用的Connection?这个Connection就泄漏了,迟早会达到数据库连接上限。所以建议是除非你能保证,同一时间只有一个线程调用SqlHelper上的方法,不然别这么做。你可以使用DataSource数据源,这都说烂的事了。比如C3P0之类的,你只需要问他拿Connection使用完调用close就可以了。性能由C3P0来保证。当然数据源实现有好多种了。
解决方案八:
引用5楼u010097361的回复:

Quote: 引用4楼u010097361的回复:
一个Connection的开启和关闭一般用于代表一个事务,对于Connection,设置为一个成员变量的时候,当出现多线程调用这个Connection成员变量,如果不处理同步问题,则可能你在线程1中调用这个Connection成员变量的时候,发现这个是一个空指针,于是就新建了一个Connection,但是如果同时线程2也在跑,也同时发现这个是一个空指针,同样新建了一个Connection(多线程就是这样的,因为你没有处理异步问题),这样你的Connection关闭就很有问题了,并且可能会很快占用完数据库连接(new了太多Connection)!所以最佳的做法就是,每次操作数据库之前都独立获取一个Connection对象,并且操作完之后对其进行关闭!也就很好地保证了事务的一致性以及代码的同步操作。

可以把每次单独获取Connection和prepareStatement的代码写到一起提供复用。多次开启和关闭独立的Connection是没有问题的,一般都是这么做的,如果想更加优化,一般推荐使用连接池!

可以给各小例子吗?谢谢,我不知道怎么复用,是静态还是动态的?!
解决方案九:
引用6楼etnet的回复:

你的代码都不是性能问题了,是肯定会出多线程问题。除非你能保证,同一时间SqlHelper只有一个线程被调用。A线程调用了getPreparedStatement,B线程也调用了getPreparedStatement。。。这时候A先调用结束然后调用了closeConnection关掉了Connection,那么等B线程调用结束后如何关掉B线程用的Connection?这个Connection就泄漏了,迟早会达到数据库连接上限。所以建议是除非你能保证,同一时间只有一个线程调用SqlHelper上的方法,不然别这么做。你可以使用DataSource数据源,这都说烂的事了。比如C3P0之类的,你只需要问他拿Connection使用完调用close就可以了。性能由C3P0来保证。当然数据源实现有好多种了。

好,后面我把数据库SQLHelper写成动态的了,不知道这样行不行,我也在多线程环境下调用过,在SQLManager看连接,在程序结束后就没有连接了,应该是没问题了,以后再用C3P0,谢谢

时间: 2024-07-30 15:31:05

在三层架构DAL层多次开启和关闭Connection对象好吗?的相关文章

想请教诸位一个关于三层架构DAL的问题

问题描述 我最近在做毕业设计,是个管理系统,然后在DAL层有一个提供给普通用户修改个人信息的功能,然后问题就在这里,我该如何只读取这个用户的信息,也就是select*fromusertabewhere后面的限定条件怎么写,上层的数据源选用的是OBJECTDATASOURE 解决方案 解决方案二:whereid=123UI传id解决方案三:你应该学习的是sql,而不是什么"三层架构".学习sql用时半年,而三层架构(对于已经有了足够基础知识和经验的人来说)顶多只需要1周.如果一个hr不懂

asp.net三层架构 UI层引用问题

问题描述 asp.net改成三层架构时在UI层引用了BLL,也加了UsingBLL,写代码的时候没有任何问题,但是编译时说缺少引用....求大神指教,,马上就毕业答辩了 解决方案 解决方案二:看一下你的BLL版本.看看是否本web的.net版本要高.解决方案三:删掉重新添加引用

三层架构各层间的访问过程

1.传入值,将值进行类型转换(为整型). 2.创建bll层的对象,通过对象访问bll层的方法调用bll层. 3.bll层方法中取得数据访问层的实例,实例化idal层的接口对象,这个对象是由工厂层创建的,然后返回idal层传入值所查找的内容的方法. 4.数据工厂通过web.config配置文件中给定的webdal字串访问sql层,返回一个完整的调用sql层的路径给 bll层. 5.到此要调用sql层,sql层完成赋值model层的对象值为空,给定一个参数,调用sql层的sqlhelper的exec

ASP.NET 三层架构使用IDAL 接口层有什么作用,有和妙用,使用业务逻辑层BLL直接调用数据层DAL不可以嘛。

问题描述 我们通常是UIweb层调用BLL层,BLL层调用DAL达到数据的交换.但是看到大多数项目是有个IDAL接口,只是声明方法没有任何的代码实现部分,代码实现部分都放在了DAL层,然后BLL层去调用IDAL接口层的方法实现,并没有去调用DAL层,UI层调用BLL层,这里的接口层有和作用,请教各位帮忙解答,不胜感激! 解决方案 解决方案二:IDAL是DAL层的类要实现的接口.DAL层的各类需要完成对数据库的访问,但是不同的数据库需要使用不同的DAL对象,这样对于BLL层来说无法实现数据库无关性

三层架构 ent-求一个简单3层架构,.ent

问题描述 求一个简单3层架构,.ent 想学3层架构,求一个简单3层架构模版,能对一张表进行修改! 247056534@qq.com 解决方案 你用微软的Mvc框架就行了 解决方案二: 上网搜找一个自己下载 解决方案三: 是.net吗?是的话就如楼上所说的直接使用微软的MVC框架,结合EF,连连接数据库的类都可以省掉不写了. 你也可以自己添加三个基础类库 Model DAL BLL Model的作用数据访问层,实体类什么的可以放在这一层. DAL层为数据访问层,用于存放链接数据库的类或者做增删改

service层设计-关于三层架构中service dao 和实体的设计实现的疑问

问题描述 关于三层架构中service dao 和实体的设计实现的疑问 在 java 的三层架构中一直有几个问题困扰着我一直不得解决,特在此请教各位大神,还请各位大大,不腻赐教 场景: 加入现在是一个教务系统里面包含数据库表 课程表,学生表,学生购买的课程表 课程表 学生表 学生购买的课程表 这个时候如何设计实体类呢 学生实体1 public class student { private Integer id; private String name; private String birth

三层架构中,层与层之间返回消息,怎么实现比较好?

问题描述 三层架构中,层与层之间返回消息,怎么实现比较好?举个例子:比如UI层调用业务逻辑层,业务逻辑层会告诉UI层:操作成功.或者用户没有该操作权限.内部报错啊等等之类的消息.请教一下各位有经验的朋友们,这种层与层之间的信息通信怎么设计和实现比较好.谢谢! 解决方案 解决方案二:执行结果之类的直接用INT就可以再标准点就用ENUM但是要是返回一张表最好自定义类来实现比较好解决方案三:或者用户没有该操作权限.内部报错啊===这些可以添加TRY..CATCH捕获到异常直接在BLL抛出WEB写个基类

三层架构(一)——什么是三层架构?

 一.什么是三层架构?   1.概念   三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:表现层(UI).业务逻辑层(BLL).数据访问层(DAL).区分层次的目的即为了"高内聚,低耦合"的思想.    分层(tier) 概念 表现层(UI) 通俗讲就是展现给用户的界面,用于显示数据和接受用户输入的数据:即用户在使用一个系统的时候他的所见所得. 业务逻辑层(BLL) 针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理.是表

企业级应用框架:三层架构之解耦

前言 前段时间朋友拿了个网站给我,让我帮忙添加几个小功能,我爽快的答应了,但是当我打开源码,我瞬间就奔溃了,整个项目连最基本的三层框架也没有搭建,仅仅是封装了一个sqlhelp作为数据库的操作接口,项目中的SQL查询语句无处不在,业务逻辑紧紧耦合在UI逻辑中,看到这样的代码,坦白来说,我什么兴致都没有了,但是碍着人情,我硬着头皮,把基本功能的完成交差,通过这件事情,我对软件分层进行了深入的思考. 三层架构 说到三层架构,大伙都很熟悉,我也不再多啰嗦了,我们直接快速搭建一个. 项目的引用关系是:S