楼主: yulihua49

[PRO*C] 看我做的数据库包装器

[复制链接]
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
191#
 楼主| 发表于 2009-1-22 09:54 | 只看该作者
原帖由 jjgwolf 于 2009-1-22 09:42 发表
呵呵,我会C语言!但是早就忘光了

是啊,现在都用JAVA了,在高密度,高并发,高冲突的事务处理,还是C的地盘。
最近已经证实,基于多进程的C程序,在一定条件下其开销和响应时间是线性增长的,这点是比JAVA优越之处。
条件是,系统不发生大规模的对换,并发进程间没有资源共享、互斥和通信。
因此我们的方案是C服务器+JAVA客户端。
C客户端与JAVA客户端同台竞速,JAVA还是要肉一些的。
但是JAVA的开发成本不及C的1/3,是无可比拟的优势。
两种语言也可以互相借鉴,比如这个DAU,就是借鉴了Hibernate技术。

[ 本帖最后由 yulihua49 于 2009-1-22 10:06 编辑 ]

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
192#
 楼主| 发表于 2009-1-22 13:58 | 只看该作者

回复 #195 yulihua49 的帖子

给一个实际程序吧,根据班次表,JOIN  devname的:

JSON_OBJECT get_shift(T_SQL_Connect *SQL_Connect,char *msg)
{
int ret;
DAU u_DAU[2];
JSON_OBJECT result,json;

        result=json_object_new_array();
        ret=DAU_init(&u_DAU[0],SQL_Connect,"dev_shift a",0,0);//从数据库中找表结构
        ret=DAU_init(&u_DAU[1],SQL_Connect,"tuxdev b",0,0);
        sprintf(msg,"WHERE a.devid=b.devid");
        ret=DAU_getm(2,u_DAU,msg,0);
        while(!DAU_nextm(2,u_DAU)) {
                json=json_object_new_object();
                DAU_toJSON(&u_DAU[0],json,0);//user全部打包到json
                DAU_toJSON(&u_DAU[1],json,"devname");//组合devname到json
                json_object_array_add(result,json);//在JSON数组中加入一条记录
        }
        DAU_freem(2,u_DAU);
        return result;
}

int loadfile(T_SQL_Connect *SQL_Connect,char *tablename,FILE *ifd,FILE *ofd,int Pflg,char *buf,int buflen)
{
JSON_OBJECT result;

        result=get_shift(SQL_Connect,buf);
        printf("buf=%s\n",buf);
        printf("result=%s\n",json_object_to_json_string(result));
        json_object_put(result);
        return 0;
}

执行结果:

buf=SELECT  a.devid,to_char(a.stat_date,'YYYY-MM-DD') stat_date,a.shift_flg,a.shift_code,a.userid,to_char(a.log_time,'YYYY-MM-DD HH24:MI:SS') log_time,a.beg_no,b.devid,b.devname,b.devtype,b.devca,b.unit,b.atime,b.ptime,b.perm,b.purpose1,b.purpose2,b.purpose3,b.purpose4,b.purpose5,b.purpose6,b.purpose7,b.purpose8,b.clid,to_char(b.last_log,'YYYY-MM-DD HH24:MI:SS') last_log,b.flag FROM TICKET.dev_shift a,TICKET.tuxdev b WHERE a.devid=b.devid

result=[ { "devid": "JOLTTEST", "stat_date": "2008-10-20", "shift_flg": "BB", "shift_code": "5", "userid": "hp", "log_time": "2008-10-20 14:44:34", "beg_no": "A0000001", "devname": "JOLT测试终端" }, { "devid": "JOLTTEST1", "stat_date": "2008-11-06", "shift_flg": "AB", "shift_code": "5", "userid": "hww", "log_time": "2008-11-06 16:12:26", "beg_no": "A0000001", "devname": "黄伟伟的JOLT测试终端" }, { "devid": "SP0102002", "stat_date": "2009-01-20", "shift_flg": "DB", "shift_code": "5", "userid": "ylh", "log_time": "2009-01-20 13:54:03", "beg_no": "A0000001", "devname": "售票测试终端2" }, { "devid": "SP0102003", "stat_date": "2008-10-16", "shift_flg": "DB", "shift_code": "5", "userid": "", "log_time": "2008-10-16 10:14:53", "beg_no": "A0000001", "devname": "售票测试终端3" } ]

初看Hibernate程序也是这样,好像什么也没干,结果什么都做完了。这就是框架的好处,程序非常简练易懂,对具体数据结构不敏感。
这里只涉及了devid,devname。只要这两个字段不改,其他增加一些,改变一些,与本程序无关。系统要求,将来数据结构变更,程序要少改或不改,PL/SQL很难实现这个要求。
DAU实际上比Hibernate要好用。Hibernate无论如何需要一个POJO,不可能完全动态处理数据。上边的程序和前边的load程序都没有定义任何数据结构,运行结果完全取决于数据库当时的状况。实现了完全动态处理。

[ 本帖最后由 yulihua49 于 2009-1-22 15:28 编辑 ]

使用道具 举报

回复
论坛徽章:
3
2009新春纪念徽章
日期:2009-01-04 14:52:28设计板块每日发贴之星
日期:2009-01-23 01:01:09设计板块每日发贴之星
日期:2009-03-17 01:01:05
193#
发表于 2009-1-22 15:16 | 只看该作者
建议给 yulihua 和newkid 两位都各算一篇精华帖——可能的话哈!
缺了谁这帖子都不可能这么精彩
抛开两人的观点不谈,就这执着、深入钻研的精神让我信服和钦佩!

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
194#
 楼主| 发表于 2009-1-22 15:21 | 只看该作者
原帖由 CS-IM 于 2009-1-22 15:16 发表
建议给 yulihua 和newkid 两位都各算一篇精华帖——可能的话哈!
缺了谁这帖子都不可能这么精彩
抛开两人的观点不谈,就这执着、深入钻研的精神让我信服和钦佩!

谢谢捧场,节日快乐。

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
195#
发表于 2009-1-23 00:59 | 只看该作者
把你的代码对齐一下:

if(SQL_Connect->Errno == DUPKEY) {
        if(!Pflg) {//如果没有-P选项,这很快
                ret=updaterec(&_DAU,buf);
                if(ret==0) upd+=1;
                else loss++;
                  }
        else loss++; // 我认为你的第二种即insert - DUPKEY - LOSS应该执行到这里,为什么会跑到下面去?
       }
else {//这很慢,不必怀疑下面几句,其开销可以忽略不计。// 那么全部注释掉,会花多少时间?
        DAU_pack(&_DAU,buf);
        fprintf(ofd,"%s\n",buf);
        ShowLog(1,"loadfile:%s",buf);
        loss++;
     }
rows--;
continue;

再来看你的连接例子。DAU_getm里面肯定有循环,把数据拆成了两个集合;然后你又while(!DAU_nextm(2,u_DAU)) 来了一个循环,再把数据合并。如此分分合合累不累啊?再说,其实B表里面只需要一个devname,你自动生成的SQL却全部列都选出来了。前几天才有一本书说到这个问题:
http://www.itpub.net/viewthread. ... p;extra=&page=3
看#26。

再来看你引以为荣的“没有定义任何数据结构,运行结果完全取决于数据库当时的状况。”
你实际上依赖系统字典,但是很多情况下SQL不是单纯的取列数据。要是每个查询都是SELECT *, 那么PL/SQL也可以做到少改或不改。常见的分组操作(聚合函数),子查询,……,这些情况下你就不得不手工写SQL和模板了。因此你这种包装方法局限性很大,如果要真正高效利用数据库的性能,写高性能的SQL, 这个包装器就显得碍手碍脚,最佳做法是把SQL放到存储过程中。客户程序按行,列读取一个结果集是很方便的,不一定要映射到结构中。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
196#
 楼主| 发表于 2009-1-23 09:25 | 只看该作者
原帖由 newkid 于 2009-1-23 00:59 发表
再来看你的连接例子。DAU_getm里面肯定有循环,把数据拆成了两个集合;然后你又while(!DAU_nextm(2,u_DAU)) 来了一个循环,再把数据合并。如此分分合合累不累啊?再说,其实B表里面只需要一个devname,你自动生成的SQL却全部列都选出来了。前几天才有一本书说到这个问题:
http://www.itpub.net/viewthread. ... p;extra=&page=3
看#26。

再来看你引以为荣的“没有定义任何数据结构,运行结果完全取决于数据库当时的状况。”
你实际上依赖系统字典,但是很多情况下SQL不是单纯的取列数据。要是每个查询都是SELECT *, 那么PL/SQL也可以做到少改或不改。常见的分组操作(聚合函数),子查询,……,这些情况下你就不得不手工写SQL和模板了。因此你这种包装方法局限性很大,如果要真正高效利用数据库的性能,写高性能的SQL, 这个包装器就显得碍手碍脚,最佳做法是把SQL放到存储过程中。客户程序按行,列读取一个结果集是很方便的,不一定要映射到结构中。


框架内部如何复杂没有关系,使用简单就行。Hebernate内部极其复杂,使用非常简单。

你即便select *,还是要into吧?那个into很麻烦的。当然也可以写动态语句,那很费事易错,来个公用函数吧,就成了sqlora,想把结果集打成通信包吗?就成了DAU。
select *每次都要处理,DAU只init一次,以后反复用。如果想省时间,可以固定模板啊,固定模板是事先自动生成的,也不用手写。应用当然不是这个简单例子,会有许多复杂逻辑,DAU简化了你的编程,使你快速产生大量程序,因此,越是复杂的应用逻辑,DAU的价值越高。尤其那些生手,DAU可以使他们快速入门。

看一个自动生成的例子:
tuxticket@jgbticket:~/test> mkpatt.sh
输入表名: dev_shift

T_PkgType DEV_SHIFT_tpl[]={
        {CH_CHAR,17,"devid",0,-1},
        {CH_JUL,sizeof(INT4),"stat_date",YEAR_TO_DAY},
        {CH_CHAR,3,"shift_flg"},
        {CH_TINY,1,"shift_code"},
        {CH_CHAR,17,"userid"},
        {CH_TIME,sizeof(INT64),"log_time",YEAR_TO_SEC},
        {CH_CHAR,9,"beg_no"},
        {-1,0,0,0}
};

extern T_PkgType DEV_SHIFT_tpl[];
typedef struct {
        char devid[17];
        INT4 stat_date;
        char shift_flg[3];
        char shift_code;
        char userid[17];
        INT64 log_time;
        char beg_no[9];
} DEV_SHIFT_stu;

[ 本帖最后由 yulihua49 于 2009-1-23 10:41 编辑 ]

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
197#
 楼主| 发表于 2009-1-23 10:07 | 只看该作者
原帖由 newkid 于 2009-1-23 00:59 发表

再说,其实B表里面只需要一个devname,你自动生成的SQL却全部列都选出来了。前几天才有一本书说到这个问题:


这样行了吧:

JSON_OBJECT get_shift(T_SQL_Connect *SQL_Connect,char *msg)
{
int ret;
DAU u_DAU[2],tdev_DAU;
JSON_OBJECT result,json;
T_PkgType tdev_tpl[2]; //想选几个字段n+1

        result=json_object_new_array();
        ret=DAU_init(&tdev_DAU,SQL_Connect,"tuxdev",0,0);
        partt_copy(tdev_tpl,tdev_DAU.srm.tp,"devname"); //生成子模板,想选几个字段用,分割列表
        ret=DAU_init(&u_DAU[0],SQL_Connect,"dev_shift a",0,0);
        DAU_init(&u_DAU[1],SQL_Connect,"tuxdev b",tdev_DAU.srm.rec,tdev_tpl);
        sprintf(msg,"WHERE a.devid=b.devid");
        ret=DAU_getm(2,u_DAU,msg,0);
        while(!DAU_nextm(2,u_DAU)) {
                json=json_object_new_object();
                DAU_toJSON(&u_DAU[0],json,0);//user全部打包到json
                DAU_toJSON(&u_DAU[1],json,"devname");//组合dev_name到json
                json_object_array_add(result,json);//在JSON数组中加入一条记录
        }
        DAU_freem(2,u_DAU);
        DAU_free(&tdev_DAU);
        return result;
}

执行结果:

buf=SELECT  a.devid,to_char(a.stat_date,'YYYY-MM-DD') stat_date,a.shift_flg,a.shift_code,a.userid,to_char(a.log_time,'YYYY-MM-DD HH24:MI:SS') log_time,a.beg_no,b.devname FROM TICKET.dev_shift a,TICKET.tuxdev b WHERE a.devid=b.devid

result=[ { "devid": "JOLTTEST", "stat_date": "2008-10-20", "shift_flg": "BB", "shift_code": "5", "userid": "hp", "log_time": "2008-10-20 14:44:34", "beg_no": "A0000001", "devname": "JOLT测试终端" }, { "devid": "JOLTTEST1", "stat_date": "2008-11-06", "shift_flg": "AB", "shift_code": "5", "userid": "hww", "log_time": "2008-11-06 16:12:26", "beg_no": "A0000001", "devname": "黄伟伟的JOLT测试终端" }, { "devid": "SP0102002", "stat_date": "2009-01-20", "shift_flg": "DB", "shift_code": "5", "userid": "ylh", "log_time": "2009-01-20 13:54:03", "beg_no": "A0000001", "devname": "售票测试终端2" }, { "devid": "SP0102003", "stat_date": "2008-10-16", "shift_flg": "DB", "shift_code": "5", "userid": "", "log_time": "2008-10-16 10:14:53", "beg_no": "A0000001", "devname": "售票测试终端3" } ]

[ 本帖最后由 yulihua49 于 2009-1-23 10:16 编辑 ]

使用道具 举报

回复
论坛徽章:
3
2009新春纪念徽章
日期:2009-01-04 14:52:28设计板块每日发贴之星
日期:2009-01-23 01:01:09设计板块每日发贴之星
日期:2009-03-17 01:01:05
198#
发表于 2009-1-23 14:46 | 只看该作者
两位仁兄春节快乐!

个人觉得yulihua49和newkid两位老兄的观点不应该有根本的对立点,这就好比一个漂亮的女人穿吊带就蛮好看,yulihua49不过给人家加了一件不错的马甲(说不准还是那个“可恶”的老板强迫的),“错”就“错”在yulihua49兄不但把地摊摆错地方(这坛子里大多是色狼,偶也不例外了 ),还时不时“指责”女人太暴露不太雅。没想到newkid老兄在多伦多性感女人见得多了去啦,自然老大不爽啦,于是乎------
后来,乐见yulihua49兄也不再那么“保守”,newkid兄偶尔也还帮着缝缝纽扣着着色啥的------
再后来? -----期待ING

至于吊带好看还是马甲好看,自然是仁者见仁、智者见智了

[ 本帖最后由 CS-IM 于 2009-1-23 22:57 编辑 ]

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
199#
 楼主| 发表于 2009-1-23 17:49 | 只看该作者
原帖由 CS-IM 于 2009-1-23 14:46 发表
两位仁兄春节快乐!

个人觉得yulihua49和newkid两位老兄的观点不应该有根本的对立点,这就好比一个漂亮的女人穿吊带就蛮好看,yulihua49不过给人家加了一件不错的马甲(说不准还是那个“可恶”的老板强迫的),“错”就“错”在yulihua49兄不但把地摊摆错地方(这坛子里大多是色狼,偶也不例外了 ),还时不时“指责”女人太暴露不太雅。没想到newkid老兄在多伦多性感女人见得多了去啦,自然老大不爽啦,于是乎------
后来,乐见yulihua49兄也不再那么“保守”,newkid兄偶尔也还帮着缝缝纽扣着着色啥的------
再后来? -----也该剧终了罢

至于吊带好看还是马甲好看,自然是仁者见仁、智者见智了

是这个意思。现在人们都喜欢裸女,长老会不让。
我上边的例子还是露个WHERE小脸的,那也不行,必须蒙上DAO面纱。
其实也没有太合适的场所。C语言那边多半不玩数据库,也就是弄点怪异语句应付考试的,谁搞一些实用的东西呢?
况且只做了ORACLE数据库的,放在别处也不合适。
站在C程序员的角度,觉得这个东西很好,大大简化了访问数据库的过程。也就是十几年时间吧,这领域基本让JAVA占领了,我们的情况不得不,必须使用C语言,提出必须使用框架,象JAVA那样,一点见不到数据库。我研究了Hibernate,说没问题。在此之前,确实未见到类似产品,应该在C领域是个重要发展。现在我们这里已经认可了这个方案,但仅限于OLTP,OLAP那边是不用的,newkid所说的复杂SQL在OLTP很少使用。
DAU的用途在于对数据结构敏感度低(与数据表结构的松耦合),降低开发、维护成本。对于实现老手的精致构思,DAU可能力不从心,对于生手来说,确可以产生不算太差的语句,系统的整体性能不会太差,也可能相当优秀,看你怎么用。
有点象自动档车,老车手对之嗤之以鼻。
我当然它希望能更广泛的应用。非常遗憾的是这个坛子参与这个领域的太少,好像真的没有这方面需求。

[ 本帖最后由 yulihua49 于 2009-1-23 20:44 编辑 ]

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
200#
 楼主| 发表于 2009-1-23 20:50 | 只看该作者
原帖由 newkid 于 2009-1-23 00:59 发表
把你的代码对齐一下:

if(SQL_Connect->Errno == DUPKEY) {
        if(!Pflg) {//如果没有-P选项,这很快
                ret=updaterec(&_DAU,buf);
                if(ret==0) upd+=1;
                else loss++;
                  }
        else loss++; // 我认为你的第二种即insert - DUPKEY - LOSS应该执行到这里,为什么会跑到下面去?
       }
else {//这很慢,不必怀疑下面几句,其开销可以忽略不计。// 那么全部注释掉,会花多少时间?
        DAU_pack(&_DAU,buf);
        fprintf(ofd,"%s\n",buf);
        ShowLog(1,"loadfile:%s",buf);
        loss++;
     }
rows--;
continue;

再来看你的连接例子。DAU_getm里面肯定有循环,把数据拆成了两个集合;然后你又while(!DAU_nextm(2,u_DAU)) 来了一个循环,再把数据合并。如此分分合合累不累啊?再说,其实B表里面只需要一个devname,你自动生成的SQL却全部列都选出来了。前几天才有一本书说到这个问题:
http://www.itpub.net/viewthread. ... p;extra=&page=3
看#26。

再来看你引以为荣的“没有定义任何数据结构,运行结果完全取决于数据库当时的状况。”
你实际上依赖系统字典,但是很多情况下SQL不是单纯的取列数据。要是每个查询都是SELECT *, 那么PL/SQL也可以做到少改或不改。常见的分组操作(聚合函数),子查询,……,这些情况下你就不得不手工写SQL和模板了。因此你这种包装方法局限性很大,如果要真正高效利用数据库的性能,写高性能的SQL, 这个包装器就显得碍手碍脚,最佳做法是把SQL放到存储过程中。客户程序按行,列读取一个结果集是很方便的,不一定要映射到结构中。

对不起,注释搞错了。
ret=insrec(&_DAU,buf);
                if(ret) {
                        if(SQL_Connect->Errno == DUPKEY) {
                                if(!Pflg) {//如果没有-P选项,这很快
                                        ret=updaterec(&_DAU,buf);
                                        if(ret==0) upd+=1;
                                        else loss++;
                                }
                                else loss++;//这很慢。
                 } else { // 其它错误
                                DAU_pack(&_DAU,buf);
                                fprintf(ofd,"%s\n",buf);
                                ShowLog(1,"loadfile:%s",buf);
                                loss++;
                        }
                        rows--;
                        continue;
                }

[ 本帖最后由 yulihua49 于 2009-1-23 20:52 编辑 ]

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表