改进了一个DBAccess类,顺便说说啥是线程安全
原文:
我的DbHelper数据操作类
http://www.cnblogs.com/fanrong/archive/2007/04/25/726526.html
源码下载地址
http://www.cnblogs.com/Files/onlytiancai/WawaDbAccess.rar
修改如下
加了一个参数帮助类,如下,从旧版petshop拆出来的,功能是缓存每个命令的参数。
经测试,代码一行也不用改,只改配置文件,在access和sqlserver2005下都能通过。
public class DbParametersHelper
{
private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable());
public static void CacheParameters(string cacheKey, params DbParameter[] cmdParms)
{
parmCache[cacheKey] = cmdParms;
}
public static DbParameter[] GetCachedParameters(string cacheKey)
{
DbParameter[] cachedParms = (DbParameter[])parmCache[cacheKey];
if (cachedParms == null)
return null;
DbParameter[] clonedParms = new DbParameter[cachedParms.Length];
for (int i = 0, j = cachedParms.Length; i < j; i++)
clonedParms[i] = (DbParameter)((ICloneable)cachedParms[i]).Clone();
return clonedParms;
}
}
DbHelper类里加了两个方法,如下,功能分别是把参数缓存起来和从缓存里初始化参数
public void CachedParameters(DbCommand cmd)
{
DbParameterCollection paramColl = cmd.Parameters;
DbParameter[] parms = new DbParameter[paramColl.Count];
for (int i = 0; i < paramColl.Count; i++)
{
parms[i] = paramColl[i];
}
DbParametersHelper.CacheParameters(
string.Format("{0}{1}", cmd.Connection.ConnectionString, cmd.CommandText),
parms);
}
public bool initParametersFromCache(DbCommand cmd)
{
DbParameter[] parms = DbParametersHelper.GetCachedParameters(
string.Format("{0}{1}", cmd.Connection.ConnectionString, cmd.CommandText));
if (parms == null)
return false;
for (int i = 0; i < parms.Length; i++)
{
cmd.Parameters.Add(parms[i]);
}
return true;
}
使用如下
class Program
{
const string ADD_USER_SQL = "insert into U_Users([userid],[username],[nickname],[password],[hashpassword],[createdate],[createdip],[status])" +
"values(@userid,@username,@nickname,@password,@hashpassword " +
",@createdate,@createip,0)";
public static void AddUser(string username, string password, string nickname, string createip)
{
DbHelper db = new DbHelper();
DbCommand cmd = db.GetSqlStringCommond(ADD_USER_SQL);
if (db.initParametersFromCache(cmd))
{
cmd.Parameters[0].Value = 1;
cmd.Parameters[1].Value = username;
cmd.Parameters[2].Value = nickname;
cmd.Parameters[3].Value = password;
cmd.Parameters[4].Value = password;
cmd.Parameters[5].Value = DateTime.UtcNow;
cmd.Parameters[6].Value = createip;
}
else
{
db.AddInParameter(cmd, "@userid", DbType.Int32, 1);
db.AddInParameter(cmd, "@username", DbType.String, username);
db.AddInParameter(cmd, "@nickname", DbType.String, nickname);
db.AddInParameter(cmd, "@password", DbType.String, password);
db.AddInParameter(cmd, "@hashpassword", DbType.String, password);
db.AddInParameter(cmd, "@createdate", DbType.Date, DateTime.UtcNow);
db.AddInParameter(cmd, "@createip", DbType.String, createip);
db.CachedParameters(cmd);
}
db.ExecuteNonQuery(cmd);
}
static void Main(string[] args)
{
try
{
AddUser("onlytiancai", "##$%&SDF", "蛙蛙王子", "192.168.0.1");
AddUser("tiancai", "3234234", "水然枫林醉", "192.168.0.23");
Console.WriteLine("ok");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.Read();
}
}
sqlserver的配置
<appSettings>
<add key="DbHelperProvider" value="System.Data.SqlClient"/>
<add key="DbHelperConnectionString" value="Data Source=."SQLEXPRESS;AttachDbFilename=H:"KM_SVN"sync"src"db"KM.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True"/>
</appSettings>
access的配置
<appSettings>
<add key="DbHelperProvider" value="System.Data.OleDb"/>
<add key="DbHelperConnectionString" value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=H:"KM_SVN"sync"src"db"km.mdb;Persist Security Info=False"/>
</appSettings>
sqlserver的建表脚本
CREATE TABLE [dbo].[U_Users](
[UserID] [int] NOT [UserID] [int] NOT NULL,
NULL,
[Username] [varchar](16) COLLATE Chinese_PRC_CI_AS NOT NULL,
[Nickname] [nvarchar](16) COLLATE Chinese_PRC_CI_AS NOT NULL,
[Password] [varchar](16) COLLATE Chinese_PRC_CI_AS NOT NULL,
[HashPassword] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
[CreateDate] [datetime] NOT NULL CONSTRAINT [DF_U_Users_CreateDate] DEFAULT (getdate()),
[CreatedIP] [varchar](32) COLLATE Chinese_PRC_CI_AS NOT NULL,
[LastLoginIp] [varchar](32) COLLATE Chinese_PRC_CI_AS NULL,
[LastLoginTime] [datetime] NULL CONSTRAINT [DF_U_Users_LastLoginTime] DEFAULT (getdate()),
[Status] [tinyint] NOT NULL CONSTRAINT [DF_U_Users_Status] DEFAULT ((0))
) ON [PRIMARY]
access的表结构
[Username] 数字
[Nickname] 文本
[Password] 文本
[HashPassword] 文本
[CreateDate] 日期/时间
[CreatedIP] 文本
[LastLoginIp] 文本
[LastLoginTime] 日期/时间
[Status] 数字
[1] [2] 下一页