数据库访问层,将所有的方法写成静态这是提高效率的一个很好的方法,现在要讨论的问题就是SqlConnection 和SqlCommand这二个对像,是否要静态的问题。
静态写法:
private static string strConnection = ConfigurationManager.ConnectionStrings["conString"].ToString();
private static SqlConnection con = new SqlConnection();
private static SqlCommand cmd = new SqlCommand();当要用到con这个静态字段的时候,用con.State判断一下,连接是否在打开状态,如果打开就用,不打开就不用,cmd对像用个CLEAR()的方法,用的时候清除一下!在B/S的应用中,我指的是网站。这样做的法,当存在并发的时候,会不会严重影响情能呢,因为只有一个连接对像,和一个命今对像。动态方法:
当要用到这个对像的时候,才创造这个对像,用完后,在关掉它。比如下面这个方法
public static object ExecuteScalar(string connString, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms)
{
SqlCommand cmd = new SqlCommand(); using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = cmdText;
if (cmdParms != null)
{
foreach (SqlParameter parm in cmdParms)
cmd.Parameters.Add(parm);
}
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
conn.Close();
return val;
}
}还有是用using好呢,还是用TRY CATCH FINALLY请高手指教,谢谢!
静态写法:
private static string strConnection = ConfigurationManager.ConnectionStrings["conString"].ToString();
private static SqlConnection con = new SqlConnection();
private static SqlCommand cmd = new SqlCommand();当要用到con这个静态字段的时候,用con.State判断一下,连接是否在打开状态,如果打开就用,不打开就不用,cmd对像用个CLEAR()的方法,用的时候清除一下!在B/S的应用中,我指的是网站。这样做的法,当存在并发的时候,会不会严重影响情能呢,因为只有一个连接对像,和一个命今对像。动态方法:
当要用到这个对像的时候,才创造这个对像,用完后,在关掉它。比如下面这个方法
public static object ExecuteScalar(string connString, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms)
{
SqlCommand cmd = new SqlCommand(); using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = cmdText;
if (cmdParms != null)
{
foreach (SqlParameter parm in cmdParms)
cmd.Parameters.Add(parm);
}
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
conn.Close();
return val;
}
}还有是用using好呢,还是用TRY CATCH FINALLY请高手指教,谢谢!
2.using当用完了这对象之后会立即自动垃圾回收, 不用等到托管代码来回收.
try catch只是错误捕获,你必须手动Dispose()你所创建的对象才能达到using的效果.
//private static SqlConnection con = new SqlConnection();
//viena 观察力真狠
private static SqlCommand cmd = new SqlCommand();
===============================
写个多线程的测试一下你就晕了。private static string strConnection = ConfigurationManager.ConnectionStrings["conString"].ToString();
====================
用得着.ToString();吗?
Eddie005(♂) №.零零伍 (♂)
在B/S的应用中,这样做的话,当存在并发的时候,会严重影响情能,甚至导致大规模的请求不响应!!!PS:为什么CSDN就有这么一些找抽贴啊。(不针对问题,针对个人素质)
http://blog.csdn.net/chenjinghua/archive/2006/06/23/825005.aspx
本人只是一个小小的电工,只会修修电灯,换换日光灯,但对编程有强烈的爱好!所以提出来,大家研究研究!
很感动,四个红星的进我的贴子,研究,谢谢你们啊!!
1、想出用静态的人实在是太有创意了,PF!如果实在没把握SqlConnection的状态的话,用if(mySqlconn.State==close())mySqlconn.open();不行?
2、好像没有人会一直保持mySqlconn.open()吧?本人一般人(非高手)在正常情况下都用try{}catch{}finaly{mySqlconn.close()}
3、引用这样的一段代码来讨论,的确给大家的带来不少快乐:)
谢谢楼主!
但是俺知道这堆代码和想法都很垃圾其他的别人都说了
检查State????
呵呵~~~~
效率是相当的差
如果真的需要
应该监视StateChange事件在CSDN混了这么长时间
一般来说挑衅的题目内容往往很垃圾~~~~
我开始通恨这个人,你想你不是高手,你就不要写blog,你写出blog就是让大家见的,结果你写的都是错了,我学起来,也跟者错,那你还写什么写,简直是误导初学者.
以下是我写的数据层,时间关系,只写一些方法,如果还是引来一片骂声,我无话可说!
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;/// <summary>
/// MS SQL 2000 数据访问层
/// </summary>
public class SqlDbCon
{
private static readonly string strConnection = "你的WEB.CONFIG配制节";
public SqlDbCon()
{
} #region 获得数据库连接对象 /// <summary>
/// 获得数据库连接对象
/// </summary>
/// <returns>返回一个SqlConnection实例</returns>
private static SqlConnection GetConnection()
{
SqlConnection con = new SqlConnection(strConnection);
return con;
} #endregion #region 获得数据库命令对象 /// <summary>
/// 获得数据库连接命令
/// </summary>
/// <param name="strProcedureName">存储过程的名字</param>
/// <param name="aryParameter">参数数组</param>
/// <returns>返回一个SqlCommand实例</returns>
private static SqlCommand GetCommand(string strProcedureName, params SqlParameter[] aryParameter)
{
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = strProcedureName;
foreach (SqlParameter sqlParameter in aryParameter)
{
cmd.Parameters.Add(sqlParameter);
}
return cmd;
} #endregion #region 组装SqlParameter对象 /// <summary>
/// 组装SqlParameter对象
/// </summary>
/// <param name="strParameterName">参数名字</param>
/// <param name="sqlDbType">参数类型</param>
/// <param name="intSize">参数字节</param>
/// <param name="objValue">参数值</param>
/// <returns>返回一个SqlParameter实例</returns>
protected static SqlParameter BuildParameter(string strParameterName, SqlDbType sqlDbType, int intSize, object objValue)
{
SqlParameter sqlParameter = new SqlParameter(strParameterName, objValue);
sqlParameter.SqlDbType = sqlDbType;
sqlParameter.Size = intSize;
return sqlParameter;
} #endregion #region 执行带多个参数的存储过程 /// <summary>
/// 执行带多个参数的存储过程
/// </summary>
/// <param name="strProcdureName">存储过程名</param>
/// <param name="aryParameter">参数数组</param>
/// <returns>如果成功返回true</returns>
public static bool ExecuteProcedure(string strProcedureName, params SqlParameter[] aryParameter)
{
SqlConnection con = GetConnection();
SqlCommand cmd = GetCommand(strProcedureName, aryParameter);
cmd.Connection = con; try
{
con.Open();
cmd.ExecuteNonQuery();
return true;
}
catch (SqlException e)
{
throw new Exception(e.Message);
}
finally
{
cmd.Dispose();
con.Close();
}
}
}
我估计编译都通不过
catch里面没有返回值
二个三角的跟我差不多,一边休息去!
----〉偷偷的告诉你
CSDN一个三角的高手有很多
要我星星月亮一打了
真想好好教育教育某人
“不耻下问”的典故
何况,除了本人
回帖的还偏偏都是比某人有能耐的不耻下问不懂
不耻上问又不明白
建议加一个Exception类我的程序里面没有把系统异常直接扔给客户的~~~~
它的两个属性ConnectionString和ProviderName你一定也不知道
才会用ToString()方法
可见外行!
还有,何必要这样取连接子串呢
难道阁下这样的高手一点向后兼容的观点都没有
没人SB到把自个的错误抛给别人SEE,这样不是给HACKER机会,这当然是在调试的时候,正试运行的时候,会写自定义的Exception类,抛到错误的页面!不错错误的原因!没CATH当然也会,可这样你的软件就不完没,最好也要搞个CATC空块
*/我服了,没话可说~
这个catch留不留看个人设计风格,一般来说最底层的函数可以不try,这个ExecuteProcedure可以不try,在调用该方法的过程内捕获;
*/
这里用try,是为了在finally里面调用连接.Close()
1.关心设置连接池大小
2.保存操作的一致性(有open,就别忘记close)对于数据库访问层(断开模式和连接模式)都有可取之处,根据需求不同而定(PetShop是个好例子但未必都一样它只是指导了B/S编程方法)
----〉
我看到的代码确实是把异常直接抛给了别人
呵呵如果说你还会完善现在的程序
那这个程序应该是没问题
反正以后还会完善
具体到啥程度别人也不知道
也许比MS的框架还要好很多
中国的软件未来就靠楼主了
我看你行~~~
我支持你~~~
二个三角的跟我差不多,一边休息去
---------------------------------
我 是刚玩这个
可不能这么说哈
在做数据访问层上还需要深入学习和实践.不针对具体某个类,抽象出来.
如(连接模式)
public interface IUserDispose
{
void Dispose(IUserDisposeCallBack handler);
}public interface IUserDisposeCallBack
{
Dispose(SqlDataReader read);
}UserDispose:IUserDispose
{
public void Dispose(IUserDisposeCallBack handler)
{
SqlCommand cmd=null;
SqlDataReader read=null;
try
{
cmd=....
cmd.Connection.Open();
handler.Dispose(read);
}
catch(SqlException ex)
{
myLog.Write("yearself message",ex);
}
finally
{
if(cmd!=null&&cmd.Connection.State!=ConnectionState.Close)
cmd.Connection.Close();
}
}
}这里只是一个小例子(模板方法),希望lz针对接口编程,这里当然也可以用.net委托来实现
在实现CallBack的自由度就大了(扩展)可以自由定制
刚才看了
protected static SqlParameter BuildParameter(string strParameterName, SqlDbType sqlDbType, int intSize, object objValue)
{
SqlParameter sqlParameter = new SqlParameter(strParameterName, objValue);
sqlParameter.SqlDbType = sqlDbType;
sqlParameter.Size = intSize;
return sqlParameter;
}
有时可以不申明类型
cmd.Parameters.Add("参数",值);
为的是维护方便
严格地说对效率会产生负面影响
对于B/S程序的数据访问目前还没有好的解决办法
虽然有连接池技术
但对于大并发请求,数据库依然会很吃力
但是可以采用象数据缓存的方法来绕开对数据库的多次相同结果的访问
Oracle在大并发的情况下表现比SqlServer好(本人自己做的测试)
一个重要的原因就是
Oracle本身就带有缓存技术
毕竟从内存读取数据要比磁盘读文件快很多象楼主那样有不要缓存
又想要高性能
还不如不要封装数据访问层
直接将数据访问代码写入每一个需要访问数据库的方法中
而且务必要调用close()方法
且保证close()方法在方法体中任何执行路径能够被访问到
针对接口编程是为了有良好的扩展性.
而对net数据库编程中的注意点也都说了.
不知道在贴中的有没有处理过每秒100个并发请求.
每小时采集10万数据信息,很多时候要实践来说话.