惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
博客园_首页
宝玉的分享
宝玉的分享
S
SegmentFault 最新的问题
Jina AI
Jina AI
Hugging Face - Blog
Hugging Face - Blog
V
Visual Studio Blog
美团技术团队
IT之家
IT之家
罗磊的独立博客
Blog — PlanetScale
Blog — PlanetScale
Google DeepMind News
Google DeepMind News
月光博客
月光博客
Microsoft Azure Blog
Microsoft Azure Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
博客园 - 叶小钗
M
MIT News - Artificial intelligence
B
Blog RSS Feed
有赞技术团队
有赞技术团队
Y
Y Combinator Blog

博客园 - 飞得更高

MPI并行编程系列之五:图的单源最短路径算法 MPI并行编程系列之四:KMP算法及并行化 MPI并行编程系列三:并行正则采样排序PSRS MPI并行编程系列 MPI并行编程系列二:快速排序 MPI并行编程系列一:枚举排序 c#基础(一)之内存管理 用Windows Live Writer 首发Blog 一个被我长期忽略的一个问题:验证控件与Button的OnClientClick事件 LINQ TO SQL 复杂查询之Queries with local collections are not supported linq下数据库接口的定义和实现(linq to SQL) sql 常用函数总结 面对恶意操作,勇敢说不------定制服务器端验证器 验证控件失效,求助解决方案 js浮点运算bug的解决办法 从页面的生命周期事件到页面基类(PageBase类)的编写 c# 委托实例 回车与服务器控件Button的Click事件 javascript:Web页面中的所有控件清空 - 飞得更高 - 博客园
远程数据自动导入的设计与实现
飞得更高 · 2008-12-10 · via 博客园 - 飞得更高

一、需求

    有两个部门,部门A和部门B,部门B需要部门A提供一些数据,而这些数据存放在部门A的数据库中(这些数据会不定期的更新),要求将这些数据的变更(主要是添加)定期自动从部门A 的数据库导入到部门B的数据库中。注意:部门A的数据库和部门B的数据库不是统一的。

二、分析

    要实现这个功能,最平常的想法就是:从部门A的数据库中获取这些数据,然后将这些数据导入到部门B的数据库中。下面是对这两个步骤的仔细分析。

    1)从部门A的数据库中取得数据

    分析:在部门A架设一个网站,这个网站的功能很简单:从部门A的数据库中读取数据,并显示在页面上。

    2)取得网站上的数据,并将这些数据导入到部门B的数据库中

    分析:分为以下几个步骤:

    1 ) 要实现自动定期的导入,我们需要设计一个Windows服务定期访问架设在部门A的网站,并从页面上读取数据。

    2)要将这些数据导入到部门B的数据库中,就要将这些数据进行解析,是指满足部门B的数据库的格式。因为部门A和部门B的数据库是不统一的。

    3) 完成上面两部后, 将解析好的数据导入到部门B的数据库中。

  难点:部门A的数据以一种什么样的格式显示在网站上,才能更好的被读取,解析成部门B所需要的数据呢?这是我想到了XML:将部门A的数据以XML的格式显示在网站的页面上,部门B获取这些XML,解析XML,最后就能获取这些数据。

    综上,要实现这个功能,我们需要一下三个步骤

  1)在部门A架设一网站,将数据以xml的格式显示在网站的页面上。

  2)设计一windows服务,定期访问这个网站,取得xml,在对这个xml进行解析,获得需要的数据。

  3) 将这些数据导入到部门B的数据库中。

三、实现

  1)部门A架设一网站,将数据以xml的格式显示在网站的页面上。

    这个网站是非常简单的,一个页面,没有任何业务逻辑,就是将取出数据,然后拼成xml的格式,显示在页面上。

    如何具体实现就不多说了,就是根据给定的XML的形式,拼字符串,下面是我xml的格式,title是对数据的描述,value的数据的值。

Code
<Entities>
  
<Entity>
    
<Item title="****" value="***"/>
    
<Item title="****" value="***"/>
    
<Item title="****" value="***"/>
  
</Entity>
  
</Entities>

   2)设计一windows服务,访问这个网站,读取数据,解析数据。

   这一步,主要说下从页面中获取xml,并解析xml。至于如何建windows服务这里就不说了,相信大家都很熟悉。

  1>从页面中获取xml类,看代码:

Code
  /// <summary>
    
/// 从页面中获得XML文档
    
/// </summary>
    public class GetXmlDocFromWeb
    {
/// <summary>
        
/// 获得XML文档
        
/// </summary>
        
/// <returns></returns>
        public static XmlDocument LoadXMLDocument(string url)
        {
            StreamReader streamReader 
= GetWebContent(url);
            XmlDocument xdoc 
= new XmlDocument();
            xdoc.Load(streamReader);
            
return xdoc;
        }
        
private static StreamReader GetWebContent(string Url)
        {
            
//声明一个HttpWebRequest请求
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
            
//设置连接超时时间
            request.Timeout = 300000;

            request.Headers.Set(

"Pragma""no-cache");
            HttpWebResponse response 
= (HttpWebResponse)request.GetResponse();
            Stream streamReceive 
= response.GetResponseStream();
            Encoding encoding 
= Encoding.GetEncoding("utf-8");
            StreamReader streamReader 
= new StreamReader(streamReceive, encoding);
            
return streamReader;
        }
    }

这个类接收一个url(网站的地址)参数,返回一个xml文档。

  2> 获得xml文档后,对这个xml文档进行解析,(文档格式在上文中已给出)

   从上面的文档格式我们可以看出,这一文档有许多Entity,每个Entity有许多Item,每个Item又有title和value属性,因此抽象出两个列:EntityImporter和ItemImporter。代码如下:

首先是EntityImporter类:

Code
/// <summary>
    
/// 要导入的数据
    
/// </summary>
    public class EntityImport
    {
        
private List<ItemImport> _ItemList = new List<ItemImport>();
        
/// <summary>
        
/// 导入数据的详细信息
        
/// </summary>
        public List<ItemImport> ItemList
        {
            
get { return _ItemList; }
            
set { _ItemList = value; }
        }
    }

然后是ItemImporter类:

Code
/// <summary>
    
/// 导入数据详细信息
    
/// </summary>
    public class ItemImport
    {
        
/// <summary>
        
/// 名称属性
        
/// </summary>
        public string Title { getset; }
        
/// <summary>
        
/// 值属性
        
/// </summary>
        public string Value { getset; }
    }

有了这两类后,就可以对XML进行解析,代码如下:

Code
 /// <summary>
        
/// 解析XML文档
        
/// </summary>
        
/// <param name="xdoc"></param>
        
/// <param name="rootNode"></param>
        
/// <returns></returns>
        public static List<EntityImport> parseXmlDocument(XmlDocument xdoc, string rootNode)
        {
            List
<EntityImport> EntityImportList = new List<EntityImport>();foreach (XmlNode xmlNode in xdoc.SelectSingleNode(rootNode).ChildNodes)
            {
                
if (xmlNode != null)
                {
                    EntityImport entityImport 
= new EntityImport();
                    EntityImportList.Add(entityImport);
                    
foreach (XmlNode node in xmlNode.ChildNodes)
                        
if (node != null)
                            entityImport.ItemList.Add(getItemFromNode(node));
                }

            }

return EntityImportList;
        }
private static ItemImport getItemFromNode(XmlNode node)
        {
            ItemImport item 
= new ItemImport();
            item.Title 
= getStringFromAttribute(node, "title");
            item.Value 
= getStringFromAttribute(node, "value");
            
return item;
        }
private static string getStringFromAttribute(XmlNode node, string AttributeName)
        {
            
if (node.Attributes[AttributeName] == null)
                
return string.Empty;
            
else
                
return node.Attributes[AttributeName].Value;
        }
    }

这样我们将Xml解析成一个list,就可以非常方便的遍历这个list取得数据。取得数据后,就可以导入到数据库了。

  3> 导入数据

    要导入数据,首先要取得数据库,考虑到数据库可能会变,我们将数据库的连接字符串放在了注册表文件中,这样就不用担心数据库的变化。

取得数据库的代码如下:

Code
/// <summary>
    
/// 取得数据库
    
/// </summary>
    public class GetDataBase
    {
        
private const string RegPath = @"SOFTWARE\SrimsDatabaseConnectionString";
        
private const string ConnectionStringKey = "connectionString";
        
/// <summary>
        
/// 取得数据库
        
/// </summary>
        
/// <returns></returns>
        public static Database GetNewDataBase()
        {
            
string connectionString = getConnectionString();
            Database database 
= Database.New(connectionString);
            
return database;
        }
        
private static string getConnectionString()
        {
            
return Registry
                   .LocalMachine
                   .OpenSubKey(RegPath)
                   .GetValue(ConnectionStringKey)
                   .ToString();
        }
    }

好,这样数据导入前的工作就算完成了,导入数据的过程就不说了,这是最简单的部分了。

四、总结

    这个功能的核心就是取得XML文档,并对其进行解析。实现了这两个功能,一切都变得简单了。