自定义个“缓存数据库”玩玩
Posted 布拉德皮特
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义个“缓存数据库”玩玩相关的知识,希望对你有一定的参考价值。
前言:首先声明,此文题目算是标题党的一种,是本人为了完成与widows服务通信编程学习幻想出来的一个模型(并不是真的缓存数据库),并且会作为本人以后加深多线程、设计模式、非关系型数据库等方面学习的一个模型实例,毕竟有一个实际的模型更容易加深理解。
完成这部分模型,大概会做一下几件事情:
1、 创建一个Windows服务(用来寄存这个“缓存数据库”)
2、 创建一个WCF服务,寄宿在windows服务中(用于跟客户端通信,对“缓存数据库”进行增删查操作)
3、 创建客户端进行测试
第1步:WCF服务的创建及对缓存对象增删查的实现
WCF服务创建的过程及其Endpoint节点相关基础在这里不作累述,网上很多资料,这里直接贴Contract及其实现的代码,保存表数据的数据结构是Dictionary<string,DataTable>,其中key存放是表名,DataTable存放是数据。
1 using System; 2 3 using System.Collections.Generic; 4 5 using System.Data; 6 7 using System.Linq; 8 9 using System.Runtime.Serialization; 10 11 using System.ServiceModel; 12 13 using System.ServiceModel.Web; 14 15 using System.Text; 16 17 18 19 namespace SelfWcfService 20 21 { 22 23 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。 24 25 [ServiceContract] 26 27 public interface ISelfSQLData 28 29 { 30 31 [OperationContract] 32 33 ExcuteResult CreateTable(string tableName, DataTable colNames); 34 35 36 37 [OperationContract] 38 39 ExcuteResult Insert(string tableName, SelfDataRow dr); 40 41 42 43 [OperationContract] 44 45 ExcuteResult Delete(string tableName, SelfDataRow dr); 46 47 48 49 [OperationContract] 50 51 ExcuteResult DropTable(string tableName); 52 53 54 55 [OperationContract] 56 57 Dictionary<string, DataTable> GetData(); 58 59 } 60 61 62 63 [DataContract] 64 65 public class SQLData 66 67 { 68 69 [DataMember] 70 71 public Dictionary<string, DataTable> DataTables { get; set; } 72 73 } 74 75 76 77 [DataContract] 78 79 public class SelfDataRow 80 81 { 82 83 [DataMember] 84 85 public DataTable DataTable { get; set; } 86 87 } 88 89 }
接口实现部分:
1 using System; 2 3 using System.Collections.Generic; 4 5 using System.Data; 6 7 using System.Linq; 8 9 using System.Runtime.Serialization; 10 11 using System.ServiceModel; 12 13 using System.ServiceModel.Web; 14 15 using System.Text; 16 17 18 19 namespace SelfWcfService 20 21 { 22 23 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。 24 25 // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。 26 27 public class SelfSQLData : ISelfSQLData 28 29 { 30 31 private static SQLData _sqlData; 32 33 public static SQLData SqlData 34 35 { 36 37 get 38 39 { 40 41 if (_sqlData == null) 42 43 { 44 45 _sqlData = new SQLData(); 46 47 } 48 49 if (_sqlData.DataTables == null) 50 51 { 52 53 _sqlData.DataTables = new Dictionary<string, System.Data.DataTable>(); 54 55 } 56 57 return _sqlData; 58 59 } 60 61 set 62 63 { 64 65 _sqlData = value; 66 67 } 68 69 } 70 71 72 73 private void InitalSqlData() 74 75 { 76 77 if (_sqlData == null) 78 79 { 80 81 _sqlData = new SQLData(); 82 83 } 84 85 if (_sqlData.DataTables == null) 86 87 { 88 89 _sqlData.DataTables = new Dictionary<string, System.Data.DataTable>(); 90 91 } 92 93 } 94 95 96 97 public ExcuteResult CreateTable(string tableName, DataTable colNames) 98 99 { 100 101 if (string.IsNullOrWhiteSpace(tableName)) 102 103 { 104 105 return new ExcuteResult(1, "表名不能为空!"); 106 107 } 108 109 if (colNames == null || colNames.Columns.Count < 1) 110 111 { 112 113 return new ExcuteResult(1, "表字段不能为空!"); 114 115 } 116 117 InitalSqlData(); 118 119 if (!_sqlData.DataTables.ContainsKey(tableName)) 120 121 { 122 123 try 124 125 { 126 127 _sqlData.DataTables.Add(tableName, colNames); 128 129 } 130 131 catch (Exception ex) 132 133 { 134 135 return new ExcuteResult(1, ex.Message); 136 137 } 138 139 return new ExcuteResult(0, "表" + tableName + "创建成功!"); 140 141 } 142 143 else 144 145 { 146 147 return new ExcuteResult(1, "已存在名为\'" + tableName + "\'的表"); 148 149 } 150 151 } 152 153 154 155 public ExcuteResult Insert(string tableName, SelfDataRow dr) 156 157 { 158 159 if (string.IsNullOrWhiteSpace(tableName)) 160 161 { 162 163 return new ExcuteResult(1, "表名不能为空!"); 164 165 } 166 167 if (dr == null) 168 169 { 170 171 return new ExcuteResult(1, "不能插入空的数据行!"); 172 173 } 174 175 InitalSqlData(); 176 177 if (!_sqlData.DataTables.ContainsKey(tableName)) 178 179 { 180 181 try 182 183 { 184 185 _sqlData.DataTables[tableName].Rows.Add(dr.DataTable.Rows[0]); 186 187 } 188 189 catch (Exception ex) 190 191 { 192 193 return new ExcuteResult(1, ex.Message); 194 195 } 196 197 return new ExcuteResult(0, "数据新增成功!"); 198 199 } 200 201 else 202 203 { 204 205 return new ExcuteResult(1, "表\'" + tableName + "\'不存在!"); 206 207 } 208 209 } 210 211 212 213 public ExcuteResult Delete(string tableName, SelfDataRow dr) 214 215 { 216 217 if (string.IsNullOrWhiteSpace(tableName)) 218 219 { 220 221 return new ExcuteResult(1, "表名不能为空!"); 222 223 } 224 225 if (dr == null) 226 227 { 228 229 return new ExcuteResult(1, "请指定删除对象!"); 230 231 } 232 233 InitalSqlData(); 234 235 if (!_sqlData.DataTables.ContainsKey(tableName)) 236 237 { 238 239 try 240 241 { 242 243 _sqlData.DataTables[tableName].Rows.Remove(dr.DataTable.Rows[0]); 244 245 } 246 247 catch (Exception ex) 248 249 { 250 251 return new ExcuteResult(1, ex.Message); 252 253 } 254 255 return new ExcuteResult(0, "数据删除成功!"); 256 257 } 258 259 else 260 261 { 262 263 return new ExcuteResult(1, "表\'" + tableName + "\'不存在!"); 264 265 } 266 267 } 268 269 270 271 public ExcuteResult DropTable(string tableName) 272 273 { 274 275 if (string.IsNullOrWhiteSpace(tableName)) 276 277 { 278 279 return new ExcuteResult(1, "表名不能为空!"); 280 281 } 282 283 InitalSqlData(); 284 285 if (!_sqlData.DataTables.ContainsKey(tableName)) 286 287 { 288 289 try 290 291 { 292 293 _sqlData.DataTables.Remove(tableName); 294 295 } 296 297 catch (Exception ex) 298 299 { 300 301 return new ExcuteResult(1, ex.Message); 302 303 } 304 305 return new ExcuteResult(0, "表" + tableName + "删除成功!"); 306 307 } 308 309 else 310 311 { 312 313 return new ExcuteResult(1, "表\'" + tableName + "\'不存在!"); 314 315 } 316 317 } 318 319 320 321 public Dictionary<string, DataTable> GetData() 322 323 { 324 325 return SqlData.DataTables; 326 327 } 328 329 } 330 331 }
整个WCF实现的逻辑都在上面了,web配置文件不需要改,因为它不以web的形式发布寄宿在IIS中,而是windows服务中。
第2步:将WCF寄宿在Windows服务中
Windows服务的创建、安装、启动在这里也不作累述,跟WCF一样,网上资料也很多。这里重点介绍一下将WCF寄宿在Windows服务中。
(1) 将wcf项目的dll引用到windows服务项目中
(2) 在app.config文件中配置WCF终结点
1 <system.serviceModel> 2 3 <services> 4 5 <service behaviorConfiguration="BasicServiceBehavior" 6 7 name="SelfWcfService.SelfSQLData"> 8 9 <endpoint address="" binding="netTcpBinding" bindingConfiguration="" 10 11 contract="SelfWcfService.ISelfSQLData"> 12 13 <!--<identity> 14 15 <dns value="192.168.1.4" /> 16 17 </identity>--> 18 19 </endpoint> 20 21 <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" 22 23 contract="IMetadataExchange" /> 24 25 <host> 26 27 <baseAddresses> 28 29 <add baseAddress="net.tcp://localhost:9000/SelfSQLData.svc"/> 30 31 <add baseAddress="http://localhost:9001/SelfSQLData.svc"/> 32 33 </baseAddresses> 34 35 </host> 36 37 </service> 38 39 </services> 40 41 <behaviors> 42 43 <serviceBehaviors> 44 45 <behavior name="BasicServiceBehavior"> 46 47 <serviceMetadata httpGetEnabled="true" /> 48 49 <serviceDebug includeExceptionDetailInFaults="true" /> 50 51 </behavior> 52 53 </serviceBehaviors> 54 55 </behaviors> 56 57 <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" /> 58 59 <bindings> 60 61 <netTcpBinding> 62 63 <binding name="defaultBinding" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"> 64 65 <security mode="None"> 66 67 <message clientCredentialType="None"/> 68 69 <transport clientCredentialType="None"></transport> 70 71 </security> 72 73 <readerQuotas /> 74 75 </binding> 76 77 </netTcpBinding> 78 79 </bindings> 80 81 </system.serviceModel>
(3) 在windows服务启动的时候启动WCF服务
1 using SelfHelper; 2 3 using System; 4 5 using System.Collections.Generic; 6 7 using System.ComponentModel; 8 9 using System.Data; 10 11 using System.Diagnostics; 12 13 using System.Linq; 14 15 using System.ServiceProcess; 16 17 using System.Text; 18 19 using System.ServiceModel; 20 21 22 23 namespace SelfSQL 24 25 { 26 27 public partial class SelfSQLServer : ServiceBase 28 29 { 30 31 public SelfSQLServer() 32 33 { 34 35 InitializeComponent(); 36 37 } 38 39 40 41 ServiceHost host = new ServiceHost(typeof(SelfWcfService.SelfSQLData)); 42 43 protected override void OnStart(string[] args) 44 45 { 46 47 LogWriter.WriteLog("服务已启动!"); 48 49 try 50 51 { 52 53 host.Open(); 54 55 Log以上是关于自定义个“缓存数据库”玩玩的主要内容,如果未能解决你的问题,请参考以下文章