返回首页

互盟云动态

多看云动态,了解互盟新动向、学习行业科普知识
< 返回业界新闻列表

服务器的数据存储和读取

发布时间:2019-04-29 11:40:00    来源: 互盟云
  数据的存储和读取是保证数据永久化的重要一步,客户端读取excel等文件读取基础的一些数据,服务器则需要访问数据库进行数据的存储和读取的过程。

  先看一下服务器读取数据与存储数据的结构图,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和存储过程基本上只有数据字段不同,其他的部分都是一样的,为了开发效率以及保证不出错,通常会开发相应的工具去自动生成这些类,我们会在之后介绍工具的开发。
现在注册,即可享受多款产品免费体验
立即注册
故障赔偿 无理由退款 快速备案 专业服务 服务支持