实现新闻点击率收集器并不难,但制作一个节约系统资源,反应灵敏的的收集者就要我们发挥想象力了。这里向给出一个我想出来的解决方案。一个利用xml文件来实现中间缓存的点击率收集器。
其开发思想为:
浏览者-----------新闻---------xml文件-------------数据库
查看 插入记录 当记录数大于一个给定值,向数据库执行批量更新。
这个收集器只是利用了xml文件来暂时缓存数据,达到不频繁调用数据库连接,节约系统资源,使新闻访问速度加快。
-------------------------------------------------数据----------------------------------------
首先我们来建张新闻表:infomation
字段 数据类型
info_id int 标识 主键
info_caption varchar(100)
info_context ntext(16)
info_date varchar(30)
info_count bigint
做缓存用的xml文件 tempcount.xml
<newscount>---根节点
<countsum></countsum> 总点击数,后面要加个逻辑来判断这个数当符合条件时调用批量更新
<note newid=""> newid为新闻标号对应info_id
<tempcount></tempcount> 该新闻点击的数目
</note>
</newscount>
----------------------------------------------------------
-------------------------------------------商务逻辑-----------------------------------
我们在项目里建个类文件取名为newscount
下面的介绍该类的几个核心方法:
首先是addNewCount()方法,该方法是当用户点击新闻时调用的,收集用户点击新闻的信息,并把该信息插入到xml文件中
- public static void addNewCount(int newid)
- {
- string tempfile = HttpContext.Current.Server.MapPath(@"~/fore/tempcount.xml");
- bool flag = false;//用来标识消息队列中的缓存的消息是否超过范围
- XmlDocument document = new XmlDocument();
- document.Load(tempfile);
- XmlNode tmpNode = document.SelectSingleNode("newscount/countsum");
- int intTemp = int.Parse(tmpNode.InnerText);
- intTemp += 1;
- if (intTemp >= int.Parse(ConfigurationManager.AppSettings["CountQueue"].ToString())) flag = true;//判断是否需要调用方法uptCountQueue()
- tmpNode.InnerText = intTemp.ToString();
- XmlNode tmpNewNode = document.SelectSingleNode("newscount/note[@newid=" + newid.ToString() + "]");//xpath 返回属性newid为指定内容的note节点
- if (tmpNewNode != null)
- {
- intTemp = int.Parse(tmpNewNode.SelectSingleNode("tempcount").InnerText);
- intTemp += 1;
- tmpNewNode.SelectSingleNode("tempcount").InnerText = intTemp.ToString();
- }
- else
- {
- //新建一个note节点来保存点击信息
- XmlNode root = document.DocumentElement;
- XmlElement child = document.CreateElement("note");
- XmlAttribute attribute = document.CreateAttribute("newid");
- attribute.Value=newid.ToString();
- child.Attributes.Append(attribute);
- XmlElement child2;
- child2 = document.CreateElement("tempcount");
- child2.InnerText ="1";
- child.AppendChild(child2);
- root.AppendChild(child);
- }
- document.Save(tempfile);
- if (flag) uptCountQueue();//如果符合条件就调用更新方法
- }
接下来要介绍的是更新方法uptCountQueue(),该方法主要作用为读取xml文件tempcount.xml,分析里面的数据,然后将收集
到的数据更新到数据库中。
- public static void uptCountQueue()
- {
- string tmpFilePath = HttpContext.Current.Server.MapPath(@"~/fore/tempcount.xml");
- XmlReader reader = XmlReader.Create(tmpFilePath); //xmlReader
- DataTable updTable = new DataTable();
- DataColumn column = new DataColumn("info_id", typeof(int));
- updTable.Columns.Add(column);
- column = new DataColumn("info_count", typeof(Int64));
- updTable.Columns.Add(column);
- DataRow row;
- while (reader.Read())
- {
- if (reader.NodeType == XmlNodeType.Element && reader.Name == "note")
- {
- row=updTable.NewRow();
- XmlReader readerSubTree = reader.ReadSubtree();
- while (readerSubTree.Read())
- {
- if (readerSubTree.NodeType == XmlNodeType.Element && readerSubTree.Name == "note")
- {
- if (readerSubTree.MoveToAttribute("newid")) //判断节点note是否包含属性newid,如果存在将移动到该属性
- row[0] = readerSubTree.Value; //读取该属性的值
- }
- if (readerSubTree.NodeType == XmlNodeType.Element && readerSubTree.Name =="tempcount")
- {
- row[1] = reader.ReadElementContentAsInt();
- }
- }
- updTable.Rows.Add(row);
- }
- }
- reader.Close();
- string filter=null; //用来设置下面sql过滤条件
- foreach (DataRow r in updTable.Rows)
- filter += r[0].ToString() + ",";
- filter=filter.Substring(0, filter.Length - 1);//去处多余的“,”
- DataSet ds = new DataSet();
- SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["school_river"].ToString());
- SqlCommand cmd = new SqlCommand("select info_id,info_count from infomation where info_id in ("+filter+")", conn);
- SqlCommand cmd2=new SqlCommand("update infomation set info_count=info_count+@info_count where info_id=@info_id",conn);
- SqlDataAdapter adpt = new SqlDataAdapter(cmd);
- adpt.UpdateCommand=cmd2;
- ad pt.UpdateCommand.Parameter.add(New SqlParameter("@info_count",SqlDbType.BigInt,8,"info_count"));
- adpt.UpdateCommand.Parameter.add(New SqlParameter("@info_id",SqlDbType.Int,4,"info_id"));
- // SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(adpt); //SqlCommandBuilder
- adpt.Fill(ds);
- for (int i = 0; i < ds.Tables[0].Rows.Count; i++) //修改获取的数据
- ds.Tables[0].Rows[i][1] = updTable.Rows[i][1];
- adpt.Update(ds.Tables[0]); //更新
- XmlDocument doc = new XmlDocument();
- doc.LoadXml(@"<newscount><countsum>0</countsum></newscount>"); //重构tempcount.xml文件
- doc.Save(HttpContext.Current.Server.MapPath(@"~/fore/tempcount.xml"));
- }
到这里这个点击率收集者的,主要框架也算打好了,还有就是在web.config文件里再添加写内容:
<appSettings>
<add key="CountQueue" value="50"></add>
</appSettings>
里面的value存储的值为tempcount.xml中可以保存的点击数,如果大于该数的话,系统将自动调用uptCountQueue()方法。
使用这个收集者个时候只要把方法addNewCount()添加到新闻显示页面的Page_load事件中就可以了.
该收集者已经打包了,下载地址为:http://download.csdn.net/source/697297