编译asp.net 2.0项目到dll文件

Asp.net不是asp的简单升级,而是微软.Net计划中的一个重要组成部分,它依托.Net的多语言与强大的类库支持,引进了服务端 HTML控件与WEB控件,自动处理控件的客户端与服务端的 交互,为开发人员提供了类似Windows下窗口编程的界面,为开发大型网络应用程序功能提 供了良好的编程接口,也能够极大地提高开发人员的工作效率。

然而,"一次转换,两次编译"过程使得aspx文件在首次执行(或更 新后首次运行)时显得略有不足,特别是在拥有大量aspx及codebehind的代码文件的应用环境中,把aspx文件编译成DLL(在.Net中,被 称为应用程序集)后再发布,省去"一次转换、一次编译"的时间及CPU占用率,对提高WEB服务的整体性能会有较大的提升。当然,编译成DLL后,对源代 码的保密性也有一定程度的提高。

本文通过对Asp.Net的基本处理流程及一个偶然发现的秘密的分析,介绍了在Asp.Net中 如何建立aspx到DLL的映射,如何开发一个可以处理HTTP请求/响应的DLL,以及如何设置"陷阱",把现成的单个aspx文件与 codebehind的aspx文件编译成DLL的过程,文章最后,还介绍了一个在实际操作过程的小技巧。

由于本文要涉及Asp.Net应用程序、命令行编译、web.config配置文件等概念,为了使读者能更好地理解本文内容,也为了使本文看上去不显累赘,先就本文相对应的系统环境作一介绍:

系统环境:
Win2000(SP3)+ IIS5 + .Net Framework 1.0(中文版)。
服务器名称:
由于本文的例子均在本机上测试,服务器名称为localhost
IIS设置:
建立虚拟目录dlltest(真实路径为w:/wwwroot/dlltest),并把它设为应用程序,在dlltest下建立bin目录。所有源文件将放在dlltest目录下,而所有dll文件将放在dlltest/bin目录下。

Asp.Net应用程序配置文件--web.config
在dlltest目录下建立一个web.config文件,初始时该文件内容如下:

<?xml version="1.0"?>
<configuration>
<system.web />
</configuration>

命令窗口(DOS窗口)
打开命令窗口,并用cd命令使当前目录为w:/wwwroot/dlltest。

(一)建立aspxdll的映射

首先让我们来看看一般情况下aspx文件是如何被Asp.Net处理的:

当一个HTTP请求(例如"http://webserver/webapp/webpage.aspx") 从客户端发送到IIS服务器时,IIS捕获并分析这个请求,

è当它分析到这个请求是一个aspx页面时,立即以 "/webapp/webpage.aspx"为参数调用Asp.Net运行环境(aspnet_wp.exe),

èAsp.Net环境启动后,检查 "/webapp/webpage.aspx"是否存在,若不存在,则向客户端返回HTTP 404(File not found)错误,

è否则在 Asp.Net 的临时目录中查找相应的dll文件,若不存在或者该dll比aspx源文件"旧",则调用csc编译器(若aspx的服务端脚本语言是 VB或JScript,则调用相应的vbc编译器, jsc编译器)把aspx文件编译成dll,

è然后Asp.Net再调用该dll来处理具体的客户请 求,返回服务器响应。

从这个处理流程可以看出,一般情况下,Asp.Net运行环境会自动识别、检查、更新与aspx相对应的 dll。那么有没有其它办法可以强制把对一个aspx文件的处理"路由"到一个已编译存在的DLL呢?方法就是在Asp.Net应用程序配置文件 web.configsystem.web节的httpHandlers节添加aspxdll的映射项,语法如下:

<add verb="*" path="aspx文件名" type="类名,dll文件" />
aspx文件:需要被"路由"的虚拟名称,扩展名必须是aspx,否则IIS会先于Asp.Net运行环境处理该文件。
dll文件: dll文件(应用程序集)的名称,不必输入".dll"。ASP.NET 首先在应用程序的专用 /bin 目录中搜索程序集 DLL,然后在系统程序集缓存中搜索程序集 DLL。
类名: 由于一个dll可能会有多个名称空间或多个类,因此必须指明当dll调用时自动加载哪个类。

例如,某一Asp.Net应用程序的web.config文件如下:

<?xml version="1.0"?>
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="index.aspx" type="BBS.IndexPage, bbs" />
</httpHandlers>
</system.web>
</configuration>

该配置文件告诉Asp.Net,在客户端请求本应用程序的index.aspx文件时,直接调用应用程序bin目录下的bbs.dll,并自动加载其中的BBS.IndexPage类。

(二)开发能处理HTML页面的DLL

应该指出的是,并不是所有的应用程序集DLL都能实现HTTP请求/响应模式。还是来看一下Microsoft Asp.Net快速入门教程(http://chs.gotdotnet.com/quickstart/aspplus/)中关于"Http 处理程序和工厂"的描述:

ASP.NET  提供低级别的请求/响应 API,使开发人员能够使用 .NET 框架类为传入的 HTTP 请求提供服务。为此,开发人员需创作支持  System.Web.IHTTPHandler 接口和实现 ProcessRequest() 方法的类。当处理 HTTP 请求不需要由高级别的 页框架抽象化提供的服务时,处理程序通常很有用。处理程序的常用用途包括筛选器和类似 CGI 的应用程序,尤其是那些返回二进制数据的应用程序。

ASP.NET  收到的每个传入 HTTP 请求最终由实现 IHTTPHandler 的类的特定实例来处理。IHttpHandlerFactory 提供了处理  IHttpHandler 实例 URL 请求的实际解析的结构。除了 ASP.NET 提供的默认 IHttpHandlerFactory 类外, 开发人员还可以选择创建和注册工厂以支持大量的请求解析和激活方案。

从这段文字可以看出,当aspx页面不涉及.net框架提 供的高级界面技术(如数据缓存、状态保持、Web窗体控件引用等等)时,且向客户端输出的不是复杂的HTML文本,特别是只向客户端返回二进制数据(如图 片,声音等)时,可以用一个.cs应用程序文件(本文使用c#语言,如果是用VBJScript...)来替代,而该应用程序必须有一个实现 System.Web.IHTTPHandler 接口和并实现 ProcessRequest() 方法的类。一个简单的例子如下:

1
 2/**//* 源文件:ex1.cs 开始 */
 3using System.Web;
 4namespace DllTest
 5{
 6/**//*类必须实现IHttpHandler接口。如果程序将访问会话状态(Session),则必须实现 IRequiresSessionState 接口(不包含任何方法的标记接口)。*/
 7
 8
 9public class Ex1Page : IHttpHandler
10{
11/**//*IsReusable属性告诉.Net框架,本程序是否可以被多个线程同时使用。
12true对应是;false对应否。*/
13
14public bool IsReusable
15{
16get { return true; }
17} 
18
19
20
21/**//*实现ProcessRequest方法,向客户端返回响应数据。
22本例中向客户端返回一个简单的HTML页*/
23
24public void ProcessRequest(HttpContext context) 
25{
26HttpResponse res = context.Response;
27
28res.Write("<html><body>");
29res.Write("<h1>DllTest - Ex1(例1)</h1><hr>");
30res.Write("本页面直接由DLL处理");
31res.Write("</html></body>");
32}}}
33

/* 源文件:ex1.cs 结束 */
在命令行状态,用如下的编译命令把ex1.cs编译成ex1.dll,并把它存放在bin目录下。

csc /t:library /out:bin/ex1.dll ex1.cs
可以但要写全路径

csc /t:library /out:j:/WebSite/WebTest/bin/ex1.dll

J:/WebSite/WebTest/App_Code/ex1.cs

 

在配置文件web.config中添加aspx->dll映射,添加后,web.config应该是这样子的:

<?xml version="1.0"?>
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="dlltest1.aspx" type="DllTest.ex1Page,ex1" />
</httpHandlers>

</system.web>
</configuration>

现在当浏览器访问http://localhost/dlltest/dlltest1.aspx时,实际上就是调用了ex1.dll中DllTest.Ex1Page类的ProcessRequest方法,在浏览中应该可以看到一个简单的页面。

(三)把单个aspx文件编译成DLL

从 上一节微软公开描述的"言外之意"来看,微软是不支持让开发人员直接把aspx文件编译成DLL的。然而,Asp.Net高级界面技术(服务端HTML控 件,WEB控件等等)都是需要通过aspx文件才能展现出来的,如果为了DLL的运行效率而放弃aspx的高级特性,则显然是得不尝失的。

现在静下心来分析一下:
csc编译器只是一个c#语言的编译器,它只能对符合C#语言规范的文件进行编译,而aspx文件的格式显然不符合c#语言规范,所以csc编译器是无法对aspx源文件进行编译的。

此,要想把aspx文件编译成dll文件,必然要先把aspx文件转化成csc编译器能识别的cs源文件。那么用什么工具来进行转换呢?虽然我深信这个工 具一定是隐藏在.Net Framework里面,但在查阅了大量的Asp.Net及.Net的公开文档及参考手册,资料之后,仍找不到相关资料。

呵呵,天无绝人之路,一个偶然的机会,还是让我发现了这个秘密。
来看看源文件ex2.aspx:

/* 源文件:ex2.aspx 开始 */
<%@ Page Language="c#" %>
<script runat="server">
/**//*你没看错,下一行就是"abcdefg",正是这一行,才让我有机会写出本篇文章^_^;
在文中,我把这一行称作"代码陷阱"*/

abcdefg // 代码陷阱

void Page_Load(Object src, EventArgs args)
{
if( !IsPostBack ) NoteLabel.Text = "请输入您的姓名:";
}

void OnNameSubmit(Object src, EventArgs args)
{
string name = f_Name.Value;
NoteLabel.Text = (name=="") ? "姓名不能为空" : name +",您好。欢迎光临!";
}
</script>
<html>
<body>
<form runat="server">
<h1>DllTest - Ex2(例2)</h1>
<hr>
<asp:label runat="server" id="NoteLabel" style="color:red; font-weight:bold" />
<input runat="server" id="f_Name" size="8">
<button runat="server" onserverclick="OnNameSubmit">确定</button>
</form>
</body>
</html>

/* 源文件:ex2.aspx 结束 */

如果把"代码陷阱"注释掉或删掉,那么ex2.aspx就是一个简单的Asp.Net文件,

IE浏览此页面可以发现它能正常工作。

现在让我们打开"陷阱",来看看Asp.Net到底返回了什么?

回的是一个"编译错误"的页面,报告源文件无法通过编译。让我们感兴趣的是该页面最下方的一个名为"显示完整的编译源"的超链接,点击些链接,就能看到这 个由ex2.aspx转换而来的cs源文件("完整的编译源")的完整内容。把这部分"完整的编译源"去掉前面的行号信息和其它的一些编译开关(主要是 #line编译命令),并关闭那个可爱的"代码陷阱"(用//把它注释掉或直接把它delete也行),整理后保存为ex2_aspx.cs

/**//* 源文件:ex2_aspx.cs 开始 */

/**//*

从下面的说明可以看出,确实有一个未公开的工具来完成把aspx文件转化成cs源文件

*/

//------------------------------------------------------------------------------

// <autogenerated>

// This code was generated by a tool.

// Runtime Version:1.0.3705.0

//

// Changes to this file may cause incorrect behavior and will be lost if

// the code is regenerated.

// </autogenerated>

//------------------------------------------------------------------------------

/**//*

奇怪的是:命名空间居然是ASP而不是ASPX

建议把该名称改成适合应用程序的名称,防止命名冲突,例如针对本文,可以改成DllTest

这里没改是为了让大家看清它的原貌

*/

namespace ASP

{

using System;

using System.Collections;

using System.Collections.Specialized;

using System.Configuration;

using System.Text;

using System.Text.RegularExpressions;

using System.Web;

using System.Web.Caching;

using System.Web.SessionState;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

/**//*

1、注意一下类名的构成,如果必要,可以把它改成有意义的名称,例如针对本文,可以改成Ex2Page

2、注意它的基类。Syste.Web.UI.Page实现了IHttpHandler接口,由于要访问Session,所以也实现了IRequiresSessionState接口。

*/

public class ex2_aspx : System.Web.UI.Page, System.Web.SessionState.IRequiresSessionState

{

private static int __autoHandlers;

protected System.Web.UI.WebControls.Label NoteLabel;

protected System.Web.UI.HtmlControls.HtmlInputText f_Name;

protected System.Web.UI.HtmlControls.HtmlButton __control3;

protected System.Web.UI.HtmlControls.HtmlForm __control2;

private static bool __intialized = false;

private static System.Collections.ArrayList __fileDependencies;

/**//* 现在可以关掉"陷阱"了 */

// abcdefg

void Page_Load(Object src, EventArgs args)

{

if( !IsPostBack ) NoteLabel.Text = "请输入您的姓名: ";

}

void OnNameSubmit(Object src, EventArgs args)

{

string name = f_Name.Value;

NoteLabel.Text = (name=="") ? "姓名不能为空" : name +",您好。欢迎光临!";

}

/**//* 构造函数 */

public ex2_aspx()

{

System.Collections.ArrayList dependencies;

if ((ASP.ex2_aspx.__intialized == false))

{

dependencies = new System.Collections.ArrayList();

/**//*

应该把下面这行注释掉,让DLL成为一个无依赖的独立文件

防止在DLL运行时再次去查找、比较它的"依赖"文件的新旧

*/

//dependencies.Add("W://wwwroot//dlltest//ex2.aspx");

ASP.ex2_aspx.__fileDependencies= dependencies;

ASP.ex2_aspx.__intialized = true;

}

}

protected override int AutoHandlers

{

get {

return ASP.ex2_aspx.__autoHandlers;

}

set {

ASP.ex2_aspx.__autoHandlers = value;

}

}

protected System.Web.HttpApplication ApplicationInstance

{

get

{

return ((System.Web.HttpApplication)(this.Context.ApplicationInstance));

}

}

public override string TemplateSourceDirectory

{

get

{

return "/dlltest";

}

}

private System.Web.UI.Control __BuildControlNoteLabel()

{

System.Web.UI.WebControls.Label __ctrl;

__ctrl = new System.Web.UI.WebControls.Label();

this.NoteLabel = __ctrl;

__ctrl.ID = "NoteLabel";

((System.Web.UI.IAttributeAccessor)(__ctrl)).SetAttribute("style", "color:red; font-weight:bold");

return __ctrl;

}

private System.Web.UI.Control __BuildControlf_Name()

{

System.Web.UI.HtmlControls.HtmlInputText __ctrl;

__ctrl = new System.Web.UI.HtmlControls.HtmlInputText();

this.f_Name = __ctrl;

__ctrl.ID = "f_Name";

__ctrl.Size = 8;

return __ctrl;

}

private System.Web.UI.Control __BuildControl__control3()

{

System.Web.UI.HtmlControls.HtmlButton __ctrl;

__ctrl = new System.Web.UI.HtmlControls.HtmlButton();

this.__control3= __ctrl;

System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(__ctrl));

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("确定"));

__ctrl.ServerClick += new System.EventHandler(this.OnNameSubmit);

return __ctrl;

}

private System.Web.UI.Control __BuildControl__control2()

{

System.Web.UI.HtmlControls.HtmlForm __ctrl;

__ctrl = new System.Web.UI.HtmlControls.HtmlForm();

this.__control2= __ctrl;

System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(__ctrl));

__parser.AddParsedSubObject (new System.Web.UI.LiteralControl("/r/n <h1>DllTest - Ex2(例2)< /h1>/r/n <hr>/r/n "));

this.__BuildControlNoteLabel();

__parser.AddParsedSubObject(this.NoteLabel);

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("/r/n "));

this.__BuildControlf_Name();

__parser.AddParsedSubObject(this.f_Name);

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("/r/n "));

this.__BuildControl__control3();

__parser.AddParsedSubObject(this.__control3);

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("/r/n "));

return __ctrl;

}

private void __BuildControlTree(System.Web.UI.Control __ctrl)

{

System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(__ctrl));

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("/r/n/r/n<html>/r/n<body>/r/n "));

this.__BuildControl__control2();

__parser.AddParsedSubObject(this.__control2);

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("/r/n</body>/r/n</html>/r/n"));

}

protected override void FrameworkInitialize()

{

this.__BuildControlTree(this);

this.FileDependencies = ASP.ex2_aspx.__fileDependencies;

this.EnableViewStateMac = true;

}

public override int GetTypeHashCode()

{

return -11574299;

}

}

}

/**//* 源文件:ex2_aspx.cs 结束 */

相信大家在分析了这个文件之后,会对Asp.Net运行原理有更进一步的认识(与本文无关,不详述)。

在命令行状态,用如下的编译命令把ex2_aspx.cs编译成ex2.dll,并把它存放在bin目录下。
csc /t:library /out:bin/ex2.dll ex2_aspx.cs

在配置文件web.config中添加aspx->dll映射,即在system.web节的httpHandlers添加下面一行:
<add verb="*" path="dlltest2.aspx" type="ASP.ex2_aspx, ex2" />

现在当浏览器访问http://localhost/dlltest/dlltest2.aspx时,就如同访问ex2.aspx一样。当然,现在即使ex2.aspx不存在,或者已经更新过,也不会对页面访问有任何影响,除非重新生成bin/ex2.dll。

(四)把codebehindaspx文件编译成dll

对 于把codebehind的aspx文件编译成dll,其中把aspx文件转化成cs源文件的原理同上,也是先设置一个"代码陷阱",然后把"完整的编译 源"进行适当整理,保存为cs源文件。区别是在编译成dll时的步骤:(为叙述方便,假设界面文件为ex3.aspxcodebehind文件为 ex3.aspx.csex3.aspx"完整编译源"保存为ex3_aspx.cs

第一步:先用如下命令把ex3.aspx.cs编译成bin/ex3.aspx.cs.dll
csc /t:library /out:bin/ex3.aspx.cs.dll ex3.aspx.cs

第二步:再用如下命令把ex3_aspx.cs编译成bin/ex3.dll
csc /t:library /r:bin/ex3.aspx.cs.dll /out:bin/ex3.dll ex3_aspx.cs

然后在配置文件web.config中添加aspx->dll映射,即在system.web节的httpHandlers添加下面一行:
<add verb="*" path="dlltest3.aspx" type="ASP.ex3_aspx, ex3" />

现在打开浏览器,访问http://localhost/dlltest/dlltest3.aspx试试。

(五)一点小技巧

在设置"陷阱"把aspx文件转化成cs源文件时,一般是使用copy、paste方法把"完整的编译源"保存在记事本或vs.net或其它asp.net开发环境,再进行整理后保存为cs源文件的。

整理,就是把paste进来的行号信息与"#line"编译指令去掉。如果是手动地删掉这些信息,则会太麻烦,即使是一个简单的如ex2.aspx的文件,也会产生约270行的"完整的编译源"。

我 所使用的一个小技巧是:在记事本里,用替换的方法来快速整理。

用"/* 行"来全部替换"行",

用":*/"来全部替换":",

用"// #line 行 "来全部替换"#line",

替换完成之后,再把"代码陷阱"注释掉,把主类构造函数里设置"依赖文件"的语句全部注释掉,这样就算整理完成了。

编译asp.net 2.0项目到dll文件相关推荐

  1. c#.net2005 调用evc4.0生成的dll文件

    又好久没有写博客了,这一段时间一直在做东西,碰到了一些问题并解决掉了,所以把它写出来.写程序时碰到的第一个问题就是用c#.net2005 调用evc4.0生成的dll文件. 首先,在调用自己写的dll ...

  2. java web配置dll文件_JavaWeb项目中dll文件动态加载方法解析(详细步骤)

    相信很多做Java的朋友都有过用Java调用JNI实现调用C或C++方法的经历,那么Java Web中又如何实现DLL/SO文件的动态加载方法呢.今天就给大家带来一篇JAVA Web项目中DLL/SO ...

  3. 编译原理中LR(0)项目集规范族的构造

    本文转载自:  http://www.cnblogs.com/lazycoding/archive/2012/05/12/2497065.html 此文略长.我也没想到这写起来这么多,但对构造过程绝对 ...

  4. 关于Silverlight中多项目共享DLL文件的讨论

    假如你的解决方案中有两个Silverlight项目,其中的DLL文件时两个SL项目都使用到的,为了能够最大程度的减小XAP包的体积,你选择了系统的这个选项 编译后在Web的ClientBin文件夹下会 ...

  5. [原]Asp.net替换不同版本的Dll文件碰到的问题以及解决办法.

    情景还原: 今天一个朋友说网站不能上传图片,我检查后发现一直卡住在上传页面,一直滚动,是个Fckeditor控件2.6.3的. 经过google以后得到的结论是图片上传成功,但是没有返回结果,在服务器 ...

  6. 不用Fody,支持.net2.0,C#把Dll文件打包到Exe输出单文件版应用

    网上一些使用fody对c#的调用的dll文件捆包成exe文件,并不适合我,因为我的.net项目为了在低端机上使用,只安装.net2.0 这个改动主要分为两部分.,第一部分是先写一个自动通过资源加载dl ...

  7. IIS6+asp.net 2.0+HTTP 错误 404 - 文件或目录未找到:您正在搜索的页面可能已经删除、更名或暂时不可用。...

    错误信息 您正在搜索的页面可能已经删除.更名或暂时不可用. HTTP 错误 404 - 文件或目录未找到. 解决方法 手动开始 ASP.NET 2.0 服务扩展: 转载于:https://www.cn ...

  8. Asp.NET Core2.0 项目实战入门视频课程_完整版

    END OR START? 看到这个标题,你开不开心,激不激动呢? 没错,.net core的入门课程已经完毕了.52ABP.School项目从11月19日,第一章视频的试录制,到今天完整版出炉,离不 ...

  9. ASP.net Core MVC项目给js文件添加版本号

    需求:使用ASP.net Core Mvc开发公司内部web系统,给视图中js(css,image也可以)文件添加版本号避免缓存问题. 解决方法:利用Taghelper提供的标签(asp-append ...

  10. webpack+Vue2.0项目基础工程文件配置

    随着Vue的流行,很多公司开始技术栈指向Vue,开始的时候用gulp+vue1.0做项目,一直到现在,webpack趋势也上来了,而且vue官网也是用webpack跟Vue结合去讲解实例,接下来大概说 ...

最新文章

  1. R语言使用scatterplot3d包的scatterplot3d函数可视化3D散点图(3D scatter plots)、在3D散点图中添加垂直线和数据点描影、3D图中添加回归平面
  2. 天冷了,大家如果有往年的不穿的衣服别扔,寄给需要的人好吗?
  3. Python-深拷贝-浅拷贝-时间消耗
  4. 用eclipse创建动态web项目手动生成web.xml方法
  5. 在Ubuntu上安装使用深度影音深度音乐
  6. python 从列表中随机选择_使用条件Python从列表中随机选择
  7. 插入数据并返回插入数据ID
  8. shareplex三点同步配置
  9. ubuntu18.04 init setting
  10. python的输出语句_python 中简单的输出语句
  11. pcb布线注意点:晶振
  12. 密封橡胶圈尺寸缺陷视觉检测系统
  13. linux 7 查看网卡配置文件,如何查询centos网卡配置文件
  14. JavaDay03.练习2.写一个程序来帮助用户进行电话套餐选择
  15. 苹果备份与恢复_手机照片误删了怎么恢复?不得不说的好方法
  16. 人人旗下风车网产品经理的创业失败教训总结
  17. UEStudio/UltraEdit 的语法高亮文件 (*.uew)
  18. js 超简单 判断是否字符串是否为纯数字
  19. JavaSwing_3.2: JScrollPane(滚动面板)
  20. Java-pdf无限压缩方案-优化内存问题

热门文章

  1. 【单目标优化求解】基于matlab海洋捕食者算法(MPA)求解单目标问题【含Matlab源码 478期】
  2. 【优化算法】粒子群的混沌混合蝴蝶优化算法【含Matlab源码 047期】
  3. 字符串匹配代码C语言,KMP字符串匹配算法C语言实现
  4. 数仓 调度_【数仓开发-数仓概念篇】3.3 报表vs数据可视化vs ETL
  5. java 图片渐变消失_在线等:java图片怎样使之渐变消失
  6. 事务影响懒加载 no session or session was closed
  7. MySQL增删改查--之删
  8. SQL SERVER中隐式转换的一些细节浅析
  9. 揭开阿里P2P面纱:大数据是泡泡
  10. android源码编译完成之后