服务器的数据存储和读取
发布时间:2019-04-29 11:40:00 来源: 互盟云
先看一下服务器读取数据与存储数据的结构图,CacheModel中进行逻辑处理,DBModel是访问数据库的操作类,调用数据库的存储过程来完成sqlServer中存储和读取,当然正常的服务器为了效率会做缓存,用过的数据存到缓存中,这样可以避免不断访问数据库节省性能。
首先我先来制作DBModel模块,它与数据进行交互,有一些通用的增删改查方法以及entity转化为SqlParameter和从数据库读取到的数据转化为Entity的工具方法。增删改查的具体具体实现我们之后会介绍。
///数据库连接字符串
protectedoverridestringConnectionString
{
get{returnDBConn.DBGameServer;}
}
///表名
protectedoverridestringTableName
{
get{return"Role_Equip";}
}
///转换参数
protectedoverrideSqlParameter[]ValueParas(Role_EquipEntityentity)
{
SqlParameter[]parameters=newSqlParameter[]{
newSqlParameter("@Id",entity.Id){DbType=DbType.Int32},
newSqlParameter("@Status",entity.Status){DbType=DbType.Int32},
};
returnparameters;
}
//封装对象
protectedoverrideRole_EquipEntityGetEntitySelfProperty(IDataReaderreader,DataTabletable)
{
Role_EquipEntityentity=newRole_EquipEntity();
foreach(DataRowrowintable.Rows)
{
varcolName=row.Field<string>(0);
if(reader[colName]isDBNull)
continue;
switch(colName.ToLower())
{
case"id":
if(!(reader["Id"]isDBNull))
entity.Id=Convert.ToInt32(reader["Id"]);
break;
case"status":
if(!(reader["Status"]isDBNull))
entity.Status=(EnumEntityStatus)Convert.ToInt32(reader["Status"]);
break;
}
}
returnentity;
}
构建一个数据交互的实体类,用来操作具体的数据。
publicpartialclassRole_EquipEntity:MFAbstractEntity
{
///主键
publicoverrideint?PKValue
{
get
{
returnthis.Id;
}
set
{
this.Id=value;
}
}
///编号
publicint?Id{get;set;}
///状态
publicEnumEntityStatusStatus{get;set;}
///角色Id
publicintRoleId{get;set;}
}
存储过程是对数据库操作的方法,外部可以调用存储过程定义的名字,传入相对应的参数,而存储过程都是通用的,只是针对具体的数据不同而不同,那么我就把通用的存储过程放在下面。
CREATEProcedure[dbo].[GetPageList]
@TableNamevarchar(200),--表名
@Fieldsvarchar(1000)='*',--字段名(全部字段为*)
@OrderFieldvarchar(500),--排序字段(必须!支持多字段)
@SqlWherevarchar(5000)=Null,--条件语句(不用加where)
@PageSizeint,--每页多少条记录
@PageIndexint=1,--指定当前为第几页
@TotalCountintoutput--返回总记录数
as
begin
BeginTran--开始事务
Declare@sqlnvarchar(4000);
Declare@TotalPageint;
set@TotalCount=0;
set@TableName=@TableName;
if(@PageIndexisnull)
set@PageIndex=-1
if(@PageSizeisnull)
set@PageSize=-1
if(@PageIndex<1and@PageSize<1)
begin
if(@SqlWhere=''or@SqlWhere=NULL)
set@sql='select'+@Fields+'from
'+@TableName+'orderby'+@OrderField
else
set@sql='select'+@Fields+'from
'+@TableName+'where'+@SqlWhere+'orderby'+@OrderField
end
else
begin
--计算总记录数
if(@SqlWhere=''or@SqlWhere=NULL)
set@sql='select@TotalCount=count(1)from'+
@TableName
else
set@sql='select@TotalCount=count(1)from'+
@TableName+'where'+@SqlWhere
EXECsp_executesql@sql,N'@TotalCountint
OUTPUT',@TotalCountOUTPUT--计算总记录数
--计算总页数
select@TotalPage=CEILING((@TotalCount+0.0)/@PageSize)
if(@SqlWhere=''or@SqlWhere=NULL)
set@sql='Select*FROM(selectROW_NUMBER()Over
(orderby'+@OrderField+')asrowId,'+@Fields+'from'+
@TableName
else
set@sql='Select*FROM(selectROW_NUMBER()Over
(orderby'+@OrderField+')asrowId,'+@Fields+'from'+
@TableName+'where'+@SqlWhere
--处理页数超出范围情况
if@PageIndex<=0
Set@PageIndex=1
if@PageIndex>@TotalPage
Set@PageIndex=@TotalPage
--处理开始点和结束点
Declare@StartRecordint
Declare@EndRecordint
set@StartRecord=(@PageIndex-1)*@PageSize+1
set@EndRecord=@StartRecord+@PageSize-1
--继续合成sql语句
set@Sql=@Sql+')as_pagelisttable_whererowId
between'+Convert(varchar(50),@StartRecord)+'and'+Convert
(varchar(50),@EndRecord)
end
print@Sql
Exec(@Sql)
---------------------------------------------------
If@@Error<>0
Begin
RollBackTran
Return-1
End
Else
Begin
CommitTran
Return@TotalPage---返回总页数
End
end
GO
CREATEPROCEDURE[dbo].[GetPageList_High]
(
@TableNameVARCHAR(255),--表名
@Fieldsvarchar(1000)='*',--需要返回的列
@OrderFieldVARCHAR(255)='',--排序的字段名
@SqlWhereVARCHAR(2000)='',--查询条件(注意:不要加WHERE)
@PageSizeINT=10,--页尺寸
@PageIndexINT=1,--页码
@OrderTypeBIT=0,--设置排序类型,非0值则降序
@TotalCountintoutput--返回总记录数
)
AS
SETNOCOUNTON
begintran
begintry
DECLARE@strSQLVARCHAR(5000)--主语句
DECLARE@strTmpVARCHAR(1000)--临时变量
DECLARE@strOrderVARCHAR(400)--排序类型
declare@sqlnvarchar(1000)
if@PageIndex<1and@PageSize<1
begin
if(@SqlWhere=''or@SqlWhere=NULL)
set@strSQL='select'+@Fields+'from'+@TableName+'orderby'+@OrderField
else
set@strSQL='select'+@Fields+'from'+@TableName+'where'+@SqlWhere+'orderby'+@OrderField
if@OrderType!=0
set@strSQL=@strSQL+'desc'
end
else
begin
--计算总记录数
if(@SqlWhere=''or@SqlWhere=NULL)
set@sql='select@TotalCount=count(1)from'+@TableName
else
set@sql='select@TotalCount=count(1)from'+@TableName+'where'+@SqlWhere
EXECsp_executesql@sql,N'@TotalCountintOUTPUT',@TotalCountOUTPUT--计算总记录数
IF@OrderType!=0
BEGIN
SET@strTmp='<(SELECTMIN'
SET@strOrder='ORDERBY'+@OrderField+'DESC'
--如果@OrderType不是0,就执行降序,这句很重要
END
ELSE
BEGIN
SET@strTmp='>(SELECTMAX'
SET@strOrder='ORDERBY'+@OrderField+'ASC'
END
IF@PageIndex=1
BEGIN
IF@SqlWhere!=''
SET@strSQL='SELECTTOP'+str(@PageSize)+''+@Fields+'FROM'+@TableName+'WHERE'+@SqlWhere+''+@strOrder
ELSE
SET@strSQL='SELECTTOP'+str(@PageSize)+''+@Fields+'FROM'+@TableName+''+@strOrder
--如果是第一页就执行以上代码,这样会加快执行速度
END
ELSE
BEGIN
declare@OrderFivarchar(50)
set@OrderFi=SUBSTRING(@OrderField,CHARINDEX('.',@OrderField)+1,LEN(@OrderField));
--以下代码赋予了@strSQL以真正执行的SQL代码
SET@strSQL='SELECTTOP'+str(@PageSize)+''+@Fields+'FROM'
+@TableName+'WHERE'+@OrderField+''+@strTmp+'('+@OrderFi+')FROM(SELECTTOP'+str((@PageIndex-1)*@PageSize)+''+@OrderField+'FROM'+@TableName+''+@strOrder+')AStblTmp)'+@strOrder
IF@SqlWhere!=''
SET@strSQL='SELECTTOP'+str(@PageSize)+''+@Fields+'FROM'
+@TableName+'WHERE'+@OrderField+''+@strTmp+'('
+@OrderFi+')FROM(SELECTTOP'+str((@PageIndex-1)*@PageSize)+''
+@OrderField+'FROM'+@TableName+'WHERE'+@SqlWhere+''
+@strOrder+')AStblTmp)AND'+@SqlWhere+''+@strOrder
END
end
EXEC(@strSQL)
committran
endtry
begincatch
rollbacktran
endcatch
SETNOCOUNTOFF
GO
最后是cacheModel具体的数据表业务逻辑类,可以针对需求进行相应的逻辑开发并调用缓存或者DBModel与SqlServer进行数据交互。
publicpartialclassRole_EquipCacheModel:MFAbstractCacheModel
{
privatestaticobjectlock_object=newobject();
privatestaticRole_EquipCacheModelinstance=null;
publicstaticRole_EquipCacheModelInstance
{
get
{
if(instance==null)
{
lock(lock_object)
{
if(instance==null)
{
instance=newRole_EquipCacheModel();
}
}
}
returninstance;
}
}
privateRole_EquipDBModelDBModel{get{returnRole_EquipDBModel.Instance;}}
publicMFReturnValue<object>Create(Role_EquipEntityentity)
{
returnthis.DBModel.Create(entity);
}
publicMFReturnValue<object>Update(Role_EquipEntityentity)
{
returnthis.DBModel.Update(entity);
}
}
例如角色的经验值变化了,客户端发来消息,服务端在Role中的客户端类中执行相应的刷新经验逻辑,请求到DBCacheModel执行相应的数据操作业务。
这样基本就完成了客户端到服务器到数据库的交互流程,可以看到Entity、DBModel、DBCacheModel和存储过程基本上只有数据字段不同,其他的部分都是一样的,为了开发效率以及保证不出错,通常会开发相应的工具去自动生成这些类,我们会在之后介绍工具的开发。
本文来源:
https://www.humengyun.com/news-view-640.html