ORM简介

对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 这也同时暗示者额外的执行开销;然而,如果ORM作为一种中间件实现,则会有很多机会做优化,而这些在手写的持久层并不存在。 更重要的是用于控制转换的元数据需要提供和管理;但是同样,这些花费要比维护手写的方案要少;而且就算是遵守ODMG规范的对象数据库依然需要类级别的元数据。

对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

      面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象,对象关系映射技术应运而生。
      让我们从O/R开始。字母O起源于"对象"(Object),而R则来自于"关系"(Relational)。几乎所有的程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。

      当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取对象信息,等等。你在DAL中写了很多的方法来读取对象数据,改变状态对象等等任务。而这些代码写起来总是重复的。
  如果打开你最近的程序,看看DAL代码,你肯定会看到很多近似的通用的模式。我们以保存对象的方法为例,你传入一个对象,为SqlCommand对象添加SqlParameter,把所有属性和对象对应,设置SqlCommand的CommandText属性为存储过程,然后运行SqlCommand。对于每个对象都要重复的写这些代码。
  除此之外,还有更好的办法吗?有,引入一个O/R Mapping。实质上,一个O/R Mapping会为你生成DAL。与其自己写DAL代码,不如用O/R Mapping。你用O/R Mapping保存,删除,读取对象,O/R Mapping负责生成SQL,你只需要关心对象就好。 [break]

      对象关系映射成功运用在不同的面向对象持久层产品中,如:Torque,OJB,Hibernate,TopLink,Castor JDO, TJDO 等。
      一般的ORM包括以下四部分:
      一个对持久类对象进行CRUD操作的API;
      一个语言或API用来规定与类和类属性相关的查询;
      一个规定mapping metadata的工具;
      一种技术可以让ORM的实现同事务对象一起进行dirty checking, lazy association fetching以及其他的优化操作。

一、目前流行的 ORM 产品
      目前众多厂商和开源社区都提供了持久层框架的实现,常见的有:
      Apache OJB (http://db.apache.org/ojb/
      Cayenne (http://objectstyle.org/cayenne/
      Jaxor (http://jaxor.sourceforge.net
      Hibernate (http://www.hibernate.org
      iBatis (http://www.ibatis.com
      jRelationalFramework (http://ijf.sourceforge.net
      mirage (http://itor.cq2.org/en/oss/mirage/toon
      SMYLE (http://www.drjava.de/smyle
      TopLink (http://otn.oracle.com/products/ias/toplink/index.html
      其中 TopLink 是 Oracle 的商业产品,其他均为开源项目。
      其中 Hibernate 的轻量级 ORM 模型逐步确立了在 Java ORM 架构中领导地位,甚至取代复杂而又繁琐的 EJB 模型而成为事实上的 Java ORM 工业标准。而且其中的许多设计均被 J2EE 标准组织吸纳而成为最新 EJB 3.0 规范的标准,这也是开源项目影响工业领域标准的有力见证。

二、对象-关系映射模式
      从《公共仓库元模型:开发指南》一书第8章CWM元仓库中摘录出来的内容,实现了公共仓库元模型(CWM)的UML图到Microsoft SQL Server数据库的映射,是一种将对象层次结构映射成关系型结构的方法。个人认为可以作为将本体(Ontology)文件存储到关系型数据库中的一种可借鉴方法。
      基本情况:公共仓库元模型(CWM)是对象管理组织(OMG)的一种和数据仓库相关的元模型标准,采用UML表示的对象层次结构,在保存到数据库中时由于面向对象的数据库技术的不完善(理论研究和商业应用都不是主流),所以该书的作者倾向于使用成熟的关系型数据库来保存-这也是存储本体时所遇到的问题。
      采用方法:将UML模型中的各种元素通过转换,保存为数据库模式。由于CWM是一种元模型,因此模型的实例也是一种模型,将这种实例以数据库数据的形式保存。使用数据库中比较成熟的存储过程技术提高开发和执行效率。
      1、数据类型映射模式
      1.1简单数据类型模式:建立UML和关系型数据库中简单数据类型的映射表以指导映射。
      1.2枚举数据类型模式:每种枚举类型对应一个表,只有一个列(_EnumLiteral)表示枚举值。
      1.3基于类的数据类型模式:使用外键约束,将基础列与基于类的类型实例相关联。
      2、类映射模型
      每个类对应一个表。单值属性、多值属性、继承关系可以用下述方法映射,而引用属性将在关联映射模式中提到。
      2.1单值属性模式:是cardinality的上界为1的属性,映射到类所对应的表的列上。若其下界也为1(必须有的属性),列属性为NOT NULL。
      2.2多值属性模式:每个多值属性映射成一个独立的表,使用外键连接到类所对应的表上。
      2.3继承模式:每加入一个类的实例时,根据其继承关系自顶向下生成每个类的对象,这些对象具有相同的ID(根对象对应记录的主键)。删除对象实例时,自底向上删除数据。遇到从中间删的情况怎么办?多重继承怎么处理?(金龙飞)
    3、关联映射模式
      3.1一对一关联模式:在关联两端各加一列。
      3.2一对多关联模式:和3.1一样。如果多这端是有序的,还需加入一列表示序号。
      3.3多对多关联模式:将关联单独作一个表。
      3.4组合关联模式:注意级联式删除。
      3.5反演关联模式:关联两端指向相关的类型,和普通关联一样。
      3.6成对关联模式:关联记录两个类间的关系,用交集类表示关联,表示成一个单独的表,每个关联对应一个表,用外键表示它们间的关系。
      3.7关联上的OCL需要分析成对应的存储过程代码。
      3.8保证关联的cardinality也需要分析成对应的存储过程代码。
      4、引用映射模式
      在UML中不存在的MOF特征,指属性是声明为引用类型的实例。用存储过程实现。
 


smarteng 发布于 2010-1-10 01:56

Discuz!的Memcache缓存实现

前言:
在PHP+MySQL架构的站点中,本文重点从MySQL的角度去分析如何使Discuz!论坛(或者类似的PHP+MySQL架构的程序)应对大访问量。同时给出一些使用Memcache去减轻MySQL压力的建议。其中很多数据是个人测试的结果,如有不同意见,敬请留言告之。另外由于个人思维的问题,行文比较跳跃,特此声明!

系统分析:
单纯的从MySQL的角度出发,单台MySQL的数据库负载到每天上亿次的操作(每秒大概1100次MySQL操作,然后乘以86400)应该不是非常困难的事情。按照这个数据也就是说一个单MySQL服务器的论坛来说可以跑到2千万PV是不成问题的,我相信国内绝大部分的论坛都不可能做到每天2千万的 PV,但实际情况并不是如此。当论坛PV超过百万的时候一台WEB早已经不堪重负了。

就我手头的一些数据显示,目前的Discuz!论坛的基本服务器架构是前面Squid顶着,后面才是一台DB在撑着。这种架构中,web服务器压力增大可以通过并行增加服务器解决,而MySQL压力却无处释放,在不考虑MySQL官方服务的情况下,我们通过合理的利用Memcache是可以达到减轻 MySQL服务器负载的。

可能会有朋友说我们可以对数据表进行分表(注:此处分表是指通过PHP程序去分表,比如pw,dv的分表)处理,但是当前的情况是一台DB服务器已经不能支撑当前的数据处理了,通过PHP对MySQL进行的分表依然不能减轻MySQL的负载。(注:本段文字针对已经成型的系统,如果是独立开发的系统在架构前期就进行数据的同步分区还是不错的。)[break]

还可能有朋友会说利用MySQL的主从构架,如果你提出这个问题,我就很明确的告诉你,回去看看手册吧。在Mysql Master/Slave 模式中,Slave主要是来备份数据的,只有当Master出现故障时,Slave才会接过Master的服务,对外部请求进行处理,直到Master恢复正常。就是说:在Master/Slave中,要么是Master在服务,要么是Slave在服务,不会Master/Slave同时提供服务。使用MySQL主从依然不能有效的降低MySQL的负载。

或许你又会问我为什么不使用MySQL集群(MySQL Cluster),那可是白花花的银子啊,同等金钱的付出下,获得最大的收益才是王道。PS:说句题外话,MySQL手册中将MySQL集群解释为MySQL簇,不习惯。

其实在MySQL5.1中的MySQL分区(MySQL Partition)是个很好的东西,它允许根据可以设置为任意大小的规则,跨文件系统分配单个表的多个部分。实际上,表的不同部分在不同的位置被存储为单独的表。我认为这个才是当前情况下,最积极有效的降低MySQL负载的解决方法之一。但是遗憾的是,这种MySQL分区的方式我个人没有使用过的经历,也不见有相当充分的案例表明它是稳定的或者不稳定的。所以我还在徘徊中。如果你知道,请麻烦告之!有朋友说腾讯是在用MySQL分区,但是遗憾的是我没有得到确切的数据。

好了分析总结了这么多种降低MySQL负载的方式之后,在用户环境需求等特定条件下,我得出结论在当前情况下,缓解Discuz!论坛的MySQL负载比较有效的方法就是使用Memcache!

使用Memcache的理由:
1.Web Server(Lighttpd、Nginx据说都比Apache效率高好多,大家可以试用下)对CPU要求高,对内存要求低;而Memcached Server是对CPU要求低,对内存要求高,所以可以搭配使用。在对前端的Web Server上安装Memcached Server是可行的。
2.金钱金钱金钱,最少的付出,获得最大的收益。
3.简单简单简单,对于一个架构合理的系统来说,添加Memcache的支持可能只是一个批量处理文件的过程

Discuz!使用Memcache
1.在config.inc.php中增加
$memcachehost = '127.0.0.1';
$memcacheport = 11211;
$memcachelife = 60;

2.在include/common.inc.php中
$mem = new Memcache;
$mem->connect($memcachehost, $memcacheport);

3.修改include/db_mysql.class.php中的fetch_array、query这两个方法,并添加query_mysql方法,代码如下:
function fetch_array($query, $result_type = MYSQL_ASSOC) {
return is_resource($query) ? mysql_fetch_array($query, $result_type) : $query[0];
}

function query_memcache($sql, $type = '') {
global $mem,$memcachelife;

$key = md5($sql);
if(!($query = $mem->get($key))) {
$query = $this->query($sql, $type);
while($item  = $this->fetch_array($query)) {
$res[] = $item;
}
$query = $res;
$mem->set($key, $query , 0, $memcachelife);
}
return $query;
}

function query($sql, $type = '') {
global $debug, $discuz_starttime, $sqldebug, $sqlspenttimes;

$func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ?
'mysql_unbuffered_query' : 'mysql_query';
if(!($query = $func($sql, $this->link)) && $type != 'SILENT') {
$this->halt('MySQL Query Error', $sql);
}

if(substr($sql, 0, 6) == 'SELECT') {
echo '<font color="red">Cache SQL</font>:<font color="green">'.$sql.'</font><br /><br />';
} else {
echo '<font color="red">Flash SQL</font>:<font color="green">'.$sql.'</font><br /><br />';
}

$this->querynum++;
return $query;
}

4.将需要使用Memcache缓存的SQL查询的代码由
$db->query(

修改为
$db->query_memcache(

注意并将
while($post = $db->fetch_array($query)) {

修改为
foreach($query as $post) {

没有while的$db->fetch_array可以不用修改。

下面代码有用得着的就拿去:
preg_replace("/while\([$](\w+)\s*\=\s*[$]db->fetch_array\([$]query\)\)/is", "foreach(\$query as \$\\1)", $file);

回头放出个小工具批量替换下就可以了。
在EditPlus中可以这样替换:while\([$](.*) = [$]db->fetch_array\([$]query\)\)替换为foreach($query as $\1)
5.完成了,测试吧!~
 


smarteng 发布于 2010-1-10 01:55

如何打造十页完美计划书

第一,用几句话清楚说明你发现目前市场中存在一个什么空白点,或者存在一个什么问题,以及这个问题有多严重,几句话就够了。很多人写了三百张纸,抄上一些 报告。投资人天天看这个,还需要你教育他吗?比如,现在网游市场里盗号严重,你有一个产品能解决这个问题,只需要一句话说清楚就可以。

第二,你有什么样的解决方案,或者什么样的产品,能够解决这个问题。你的方案或者产品是什么,提供了怎样的功能?
第三,你的产品将面对的用户群是哪些?一定要有一个用户群的划分。
第四,说明你的竞争力。为什么这件事情你能做,而别人不能做?是你有更多的免费带宽,还是存储可以不要钱?这只是个比方。否则如何这件事谁都能干,为什么 要投资给你?你有什么特别的核心竞争力?有什么与众不同的地方?所以,关键不在于所干事情的大小,而在于你能比别人干得好,与别人干得不一样。
第五,再论证一下这个市场有多大,你认为这个市场得未来是怎么样?
第六,说明你将如何挣钱?如果真的不知道怎么挣钱,你可以不说,可以老老实实地说,我不知道这个怎么挣钱,但是中国一亿用户会用,如果有一亿人用我觉得肯定有它的价值。想不清楚如何挣钱没有关系,投资人比你有经验,告诉他你的产品多有价值就行。
第七,再用简单的几句话告诉投资人,这个市场里有没有其他人在干,具体情况是怎样。不要说“我这个想法前无古人后无来者”这样的话,投资人一听这话就要打 个问号。有其他人在做同样的事不可怕,重要的是你能不能对这个产业和行业有一个基本了解和客观认识。要说实话、干实事,可以进行一些简单的优劣分析。
第八,突出自己的亮点。只要有一点比对方亮就行。刚出来的产品肯定有很多问题,说明你的优点在哪里。
第九,倒数第二张纸做财务分析,可以简单一些。不要预算未来三年挣多少钱,没人会信。说说未来一年或者六个月需要多少钱,用这些钱干什么?
第十,最后,如果别人还愿意听下去,介绍一下自己的团队,团队成员的优秀之处,以及自己做过什么。
一个包含以上内容的计划,就是一份非常好的商业计划书了。
 


smarteng 发布于 2010-1-10 01:55

快速统计日志文件里点击量前十位的URL

关于shell命令,网上流传着很多奇技淫巧,比如说快速统计日志文件里点击量前十位的URL: awk '{print $7}' /path/to/log | sort | uniq -c | sort -nr | head -n 10 附:这里假设日志文件是common格式的,如此一来,按空格分隔后,第七个字段就是URL 稍加思考,你会发现这里又是sort,又是uniq,存在重复操作,下面看看如何优化这条shell命令: 01 #!/bin/awk -f 02 03 { 04 url[$7]++ 05 } 06 07 END { 08 for (key in url) { 09 print url[key], key | "sort -nr | head -n 10" 10 } 11 } 把上面代码(去掉行号)保存到demo.awk文件里,然后:chmod +x ./demo.awk,做这些就够了。 我找了一个7G的common格式日志文件来测试性能,视服务器性能结果会有差异,但相对值应该差不多: time awk '{print $7}' /path/to/log | sort | uniq -c | sort -nr | head -n 10 real 1m57.150s user 1m6.794s sys 0m13.923s time ./demo.awk /path/to/log real 1m21.414s user 0m32.799s sys 0m22.556s 总体消耗的时间降低了四分之一,还是很明显的。


smarteng 发布于 2010-1-10 01:54

inotify + rsync实现linux文件实时同步

一、介绍
Inotify 是文件系统事件监控机制,作为 dnotify 的有效替代。dnotify 是较早内核支持的文件监控机制。Inotify 是一种强大的、细粒度的、异步的机制,它满足各种各样的文件监控需要,不仅限于安全和性能。

inotify 可以监视的文件系统事件包括:
IN_ACCESS,即文件被访问
IN_MODIFY,文件被 write
IN_ATTRIB,文件属性被修改,如 chmod、chown、touch 等
IN_CLOSE_WRITE,可写文件被 close
IN_CLOSE_NOWRITE,不可写文件被 close
IN_OPEN,文件被 open
IN_MOVED_FROM,文件被移走,如 mv
IN_MOVED_TO,文件被移来,如 mv、cp
IN_CREATE,创建新文件
IN_DELETE,文件被删除,如 rm
IN_DELETE_SELF,自删除,即一个可执行文件在执行时删除自己
IN_MOVE_SELF,自移动,即一个可执行文件在执行时移动自己
IN_UNMOUNT,宿主文件系统被 umount
IN_CLOSE,文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
IN_MOVE,文件被移动,等同于(IN_MOVED_FROM | IN_MOVED_TO)
注:上面所说的文件也包括目录。 [break]

二、为能在shell下使用inotify特性,需要安装inotify-tools
1、inotify-tools:The general purpose of this package is to allow inotify's features to be used from within shell scripts.
下载地址:http://inotify-tools.sourceforge.net/
编译安装
./configure
make
make install
完成后,注意查看manpage,man inotify 、 man inotifywait
inotifywait 仅执行阻塞,等待 inotify 事件。您可以监控任何一组文件和目录,或监控整个目录树(目录、子目录、子目录的子目录等等)。在 shell 脚本中使用 inotifywait。
inotifywatch 收集关于被监视的文件系统的统计数据,包括每个 inotify 事件发生多少次。
2、inotify的系统相关参数:
 /proc interfaces
       The following interfaces can be used to limit the amount of kernel memory consumed by inotify:

      /proc/sys/fs/inotify/max_queued_events
              The value in this file is used when an application calls inotify_init(2) to set an upper  limit  on  the number  of  events  that  can be queued to the corresponding inotify instance.  Events in excess of this limit are dropped, but an IN_Q_OVERFLOW event is always generated.
      /proc/sys/fs/inotify/max_user_instances
              This specifies an upper limit on the number of inotify instances that can be created per real user ID.
      /proc/sys/fs/inotify/max_user_watches
              This specifies a limit on the number of watches that can be associated with each inotify instance.

3、inotifywait 相关的参数(更多,查看manpage):
inotifywait
This command simply blocks for inotify events, making it appropriate for use in shell scripts. It can watch any set of files and directories, and can recursively watch entire directory trees.
-m, --monitor
              Instead  of  exiting  after receiving a single event, execute indefinitely.  The default behaviour is to exit after the first event occurs.
-r, --recursive
              Watch all subdirectories of any directories passed as arguments.  Watches will be set up recursively  to an  unlimited  depth.   Symbolic  links  are  not


traversed.  Newly created subdirectories will also be watched.
-q, --quiet
              If specified once, the program will be less verbose.  Specifically, it will not state when it  has  completed establishing all inotify watches.
 -e <event>, --event <event>
              Listen for specific event(s) only.  The events which can be listened for are listed in the  EVENTS  section.  This option can be specified more than once.  If omitted, all events are listened for. use“,”separate multi events

三、使用
1.查看是否支持inotify,从kernel 2.6.13开始正式并入内核,RHEL5已经支持。
看看是否有 /proc/sys/fs/inotify/目录,以确定内核是否支持inotify
[root@RHEL5 Rsync]# ll /proc/sys/fs/inotify
total 0
-rw-r--r-- 1 root root 0 Oct  9 09:36 max_queued_events
-rw-r--r-- 1 root root 0 Oct  9 09:36 max_user_instances
-rw-r--r-- 1 root root 0 Oct  9 09:36 max_user_watches

2.关于递归:
inotifywait
This command simply blocks for inotify events, making it appropriate for use in shell scripts. It can watch any set of files and directories, and can recursively watch entire directory trees.

3.使用:
#!/bin/sh
src=/opt/webmail
des=/tmp
ip=192.168.7.192

/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format  '%T %w%f' \
 -e modify,delete,create,attrib \
${src} \
| while read  file
        do
                rsync -avz --delete --progress ${src} root@${ip}:${des} &&
                echo "${src} was rsynced"
                echo "---------------------------------------------------------------------------"
        done
注:
当要排出同步某个目录时,为rsync添加--exculde=PATTERN参数,注意,路径是相对路径。详细查看man rsync
当要排除都某个目录的事件监控的处理时,为inotifywait添加--exclude或--excludei参数。详细查看man inotifywait

另:
/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format  '%T %w%f' \
 -e modify,delete,create,attrib \
${src} \
上面的命令返回的值类似于:
10/03/09 15:31 /wwwpic/1

这3个返回值做为参数传给read,关于此处,有人是这样写的:
inotifywait -mrq -e create,move,delete,modify $SRC | while read D E F;do

细化了返回值。
注:要取得监控文件发生的事件,在--format处指定%e参数,同时,使用--event参数来指定要监控的事件即可,如--format  '%T %w%f %e' --event modify,delete,create,attrib

说明: 当文件系统发现指定目录下有如上的条件的时候就触发相应的指令,是一种主动告之的而非我用循环比较目录下的文件的异动,该程序在运行时,更改目录内的文件时系统内核会发送一个信号,这个信号会触发运行rsync命令,这时会同步源目录和目标目录。
--timefmt:指定输出时的输出格式
   --format:  '%T %w%f'指定输出的格式,上面的输出类似于:12/10/08 06:34 /opt/webmail/dovecot-1.1.2/src/test/1

小脚本,同步到多台主机:
更改后,更简单,适用于同步到相同的目录,监控多目录,多文件,同步到多台服务器

#!/bin/sh

#set -x
#var

src="/usr/local/nginx/html/lib /usr/local/nginx/html/www /usr/local/nginx/html/var/www.work.com.conf.php"

des_ip="172.18.1.35 172.18.1.36 172.18.1.37 172.18.1.38"

#function

inotify_fun ()

{

/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y-%H:%M' --format '%T %w%f' \

-e modify,delete,create,move $1|while read time file

do

for ip in $des_ip

do

echo "`date +%Y%m%d-%T`: rsync -avzq --delete --progress $1 $ip:`dirname $1`"

rsync -avzq --delete --progress $1 $ip:`dirname $1`

echo

done

done

}

#main

for a in $src

do

inotify_fun $a &

done
 


smarteng 发布于 2010-1-10 01:54

用SecureCRT上传和下载文件

简要介绍:

  VanDyke CRT 和 VanDyke SecureCRT是最常用的终端仿真程序,简单的说就是windows下登录UNIX或Liunx服务器主机的软件。二者不同的是SecureCRT支持SSH∗(SSH1和SSH2)。


SecureCRT可以使用linux下的zmodem协议来快速的传送文件,而且还使用非常方便。

你只要设置一下上传和下载的默认目录就行:
打开options–>session options–>file transfer,设置上传和下载的目录 。

剩下的你只要在用SecureCRT登陆linux终端的时候:
1)发送文件到客户端:
sz filename
zmodem接收可以自行启动.
2)从客户端上传文件到linux服务端,只要服务端执行:
rz
然后在 SecureCRT 里选文件发送,协议zmodem。

如果你以前一直使用ssh,而又没有对外开放ftp服务,你就可以直接使用这种方式来传输文件。
例如:
1、将linux上文件传到PC机上
shell> sz  /etc/rc.local
例:
[root@test root]# sz /etc/rc.local
rz
Starting zmodem transfer.  Press Ctrl+C to cancel.
Transferring rc.local...
100%     464 bytes  464 bytes/s 00:00:01       0 Errors
2、将PC机上文件传到linux上
shell> rz
选择要传送的文件,确定。


smarteng 发布于 2010-1-10 01:53

企业注册流程

你要想开公司,就得明白这些呀,中国的注册流程还是很复杂的,感谢这位好心人,都整理好了,

哈哈,我们就慢慢享用吧,这是一篇介绍企业注册流程的文章。


smarteng 发布于 2010-1-10 01:52

博主

    blogger

    smarteng

    人生就流星,虽然转瞬即逝,但也有永恒。

日历

恰饭

标签