[转载]好书推荐《Pro ASP.NET MVC 3 Framework 3rd Edition》

mikel阅读(1639)

[转载]好书推荐《Pro ASP.NET MVC 3 Framework 3rd Edition》 – Junfeng Liu – 博客园.

花 了两个多星期的时间,从头到尾看了一遍,看此书如沐甘霖,绝对是一本好书。第4章讲的非常精辟,先介绍了架构模式的演化历史,从Smart UI, Model-View, Three-Tier到MVC;并比较了与Model-View-Presenter和Model-View-View Model的区别。然后介绍了领域驱动(Domain-Driven Development)、依赖注入(Dependency Injection)和单元测试(Unit Testing),再后面的章节中贯彻了这三种思想并用在了实例中。第6章介绍的Nject和Moq工具以前也没用过,再不用的话就会感觉很落后。第11 至20章是本书的核心内容,详细讲解了ASP.NET MVC 3 Framework,尤其是15至19章能学到很多新知识。

以前也感觉MVC好用,但是觉得不够快,不能拖一些控件直接到页面上,看完此书才知道并没有把MVC真正的优势发挥出来,当然VS如果能自带多一些MVC的控件就更好了。

另外关于MongoDB,推荐《MongoDB.in.Action》,这本也看了一大半了。

附:目录

Part 1: Introducing ASP.NET MVC 3
第1部分:ASP.NET MVC 3介绍
Chapter 1: What’s the Big Idea?
第1章:伟大的思想

Chapter 2: Getting Ready
第2章:准备工作

Chapter 3: Your First MVC Application
第3章:第一个MVC应用程序
3.1 Creating a New ASP.NET MVC Project【生成一个新的MVC项目】
3.2 Rendering Web Pages【渲染Web页面】
3.3 Creating a Simple Data-Entry Application【生成一个简单的数据-实体应用程序】(一)
3.3 Creating a Simple Data-Entry Application【生成一个简单的数据-实体应用程序】(二)
3.4 Summary【概要】

Chapter 4: The MVC Pattern
第4章:MVC模式
4.1 The History of MVC【MVC简史】
4.2 Understanding the MVC Pattern【理解MVC模式】
4.3 Applying Domain-Driven Development【运用域驱动开发】
4.4 Building Loosely Coupled Components【建立松耦合组件】
4.5 Getting Started with Automated Testing【自动测试初步】
4.6 Summary【概要】

Chapter 5: Essential Language Features
第5章:基本语言特性
5.1 Essential C# Features【C#基本特性】(自动属性、对象与集合初始化器)
5.1 Essential C# Features【C#基本特性】(扩展方法)
5.1 Essential C# Features【C#基本特性】(Lambda表达式)
5.1 Essential C# Features【C#基本特性】(自动类型接口、匿名类型、LINQ查询、延迟LINQ)
5.2 Understanding Razor Syntax【理解Razor语法】(一)
5.2 Understanding Razor Syntax【理解Razor语法】(二)
5.3 Summary【概要】

Chapter 6: Essential Tools for MVC
第6章:MVC主要工具
6.1 Using Ninject【使用Ninject】
6.2 Applying Ninject to ASP.NET MVC【将Ninject用于ASP.NET MVC
6.3 Unit Testing with Visual Studio【Visual Studio的单元测试】
6.4 Using Moq【使用Moq】
6.5 Summary【概要】

Chapter 7: SportsStore: A Real Application
第7章:体育商店:一个真实的应用程序
7.1 Getting Started【开始】
7.2 Starting the Domain Model【域模型】
7.3 Displaying a List of Products【显示产品列表】
7.4 Preparing a Database【准备数据库】
7.5 Adding Pagination【添加分页】
7.6 Styling the Content【设置内容样式】
7.7 Summary【概要】

Chapter 8: SportsStore: Navigation and Cart
第8章:体育商店:导航与购物车
8.1 Adding Navigation Controls【添加导航控件】
8.2 Building the Shopping Cart【建立购物车】
8.3 Using Model Binding【使用模型绑定】
8.4 Completing the Cart【完成购物车】
8.5 Submitting Orders【递交订单】
8.6 Summary【概要】

Chapter 9: SportsStore: Administration
第9章:体育商店:管理
9.1 Adding Catalog Management【添加目录管理】
9.2 Securing the Administration Features【使管理特性安全】
9.3 Image Uploads【图像上载】
9.4 Summary【概要】

Part 2: ASP.NET MVC 3 in Detail
第2部分:ASP.NET MVC 3细节
Chapter 10: Overview of MVC Projects
第10章:MVC项目概览
10.1 Working with Visual Studio MVC Projects【与Visual Studio MVC项目一起工作】
10.2 Debugging MVC Applications【调试MVC应用程序】
10.3 Project-Wide Dependency Injection【项目范围上的依赖性注入】
10.4 Summary【概要】

Chapter 11: URLs, Routing, and Areas
第11章:URL、路由及区域
11.1 Introducing the Routing System【路由系统介绍】
11.2 Generating Outgoing URLs【生成输出的URL】
11.3 Customizing the Routing System【定制路由系统】
11.4 Working with Areas【对区域进行工作】
11.5 URL Schema Best Practices【URL模式最佳实践】
11.6 Summary【概要】

Chapter 12: Controllers and Actions
第12章:控制器与动作
12.1 Introducing the Controller【控制器介绍】
12.2 Receiving Input【接收输入】
12.3 Producing Output【产生输出】
12.4 Summary 【概要】

Chapter 13: Filters
第13章:过滤
13.1 Using Filters【使用过滤器】
13.2 Summary 【概要】

Chapter 14: Controller Extensibility
第14章:控制器扩展性
14.1 Request Processing Pipeline Components【请求处理管线组件】
14.2 Creating a Controller Factory【生成一个控制器工厂】
14.3 Working with the Built-In Controller Factory【与内建的控制器工厂一起工作】
14.4 Creating a Custom Action Invoker【生成自定义动作请求】
14.5 Using the Built-In Action Invoker【使用内建的动作请求】
14.6 Improving Performance with Specialized Controllers【用序列化控制器改善性能】
14.7 Summary【概要】

Chapter 15: Views
第15章:视图
15.1 Creating a Custom View Engine【生成自定义的视图引擎】
15.2 Working with the Razor Engine【与Razor一起工作】
15.3 Adding Dynamic Content to a Razor View【将动态内容添加到Razor视图】
15.4 Using HTML Helpers【使用HTML辅助器】
15.5 Using Sections【使用会话】
15.6 Using Partial Views【使用部分视图】
15.7 Using Child Actions【使用子动作】
15.8 Summary 【概要】

Chapter 16: Model Templates
第16章:模型模板
16.1 Using Templated View Helpers【使用模板化的视图辅助器】
16.2 Customizing the Templated View Helper System【自定义模板化的视图辅助器系统】
16.3 Understanding the Metadata Provider System【理解元数据提供器系统】
16.4 Summary【概要】

Chapter 17: Model Binding
第17章:模型绑定
17.1 Understanding Model Binding【理解模型绑定】
17.2 Using the Default Model Binder【使用默认的模型绑定】
17.3 Manually Invoking Model Binding【手工请求模型绑定】
17.4 Using Model Binding to Receive File Uploads【把模型绑定用于接收文件上载】
17.5 Customizing the Model Binding System【自定义模型绑定系统】
17.6 Summary【概要】

Chapter 18: Model Validation
第18章:模型检验
18.1 Creating the Project【生成项目】
18.2 Explicitly Validating a Model【明确地检验一个模型】
18.3 Displaying Validation Messages【显示检验消息】
18.4 Using Alternative Validation Techniques【使用另一种检验技术】
18.5 Performing Client-Side Validation【执行客户端检验】
18.6 Performing Remote Validation【执行远程检验】
18.7 Summary【概要】

Chapter 19: Unobtrusive Ajax
第19章:非强制Ajax
19.1 Using MVC Unobtrusive Ajax【使用MVC的非强制Ajax】
19.2 Setting Ajax Options【设置Ajax选项】
19.3 Creating Ajax Links【生成Ajax连接】
19.4 Working with Ajax Callbacks【与Ajax回递一起工作】
19.5 Working with JSON【与JSON一起工作】
19.6 Summary【概要】

Chapter 20: JQuery
第20章:JQuery
20.1 Creating the Project【生成项目】
20.2 Referencing jQuery【引用jQuery
20.3 Writing jQuery Code【编写jQuery代码】
20.4 Basic jQuery Theory【jQuery基本理论】
20.5 Using jQuery Events【使用jQuery事件】
20.6 Using jQuery Visual Effects【使用jQuery可视化效果】
20.7 Using jQuery UI【使用jQuery的UI】
20.8 Summary【概要】

Part 3: Delivering Successful ASP.NET MVC 3 Projects
第3部分:交付成功的ASP.NET MVC 3项目
Chapter 21: Security and Vulnerability
第21章:安全性与脆弱性
21.1 All Input Can Be Forged【所有输入都可以伪造】
21.2 Cross-Site Scripting and HTML Injection【跨网站脚本与HTML注入】
21.3 Session Hijacking【会话劫机】
21.4 Cross-Site Request Forgery【跨网站请求伪造】
21.5 SQL Injection【SQL注入】
21.6 Using the MVC Framework Securely【安全地使用MVC框架】
21.7 Summary【概要】

Chapter 22: Authentication and Authorization
第22章:认证与授权
22.1 Using Windows Authentication【使用Windows认证】
22.2 Using Forms Authentication【使用表单认证】
22.3 Using Membership, Roles, and Profiles【使用成员、角色、与轮廓】
22.4 Why You Shouldn’t Use URL-Based Authorization【为什么不应该使用基于URL的认证】
22.5 Restricting Access Using IP Addresses and Domains【使用IP地址和主域限制访问】
22.6 Summary【概要】

Chapter 23: Deployment
第23章:部署
23.1 Preparing an Application for Deployment【进行应用程序部署的准备】
23.2 Understanding the IIS Fundamentals【理解IIS基础】
23.3 Preparing the Server for Deployment【准备部署服务器】
23.4 Deploying an Application【部署应用程序】
23.5 Summary【概要】

Index
索引

download : 点击下载

[转载]如何通过豆瓣API获取图书和电影列表

mikel阅读(1289)

[转载]如何通过豆瓣API获取图书和电影列表 – Justin – 博客园.

一直在豆瓣上收藏看过的书和电影(其他功能基本没用过),准备做个页面可以同步显示豆瓣上收藏的所有图书和电影,这个功能可以通过豆瓣提供的API来实现,并不复杂,我只是做了简单的封装,需要的可以直接拿去用,有问题可以直接留言,运行后的效果看这里 Books 或这里 我的豆瓣 ,因为豆瓣限制一分钟内访问次数不能超过40次,所以如果多人同时访问前面的链接可能看不到效果,再传个截图上来:

几点说明:

1.登录豆瓣后,可以去 这里 申请豆瓣APIKey。(不使用API Key时每分钟请求不能超过10次;使用API Key时,对访问的限制较为宽松,为每分钟40次

2.豆瓣API每次调用 最多返回50个结果 ,如果你豆瓣上的书和电影超过50个,就要多次发起调用,这部分功能我的程序里已经自动处理了。

3.我封装的这段脚本提供了一些可选配置如下,参数的含义都比较明确,这里就不解释了(place是一个div的ID,可以用来做定位)。

defaults:{
       place:"douban",
       user:"",
       api:"",
       book:[{stus:"reading",maxnum:20},{stus:"read",maxnum:500},{stus:"wish",maxnum:100}],
       movie:[{stus:"watched",maxnum:500},{stus:"wish",maxnum:200}],
       bookreadingtitle:"正读...",
       bookreadtitle:"读过...",
       bookwishtitle:"想读...",
       moviewatchedtitle:"看过...",
       moviewishtitle:"想看..."
   }

4.在你的网页里参考下面代码增加引用和调用,就可以实现类似这个页面的效果。

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>豆瓣列表</title>
<style type="text/css">
.douban-title {
    padding: 10px 10px 0px 0px;
    text-shadow: 0 1px 0 white,1px 2px 2px #AAA;
    font-weight: bold;
    font-size:24px;
}
.douban-list a {
    padding: 10px 10px 10px 0px;
}
</style>
<script type='text/JavaScript' src='JQuery-1.4.2.js'></script>
<script type="text/JavaScript" src="dbapi_beta1_20120316.js"></script>
</head>
<body>
<script>
    var _defaults = {
        user:"justin79", //这里换成你的豆瓣ID
        api:""          //这里换成你的豆瓣APIKEY
    }
    dbapi.show(_defaults);
</script>
</body>
</html>

整个javascript代码如下:

//批量读取豆瓣的图书和电影
//by justin 20120316
//--dbapi.begin--
var $ = JQuery;
var dbapi = {
    appendScript:function(url){
        if ((url)&&(url.length > 0))
            $("<script/>").attr("src",url).attr("charset","utf-8").appendTo($("head")[0]);
    },
    /**
     * 解析json数据为数组
     */
    parseJSON:function(json){
        var items=[];
            $.each(json.entry,function(i,item){
                var link = {};
                link.title = item["db:subject"]["title"]["$t"];               
                link.link = item["db:subject"]["link"][1]["@href"];//硬编码
                link.src = item["db:subject"]["link"][2]["@href"];//硬编码
                items.push(link);
            });           
        return items;
    },
    render:function(items){
        var html='';       
        $.each(items,function(i,item){
            html+='<a href="'
                +item.link+'" target="_blank"><img src="'
                +item.src+'" alt="'+item.title
                +'" title="'+item.title+'"border="0" /></a>';
        });
        return html;
    },
    /**
     * todo: bookurl 和 movieurl 可以合并简化
     */
    bookurl:function(stus,begin,end){
        return this.allurl("book",stus,begin,end);
    },
    movieurl:function(stus,begin,end){
        return this.allurl("movie",stus,begin,end);
    },
    allurl:function  (typ,stus,begin,end) {
        if (end ===0) return;
        if(!dbapi[typ + stus +"_SHOW"]){
            dbapi[typ + stus +"_SHOW"] = function (json) {
                var mainplace = $("#"+this.opts.place);
                if (mainplace.length ===0){
                    mainplace = $("<div/>").attr("id",this.opts.place).prependTo($("body"));
                }
                if ($("#"+typ+stus).length === 0){
                    var title = this.defaults[typ+stus+"title"]?this.defaults[typ+stus+"title"]:
                                 ">>>"+typ.toUpperCase() +"-"+stus.toUpperCase()+">>>";
                    $("<span/>").addClass("douban-title").text(title).appendTo(mainplace);
                    $("<div/>").attr("id",typ+stus).addClass("douban-list").appendTo(mainplace);                   
                }                   
                $("#"+typ+stus).append(this.render(this.parseJSON(json)));               
            }
        }
        return this.apiurl(typ,this.opts.user,this.opts.api,stus,begin,end);
    },
    apiurl:function(typ,user,key,stus,begin,end){
        var url = "http://api.douban.com/people/"+user+"/collection?cat="+typ+"&start-index="+
            begin+"&max-results="+end+"&status="+stus+"&alt=xd&callback=dbapi."+typ+stus+"_SHOW";
        if (key.length > 0)
            url += "&apikey="+key;
        return url;
    },
    /**
     * 将num按50分段生成数组集合
     * @param  {[type]} num 显示项目的个数
     * @return {[type]} 按50分段的数组
     */
    fixNum:function(num){
        var len = num;       
        var index = 1;
        var fixnums=[];
        if (50>len> 0){
            fixnums.push({begin:index,end:len})
        }else{
            while (len > 0) {
                fixnums.push({begin:index,end:index+49})
                len -= 50;
                index +=50;
            };   
        }
        return fixnums;
    },
    /**
     * 根据配置项显示豆瓣的图书和电影
     * @param  {[Object]} options [可选配置项]
     */
    show:function(options){
        this.opts = $.extend({}, this.defaults, options);
        var books = [];
        var movies = [];
        $.each(this.opts.book,function (i,item) {
            books.push({stus:item.stus,indexs:dbapi.fixNum(item.maxnum)});   
        });
        $.each(this.opts.movie,function (i,item) {
            movies.push({stus:item.stus,indexs:dbapi.fixNum(item.maxnum)});   
        });
        $.each(books,function(i,item){   
            $.each(item.indexs,function(t,idx){
                setTimeout(dbapi.appendScript(dbapi.bookurl(item.stus,idx.begin,idx.end)),300);
            });               
        });
        $.each(movies,function(i,item){   
            $.each(item.indexs,function(t,idx){
                setTimeout(dbapi.appendScript(dbapi.movieurl(item.stus,idx.begin,idx.end)),1000);
            });               
        });       
    },
    /**
     * 可选配置项
     * @type {Object}
     * todo:可以进一步把book和movie合并到一起,通过类型区分。
     */
    defaults:{
        place:"douban",
        user:"",
        api:"",
        book:[{stus:"reading",maxnum:20},{stus:"read",maxnum:500},{stus:"wish",maxnum:100}],
        movie:[{stus:"watched",maxnum:500},{stus:"wish",maxnum:200}],
        bookreadingtitle:"正读...",
        bookreadtitle:"读过...",
        bookwishtitle:"想读...",
        moviewatchedtitle:"看过...",
        moviewishtitle:"想看..."
    }
}
//--dbapi.end--

完整的实例下载:http://files.cnblogs.com/justinw/doubanAPI_Demo.rar

本文地址:http://www.cnblogs.com/justinw/archive/2012/03/16/doubanapi.html

[转载]sqlserver2008的数据库自动备份方法

mikel阅读(1112)

[转载]sqlserver2008的数据库自动备份方法 – Terry Zeng – 博客园.

SQLServer2008的数据库自动备份方法

SQL Server中出于数据安全的考虑,所以需要定期的备份数据库。而备份数据库一般又是在凌晨时间基本没有数据库操作的时候进行,所以我们不可能要求管理员 每天守到晚上1点去备份数据库。要实现数据库的定时自动备份,最常用的方式就是使用SQL Server代理中的作业。启动SQL Server Agent服务,然后在其中新建作业,作业中添加1个备份步骤,类型是T-SQL脚本,然后在命令中输入如下SQL语句,该语句实现了对数据库 TestDB1的完整备份,备份文件在C盘Backup文件夹中,文件名就是TestDB1+当时备份的日期字符串.bak。

 

declare @name varchar(250)
set @name=’C:\Backup\TestDB1_’+convert(varchar(50),getdate(),112)+’.bak’
BACKUP DATABASE [TestDB1] TO
DISK = @name
WITH NOFORMAT, NOINIT,
NAME = N’TestDB1-完整 数据库 备份’,
SKIP, NOREWIND, NOUNLOAD

 

数据库备份文件名称中不能出现空格“ ”,冒号“:”

 

创建好步骤以后,接下来就是创建计划,创建计划的操作十分简单,界面上说明的很详细了,我就不多说了。另外还可以配置警报和通知,不过一般很少用这个。

使用SQL作业中执行SQL脚本进行备份的方法虽然已经很简单了,但是至少还是要去写BACKUP脚本,这点有些人觉得不爽,那有没有更简单,更懒的方法来实现数据库的自动定时备份呢?有,那就是“维护计划”。

“维护计划”是在SSMS的对象资源管理中“管理”节点下面。使用维护计划可以通过可视化的操作,只点点鼠标就可以创建数据库维护的SSIS包,然后仍然 是通过SQL Server作业的方式来运行。维护计划与前面说到的备份方法本质的不同就是:维护计划是SSIS包,上面的是T-SQL脚本。

假设我们现在有一个生产系统的数据库需要进行备份,由于数据库中的数据很多,数据文件很大,如果每次都进行完整备份那么硬盘占用了很大空间,而且备份时间 很长,维护起来也很麻烦。对此我们可以采用完整备份+差异备份的方式,每周日进行一次完整备份,每天晚上进行一次差异备份。使用差异备份可以减小备份文件 的大小,同时还可以提高备份的速度,不过缺点就是必须使用上一次完整备份的文件和差异备份的文件才能还原差异备份时刻的数据库,单独只有差异备份文件是没 有意义。

下面我来讲一下如何通过维护计划来实现完整备份+差异备份:

(1)在SSMS的对象资源管理器中右击“维护计划”,选择 “维护计划向导”,系统将弹出向导窗口,如图:

这里向导已经告诉我们维护计划到底能够干什么了,其中最后一项“执行数据库备份”正是我们所需要的。

 

(2)点击“下一步”按钮,进入选择计划属性窗口,输入计划的名称,由于我们的计划包括2部分:完整备份和差异备份,这2部分的执行计划是不一样的,一个是一周执行一次,另一个是一天执行一次,所以要选择“每项任务单独计划”,如图:

(3)单击“下一步”按钮,选择维护任务,这里就是可以在维护计划中执行的任务,如果你想执行的任务在这里没有,那就还是不用维护计划来做,自己写 SSIS包或者SQL语句吧。我们要执行的任务都在这里,选中这2个任务,如图:

(4)单击“下一步”进入选择维护任务顺序的界面,这里我们可以看到选中的任务出现在列表中,但是我们并不能调整其顺序,那是因为在步骤2中我们选择的是 每项任务单独计划,所以这2个任务是独立的,没有先后顺序可言。如果当时选择的是另一个选项,那么这里就可以调整顺序了。

 

(5)选中“备份数据库(完整)”然后单击“下一步”按钮,系统将转到定义完整备份任务的界面,如图:

这个界面实在太长了,我把任务栏隐藏了都显示不完,出现了滚动条,这里我们选择要进行备份的数据库,选择为每个数据库创建备份文件,文件保存在C盘 Backup目录下,扩展名是bak,出于安全起见,我们可以选中“验证备份完整性”,当然也可以不选。在SQL2008中提供了压缩备份的新特性,使得 备份文件更小,备份速度更快,这里我们就是由压缩备份。最后是选择执行计划,我这里选的是每周日晚上0点的时候执行。

 

(6)单击“下一步”按钮,进入差异备份任务的设置界面,和上一步的界面是一样的,操作也是一样的,计划这里我们可以选择除了周日以外的每天进行差异备份,如图:

(7)单击“下一步”按钮,进入选择报告选项,这里我们可以将这个维护计划的执行报告写入文本文件中,也可以讲报告通过电子邮件发送给管理员。如果要发送 邮件的话,那么需要配置SQL Server的数据库邮件,另外还要设置SQL Server代理中的操作员,关于邮件通知操作员的配置网上也讲的比较多,我这里就不详述了。

(8)单击“下一步”按钮,进入“完成该向导”的界面,系统列出了向导要完成的工作,如图:

(9)单击“完成”按钮,向导将创建对应的SSIS包和SQL作业:

(10)完成后,我们再刷新下对象资源管理器,我们可以看到对应的维护计划和该计划对应的作业:

现在维护计划是创建好了,急着想看看执行后的效果如何,不需要等到晚上12点去了,在“作业”下面,右击 DbBackupPlan.Subplan_1,选择“作业开始步骤”系统便立即执行该作业,系统运行完成后,我们便可在C:\Backup文件夹下面有 我们做的完整备份的备份文件。

 

以上的操作可以是纯粹的无键盘操作,不用写任何脚本,只需要点点鼠标即可。

这里需要注意的是,我们如果不是周日制定的该维护计划,那么制定该维护计划前一定要做个完整备份,而且该备份至少要保留到下周,不然到时候出了问题,发现只有这几个工作日的差异备份,而上一次的完整备份又被删了,那就郁闷了。

 

除了使用维护计划向导以外,我们还可以直接新建维护计划,也可以修改意见创建的维护计划。我们就以修改维护计划为例。对于前面创建好的完整备份+ 差异备份维护计划,现在我们需要每周对数据库备份进行一次清理,在完整备份完成后,要将1个月前的备份删除掉。那么我们只需要修改一下维护计划即可,具体 操作如下:

(1)右击我们的维护计划,在弹出式菜单中选择“修改”选项,系统将新建一个选项卡来显示当前的维护计划。如图:

左下角是可用的维护计划组件,右下面板是维护计划的流程设置面板,其上面就是该计划的子计划列表。

 

(2)选中Subplan_1子计划,也就是每周完整备份的子计划,将“清除历史记录”任务从工具箱中拖拽到计划面板中,然后在面板中单击“备份数据库(完整)”组件,系统将显示一个绿色的箭头,将绿色箭头拖拽到“清除历史记录”组件上,如图:

也就是说在成功完整备份了数据库后,接下来才执行清除历史记录任务。

 

(3)右击“清除历史记录”任务,在弹出式菜单中选择“编辑”选项,系统将弹出清除历史记录任务设置窗口,如图:

这里既可以清除历史记录日志,也可以删除硬盘上的历史数据。这里我们要删除4周前的历史备份数据,单击“确定”回到计划面板,我们可以看到原本“清除历史 记录”任务上的小红叉不见了。单击“保存”按钮,该计划便保存起来。(说明:我在SQL2008中文版虚拟机里面做的时候一旦修改维护计划,保存的时候就 报错灾难性故障,不过我本机的英文版是正常的,不知道是我虚拟机的问题还是中文版的Bug,反正在英文版里面是对的。)

 

这样修改后,以后我们都不用手动去删除那些很久以前的数据库备份了,系统在执行完备份后就会删除那些满足条件的备份数据。

 

另外如果用过SSIS的人应该知道,一个任务在完成时是绿色箭头,如果是失败时是红色箭头,我们这里也可以设置,如果上一步骤失败,那么将执行什么操作,双击绿色箭头,在弹出的对话框中选择约束选项中的值为“失败”即可。如图:

在维护计划中也可以设置很复杂的逻辑运算和执行流程,就和SSIS 设计一样的,毕竟本质上他们都是在设计SSIS包。

[转载]如何用Swing去绘制电力系统图

mikel阅读(1399)

[转载]如何用Swing去绘制电力系统图 – twaver – 博客园.

TWaver作为一款专业的图形界面控件,可以应用在各行各业中。本文我们就来详细介绍一下TWaver如何绘制出电力系统的界面。我们现在看看几张电力系统的图:

某变电站设备接线图一

某变电所的接线图二

当然这些是我在网上搜索的一些资源,那么TWaver是否能实现这样的界面呢?回答是肯定的,我们先来分析一下,电力电气系统中这些界面都是由很多 电气元素组成的,比如变压器,刀闸,开关,接地开关,电容器,发电机等。 接下来我们看看如何去扩展这些电气元素,先整个简单的刀闸,刀闸一般有两种状态,打开关闭,因此我们可以定义一个刀闸的类,继承于 ResizableNode,添加turnOn的属性来控制开关状态

public class Switch extends ResizableNode{
private boolean turnOn = true;

public Switch() {
super();
init();
}

public Switch(Object id){
super(id);
init();
}

private void init(){
this.setSize(5,30);
this.putBorderColor(Color.black);
this.putBorderInsets(12);
}

public String getUIClassID() {
return SwitchUI.class.getName();
}

public boolean isTurnOn() {
return turnOn;
}

public void setTurnOn(boolean turnOn) {
if(this.turnOn != turnOn){
boolean oldValue = this.turnOn;
this.turnOn = turnOn;
this.firePropertyChange("turnOn", oldValue, this.turnOn);
}
}
}

接着需要在UI上需要根据turnOn的属性来绘制开关的形状,下面贴一下主要的paint方法

public void paintBody(Graphics2D g) {
g.setStroke(TWaverConst.DOUBLE_WIDTH_STROKE);

Switch switzh = (Switch)this.getElement();

//get position
final Point location = switzh.getLocation();
final Dimension size = switzh.getSize();
boolean trunOn = switzh.isTurnOn();
final int x = location.x;
final int y = location.y;
final int width = size.width;
final int height = size.height;

//draw color frame
g.setColor(new Color(170,0,225));
g.drawOval(x, y, width, width);
g.drawOval(x, y+height-width, width, width);

if(trunOn){
g.drawLine(x+width/2, y+height-width, x+height/2,y+width);
}else{
g.drawLine(x+width/2, y+height-width, x+width/2, y+width);
}
}

通过一个main来运行看看扩展出来的效果:

这是简单的刀闸元素,扩展起来还是比较容易的。接下来来个稍微复杂一点的–接地开关,同样它和刀闸一样,也有两种状态

这个例子中我们给接地开关设置了几个不同的方向,同样上面的也可以这么做一下处理,我们来看看如何绘制这个接地开关的

public void paintBody(Graphics2D g) {
g.setStroke(TWaverConst.BASIC_STROKE);
g.setColor(Color.black)

EarthingSwitch earthingSwitch = (EarthingSwitch)this.getElement();
final Point location = earthingSwitch.getLocation();

boolean turnOn = earthingSwitch.isTurnOn();
int position = earthingSwitch.getSwitchPosition();
final int x = location.x;
final int y = location.y;
int width = earthingSwitch.getWidth();
int height = earthingSwitch.getHeight();
//draw body
if(turnOn){
if(position == Utils.SWITCH_POSITION_TOP){
g.drawLine(x+width/4, y, x+width/4*3, y);
g.drawLine(x+width/6, y+2, x+width/6*5, y+2);
g.drawLine(x, y+4, x+width, y+4);
g.drawLine(x+width/2, y+4, x+width/2, y+7);
g.drawLine(x+width/2, y+7, x+width, y+height-10);
g.drawLine(x+width/2, y+height-3, x+width/2, y+height);
}else if(position == Utils.SWITCH_POSITION_LEFT){
//transfer width and height
int middle = width;
width = height;
height = middle;

g.drawLine(x,y+height/4, x, y+height/4*3);
g.drawLine(x+2, y+height/6, x+2, y+height/6*5);
g.drawLine(x+4, y, x+4, y+height);
g.drawLine(x+4, y+height/2, x+7, y+height/2);
g.drawLine(x+7, y+height/2, x+width-10, y);
g.drawLine(x+width-3, y+height/2, x+width, y+height/2);
}else if(position == Utils.SWITCH_POSITION_BOTTOM){
g.drawLine(x+width/4, y+height, x+width/4*3, y+height);
g.drawLine(x+width/6, y+height-2, x+width/6*5, y+height-2);
g.drawLine(x, y+height-4, x+width, y+height-4);
g.drawLine(x+width/2, y+height-4, x+width/2, y+height-7);
g.drawLine(x+width/2, y+height-7, x, y+10);
g.drawLine(x+width/2, y+3, x+width/2, y);
}else if(position == Utils.SWITCH_POSITION_RIGHT){
//transfer width and height
int middle = width;
width = height;
height = middle;

g.drawLine(x+width,y+height/4, x+width, y+height/4*3);
g.drawLine(x+width-2, y+height/6, x+width-2, y+height/6*5);
g.drawLine(x+width-4, y, x+width-4, y+height);
g.drawLine(x+width-4, y+height/2, x+width-7, y+height/2);
g.drawLine(x+width-7, y+height/2, x+10, y);
g.drawLine(x+3, y+height/2, x, y+height/2);
}
}else{
if(position == Utils.SWITCH_POSITION_TOP){
g.drawLine(x+width/4, y, x+width/4*3, y);
g.drawLine(x+width/6, y+2, x+width/6*5, y+2);
g.drawLine(x, y+4, x+width, y+4);
g.drawLine(x+width/2, y+4, x+width/2, y+7);
g.drawLine(x+width/2, y+7, x+width/2, y+height-3);
g.drawLine(x+width/2, y+height-3, x+width/2, y+height);
}else if(position == Utils.SWITCH_POSITION_LEFT){
//transfer width and height
int middle = width;
width = height;
height = middle;

g.drawLine(x,y+height/4, x, y+height/4*3);
g.drawLine(x+2, y+height/6, x+2, y+height/6*5);
g.drawLine(x+4, y, x+4, y+height);
g.drawLine(x+4, y+height/2, x+7, y+height/2);
g.drawLine(x+7, y+height/2, x+width-3, y+height/2);
g.drawLine(x+width-3, y+height/2, x+width, y+height/2);
}else if(position == Utils.SWITCH_POSITION_BOTTOM){
g.drawLine(x+width/4, y+height, x+width/4*3, y+height);
g.drawLine(x+width/6, y+height-2, x+width/6*5, y+height-2);
g.drawLine(x, y+height-4, x+width, y+height-4);
g.drawLine(x+width/2, y+height-4, x+width/2, y+height-7);
g.drawLine(x+width/2, y+height-7, x+width/2, y+3);
g.drawLine(x+width/2, y+3, x+width/2, y);
}else if(position == Utils.SWITCH_POSITION_RIGHT){
//transfer width and height
int middle = width;
width = height;
height = middle;

g.drawLine(x+width,y+height/4, x+width, y+height/4*3);
g.drawLine(x+width-2, y+height/6, x+width-2, y+height/6*5);
g.drawLine(x+width-4, y, x+width-4, y+height);
g.drawLine(x+width-4, y+height/2, x+width-7, y+height/2);
g.drawLine(x+width-7, y+height/2, x+3, y+height/2);
g.drawLine(x+3, y+height/2, x, y+height/2);
}
}
}

还有一些其他的元素,比如开关,发电机,变压器这些可以直接通过TWaver提供的customDraw很容易的配置出来,这些就比较简单了,此处代码省略100字,直接上图了

有了这些基础的元素,那么来绘制电力系统界面就显得不是那么复杂了,我们通过上面扩展的这些电力元素用twaver的工具画出了一个电力系统图,如下:

最后我们可以在界面上加上交互,比如双击打开关闭刀闸开关,然后添加自己的业务,这样一个简单的电力系统界面就完成了

network.addElementDoubleClickedActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
Element ele = network.getSelectionModel().lastElement();
if(ele instanceof Switch){
boolean turnOn = ((Switch)ele).isTurnOn();
((Switch)ele).setTurnOn(!turnOn);
}
}
});

同样最先贴出来的两张变电所的图是不是也就很容易的做出来呢!最后再附上TWaver做的另一张电力界面图

[转载]漫画追踪器Tracker

mikel阅读(1324)

[转载]漫画追踪器Tracker – 风中之炎 – 博客园.

1. 动机

关注漫画的人肯定会发现漫画的更新时间差异非常大:有的一个星期更新一集,有的一个月更新一集,有的一季度更新一集。如果关注的是日本漫画,并且不会日文,那么更新后的漫画还要等待汉化组翻译成中文才能看。这一等,少则几小时,多则几个星期。

等得多了,就会产生这样一种想法:如果漫画更新后能通知我就好了。有的漫画网站抓住了这种想法,增加了关注的漫画更新后就发邮件通知的功能。但是,对于不经常查看邮箱的人来说,这种功能并没有多大帮助。于是,就有了进一步的想法:如果关注的漫画更新后,就立刻下载到我的电脑上,并且弹出提示框就好了

根据这个想法形成的工具正是tracker。因而它的核心功能就是追踪漫画——当关注的漫画更新时,立即下载到指定文件夹,并弹出对话框提示。

 

2. 关键功能实现

实现tracker的追踪功能的难点在于漫画更新的判定,而下载功能的难点则是搞定漫画网站的防盗链/防盗图。以下以99漫画网(http://www.99comic.com)为例说明这两个功能是如何实现的。

2.1 判定漫画更新

在99漫画网中,打开《火影忍者》可以得到如下页面:

从上图可以得到一个猜测,漫画集数都放在同一个div中(观察该页面的源代码可以证明这个猜测是正确的)。既然如此,当漫画更新了,新一集的名称必然也是放在这个div中。根据这个特性,可以得到如下想法:记录div的当前集数,并每隔一定时间访问该页面,如果发现div中集数增加了,就说明漫画更新了。

此外,如果仔细观察页面,会发现有一个漫画更新时间(即图中红圈圈出部分)。既然是漫画更新时间,那么当漫画更新了,这个时间也应该更新。换句话说,只要记录更新时间,并每隔一定时间判定更新时间是否改变,就能判断漫画是否更新。

利用更新时间来判定是否更新在省功夫的同时,也意味着会缺失更多的信息——不清楚更新的是什么。此外,也不能确保漫画更新的同时,更新的时间会马上改变。基于以上考虑,最后实现时采用的想法是第一个想法,记录div中的漫画集数。

以下是该想法实现的流程图:

 

2.2 下载功能

通常来说,如果知道一张图片的URL地址,下载这张图片是相当简单的。但是99漫画网出于防盗链/防盗图的考虑,将URL地址隐藏了。所以难点就变成了找 到图片的URL地址。为了更好地分析图片的URL地址是如何隐藏的,我使用了Paros来截取http请求以及回应。以下开始分析。

点击火影忍者570集(http://www.99comic.com/manhua/99168/list_90873.htm?s=9 ),在Paros中查找是哪一个请求得到图片的。

在显示该漫画图片的网页的源代码中(图3-5用红色方框所圈出的那部分),可以找到图3-3请求的URL的一部分。但是前面那部分URL却没办法在源代码中找到。也就是说,存放图片服务器的URL被该漫画网站用其它方法隐藏了。

检查打开漫画图片所在网页时收到的全部回应后,在一个脚本的回应中找到了服务器的URL(图3-6用红圈圈出部分)。这个脚本请求的服务器URL是漫画网站的名称,而相对URL则可以在漫画图片所在网页的源代码中找到(图3-5用红圈圈出部分)。

找到了隐藏服务器的URL,还有相对URL,分析是不是能结束了。不能!因为现在有一个疑点——在脚本的回应中(图3-6),列出了很多服务器的URL。 这意味着不同漫画或者不同时候会使用不同的服务器。所以还要分析整个脚本,找到是如何选择服务器的。不过,分析脚本的过程比较复杂,这里就直接给出分析结 果:选择哪一个服务器与漫画所在页面的URL有关系。

总结以上过程,可以得到这样的获取方法:先请求漫画图片所在网页的URL,在回应中提取图片的相对URL,脚本的相对URL。然后利用漫画网站名称和脚本 的相对URL,构造出完整的脚本URL,并请求该脚本。利用逆解析函数分析脚本回应,得出图片的服务器URL。最后,将图片的服务器URL与相对URL结 合起来,并进行请求,就能得到图片了。

 

3. 使用Tracker的追踪功能

第一步,首先在搜索漫画栏写上自己要追踪的漫画名称,然后按下回车键或者搜索按钮。如果搜索结果没有发现自己想要的漫画,可尝试更换来源网站

第二步,单击想要追踪的漫画。PS:这时会出现漫画的简介与当前的集数。

第三步,点击追踪漫画的按钮,这时会弹出如下图所示的一个对话框。

第四步,选择一个保存用的文件夹。当漫画更新时,就会将最新那集下载到这个文件夹中。

第五步:想要追踪时,就开着这个软件。当漫画更新,会有以下提示:

PS:你可能会说577不是已经出了吗?这是BUG吗?不是,这是我为了演示,修改配置文件造成的

 

4. 下载

a. Tracker V1.1: http://115.com/file/c2k6ztfr#

b. JVM:http://java.com/en/download/inc/windows_upgrade_ie.jsp

PS:当无法打开Tracker时,才下载JVM

[转载]图片热点的使用area标签的用法

mikel阅读(1040)

[转载]图片热点的使用,html 的用法 – Cherish You – 博客园.

<area>标记主要用于图像地图,通过该标记可以在图像地图中设定作用区域(又称为热点),这样当用户的鼠标移到指定的作用区域点击时,会自动链接到预先设定好的页面。其基本语法结构如下:

      <area  class=type  id=Value  href=url  alt=text  shape=area-shape coods=value>

  class和id:是分别指定热点的类型和id号。

  alt:用于设定热点的替代性文字。

  href:用于设定该热点所链接的url地址。

  shape和coords:是两个主要的参数,用于设定热点的形状和大小。其基本用法如下:

  <area shape=”rect” coords=”x1, y1,x2,y2″ href=url>表示设定热点的形状为矩形,左上角顶点坐标为(X1,y1),右下角顶点坐标为(X2,y2)。

  <area shape=”circle” coords=”x1, y1,r” href=url>表示设定热点的形状为圆形,圆心坐标为(X1,y1),半径为r。

  <area shape=”poligon” coords=”x1, y1,x2,y2 ……” href=url>表示设定热点的形状为多边形,各顶点坐标依次为(X1,y1)、(X2,y2)、(x3,y3) ……。

       备注:x1, y1,x2,y2 这几个点的位置 是根据图片而定的,不是根据窗口的大小而定。

        <area>标记是在图像地图中划分作用区域的,因此其划分的作用区域必须在图像地图的区域内,所以在用 <area> 标记划分区域前必须用HTML的另一个标记<map>来设定图像地图的作用区域,并为指定的图像地图设定名称,该标记的用法很简单, 即<map name=”图像地图名称”> …… </map>。

    下面通过一个例子来说明这两个标记的用法:

  这里是一幅新书架的图片,要做的效果是:当鼠标点“网址大全”这本书时,新开一窗口,显示关于这本书的简介及订单的网页 (urlall.htm);当鼠标点“网站设计攻略”这本书时,新开一窗口,显示关于这本书的简介及订单的网页(siteall.htm);当鼠标点“网 页技巧大全”这本书时,新开一窗口,显示关于这本书的简介及订单的网页(pagejqlall.htm)。制作方法:

1、插入图片,并设置好图像的有关参数,且在<img>标记中设置参数usemap=”newbook” ismap,以表示对图像地图(newbook)的引用;

2、用<map>标记设定图像地图的作用区域,并取名为:newbook;

3、分别用<area>标记针对三本书的位置划分出三个矩形作用区域,并设定好其链接参数href。

制作完成,本例的源代码如下:

<img src=”http://www.webjx.com/images/logo.gif” width=”207″ height=”148″ alt=”新书架” hspace=”10″ align=”left” usemap=”#newbook” border=”0″>
<map name=”newbook”>
<area shape=”rect” coords=”56,69,78,139″ href=”urlall.htm” target=”_blank” alt=”这里收集十万多个网址。” title=”这里收集十万多个网址。”>
<area shape=”rect” coords=”82,70,103,136″ href=”siteall.htm” target=”_blank” alt=”网站设计师的启蒙读本。” title=”网站设计师的启蒙读本。”>
<area shape=”rect” coords=”106,68,128,136″ href=”pageall.htm” target=”_blank” alt=”网页制作者不可不读的书。” title=”网页制作者不可不读的书。”>
</map>

  在制作本文介绍的效果时应注意的几点:

1、在<img>标记不要忘记设置usemap、ismap参数,且usemap的参数值必须与<map>标记中的name参数值相同,也就是说,“图像地图名称”要一致;

2、同一“图像地图”中的所有热点区域都要在图像地图的范围内,即所有<area>标记均要在<map>与</map>之间;

3、在<area>标记中的 cords 参数设定的坐标格式要与shape参数设定的作用区域形状配套,避免出现在shape参数设置的矩形作用区域,而在cords 中设置的却是多边形区域顶点坐标的现象出现。

[转载]在windows下使用git客户端,github源码库以及eclipse的git插件-egit的使用

mikel阅读(1106)

[转载]在windows下使用git客户端,github源码库以及eclipse的git插件-egit的使用 – minvt – 博客园.

在windows下使用git客户端,github源码库以及eclipse的git插件-egit的使用

 

#{

//v0.1//120314

简单记录

?//v0.2?

}#

 

这段时间,公司的源码库从svn迁移到了github上,从svn换用git的过程经历了一些曲折.在此先简单记录一下.

 

关于git与svn

刚开始搞不明白git的区别,以为和svn差不多少,稍微使用了一下才发现区别较大.

svn
首先svn是在远端或者本地建立一个源码数据库,源码和版本变更都记录在其中.本地当前项目下会有隐藏的.svn文件,记

录一些当前项目的元信息,以使本地当前项目能和源码数据库中的信息接驳起来.

git
至于git比较特别,首先git会索性要求本地必须有一个源码仓库,把项目元信息也记录其中.有些人在这边可能分不清,因

为会看见两种情况,有人会一个项目建立一个源码仓库,有人是用一个集中的源码仓库,一般来说,应该使用后者吧.而提

交代码变更,即commit即为向本地源码库提交.然后在远端有一个git server,比如github,其实就是另一个源码版本库的

所在地.这里会有push,pull的概念,看来git更注重同步的理念.无论你在本地commit多少次,git server的源码库是不会

变化的,此时你要做的是,将本地源码库和远端源码库同步!这就是关键所在,你要使用push,将源码库的变更push上去.至

于pull,当然是拖下来.这样的好处显而易见,即时没有在网,你也可以随时使用版本控制功能.
但是这里我还有一些不明白的地方,就是多人开发时,不同版本库的同步冲突如何解决,因为实际上比svn多了一步,不知

道会不会很麻烦,后续研究.

在windows上使用git
windows在专业领域不愧为万年二等公民啊,不提也罢,不提也罢 – –

如何在eclipse里面使用git?

大家肯定知道,既然是eclipse,那么会有一个插件,嗯,这个传说中的插件叫做egit.
貌似现在的eclipse已经自带了这个源,你可以直接搜这个插件,或者手动的从源下载,但是eclipse并没有给这个源一个

名字,所以你添加源的话会提示你已经存在,你可以这样:

1 help->install new software
2 点击最上边的输入框的下面一行的”Available Software Sites”
3 看见”type filter text”没有? 输入”egit”,选定,edit,name咱就填个”egit”
4 好,回来,这时候插件源的下拉菜单里应该会有egit了,你选择,然后把那些乱七八糟的都装上吧,你肯定已经干了很多

次了.

这里要说一下,这个egit可不是一个gui而已,而是真的包含了可执行命令工具,但是这个东西仍在发展中…..对,会有点

儿蛋疼.
装好了吧,现在你在项目上右键单击,然后”team”里面的功能就是git的功能了,别和svn管理的项目弄混了哦.
基本的使用方法你可以参照这里:
http://jiangli.easymorse.com/?p=783

还有这里:
http://www.open-open.com/lib/view/open1328435726296.html
这个是一系列文章,不过有的稍微过时或者不详细,所以仅供参考,要多思考,不要怕.
比如”use or create repository in parent folder of project”,我才不会这样干啦,比如你放到eclipse的workspace

里肯定会很乱的.找个地方集中存放我觉得不错.

那个home变量是存放配置文件的目录.
至于你会遇到”ref”,”master”,”branch”神马的,首先,我也没搞太清楚 – –
但是,ref应该是指项目的引用,比如一个branch也是一个ref,它是一个变量,HEAD就是当前的最后一个进入仓库的项目吧

,master,顾名思义吧.
以上就是在windows上,eclipse IDE下使用git的基本套路,下面,要与github结合了 – –
———————————————————————————–
首先,不要嫌冗余,
在github的官方有一个纯命令行git工具使用的教程,就是egit封装的那个玩意,按照这个教程配置.稍微看一下基本命令

的使用.
http://help.github.com/win-set-up-git/
先看 Download and Install Git 到这里先,

然后我要说一下,貌似git传输默认是使用ssh2协议,而ssh2协议有多种验证方式,密码可以,密码加证书,或者纯证书,就

是非对称加密的密钥啦,自己拿着私钥,把公钥放到server上,然后两边一对,server就知道是你了.
github就是用这种私钥公钥大家来配对的方式,当然,也有http协议的,其实是https,但是不知道是不是因为前段时间被

攻击,还是第一次上传比较重要,反正我push项目必须要用ssh2的方式,上去后才能看见https.翻墙的同志们可能知道一

些,不过经常跟win打交道不和linux打交道的童鞋应该会陌生,因为win根本就不原生支持ssh2.

首先,你得有钥匙,嗯,eclipse本身有这个工具,但是…别用,木有hosts文件,坑死爹了,我在这绕了一天啊,对,尼玛还要

个hosts文件.所以,前面安装的git bash有用了.
http://help.github.com/win-set-up-git/后面的看完吧,linux下默认的ssh文件貌似是在.ssh文件夹下,win的默认

位置是用户目录(别问俺神马叫用户目录 – -,你打开cmd看看默认路径)的ssh文件夹下,按照官方推荐的做完全套.

其中最重要的是,把生成的密钥,还有hosts文件,拷到当前用户目录的ssh文件夹下.win7和xp不一样.

我没干之前,直接用egit遇到了”Warning:Permanently added ‘github.com,207.97.227.239’ (RSA) to the list of

know hosts.
Permission denied (publickey)”
这个狗屎问题,搜了很久很久没有确切说法,stackoverflow也看了,都没说清啊.

看到”…access”之后谢天谢地吧.

后面的命令行里让你配置user.name神马的东西眼熟吧,和egit里面一个意思.
你用文本编辑器都行.

T_T

然后!!然后,然后你终于可以在eclipse里面使用egit的push了,先commit再push,如果本地都没货你没东西push上去啊.
弹出来账户密码神马的,github版本库的位置会给你个链接,
比如”git@github.com:xxbirdman/xxProject.git“,这个就是个ssh2的链接,填在第一行URI,后面会帮你填充.协议也不

需要你动手.重点来了:
嗯,童鞋,也许你很聪明,但是绝对记住,下面的账户密码位置虽然只写了个git,但是可别自作多情去填上github的帐号密

码,不然你会很痛苦的,比如遇到神马”Exception caught during execution of ls-remote command”的狗血问题,原因

很简单,github采用了纯rsa的验证方式,只要你的私钥配上了公钥,用公共账户git登录即可,绝对不需要画蛇添足的加上

帐号密码,那样反而会出错,如果以后使用https的话,那就可以填上帐号密码了,另外记得选上记住密码,然后,跳转,再然

后,建议一般人点击”Add All Branches Spec”吧,然后finish.
这里是让你选择,你要同步版本库的那些branch上去的,每个branch都是个ref嘛,master也是一个branch嘛,HEAD,你懂的

,一般人应该是都同步吧 – –

这里貌似和svn中默认常见整天念叨的branch,trunk,tag有点区别,其实也没有本质区别啦.你把trunk和tag也看成一

种branch好了.

对了,小乌龟也有git版,叫TortoiseGit,你懂的.
最后,感谢很多人的分享,大家也可以参考以下链接:

github的帮助
http://help.github.com/

官方文档的中译
http://blog.csdn.net/xianqiang1/article/details/6944042

git中文魔法书//手册啦,有耐心翻翻
https://docs.google.com/View?

id=dfwthj68_675gz3bw8kj&pli=1#_1_41281264953870145_601701371_489039059728384

Eclipse上GIT插件EGIT使用手册,这一系列文章真心不错,再推荐一次
http://www.open-open.com/lib/view/open1328435802187.html

这是俺遇到苦逼问题时候看见的一位曾经同样倒霉过的大哥分享的内容 T_T
http://blog.csdn.net/ddlylly/article/details/7095809

这里有提到eclipse工具生成rsa密钥对的一瞥
http://freewind.me/blog/20111114/578.html

http://www.cnblogs.com/babykick/archive/2011/12/01/2271299.html
http://www.lixinyang.com/2011/05/windows-eclipse-github/
http://blog.sina.com.cn/s/blog_6b8d6ed60100zndn.html

 

本来想写一点点,结果貌似又飞了差不多两三个小时,写得有点乱,还不是很详细,命令行的使用也不熟悉,以后有空再补

充吧,多谢分享经验的各位.有错误以及不明白的地方请大家帮忙指出来.

[转载]使用事务操作SQLite数据库和一些常用的SQL语句

mikel阅读(1154)

[转载]使用事务操作SQLite数据库和一些常用的SQL语句 – forrest001 – 博客园.

使用SQLiteDatabase的beginTransaction()方法可以开启 一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。使用例子如下: SQLiteDatabase db = ….;
db.beginTransaction();//开始事务
try {
db.execSQL(“insert into person(name, age) values(?,?)”, new Object[]{“传智播客”, 4});
db.execSQL(“update person set name=? where personid=?”, new Object[]{“传智”, 1});
db.setTransactionSuccessful();//调用此方法会在执行到endTransaction() 时提交当前事务,如果不调用此方法会回滚事务
} finally {
db.endTransaction();//由事务的标志决定是提交事务,还是回滚事务
}
db.close();
上面两条SQL语句在同一个事务中执行。

一些常见的SQL语句:

CREATE TABLE person (_id integer primary key autoincrement, name varchar(20))
SQLite可以解析大部分标准SQL语句,如:
查询语句:select * from 表名 where 条件子句 group by 分组字句 having … order by 排序子句
如:select * from person
select * from person order by id desc
select name from person group by name having count(*)>1
分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录
select * from Account limit 5 offset 3 或者 select * from Account limit 3,5
插入语句:insert into 表名(字段列表) values(值列表)。如: insert into person(name, age) values(‘传智’,3)
更新语句:update 表名 set 字段名=值 where 条件子句。如:update person set name=‘传智‘ where id=10
删除语句:delete from 表名 where 条件子句。如:delete from person  where id=10

创建数据库表

db.execSQL(“CREATE TABLE person (_id integer primary key autoincrement, name varchar(20), amount integer)”);//执行有更改的sql语句

删除数据库

db.execSQL(“DROP TABLE IF EXISTS person”);

插入一条数据

db.execSQL(“insert into person (name,amount) values(?,?)”, new Object[]{person.getName(),person.getAmount()});

更新一条数据

db.execSQL(“update person set name=? where _id=?”,  new Object[]{person.getName(),person.getId()});

删除一条数据

db.execSQL(“delete from person where _id=?”, new Object[]{id.toString()});

查询一条数据

Cursor cursor = db.rawQuery(“select * from person where _id=?”, new String[]{id.toString()});

分页

Cursor cursor = db.rawQuery(“select * from person limit ?,?”, new String[]{offset.toString(), maxResult.toString()});

返回游标

db.rawQuery(“select _id as _id, name, amount from person limit ?,?”,new String[]{offset.toString(), maxResult.toString()});

得到总数

db.rawQuery(“select count(*) from person”, null);

[转载]JQuery.Uploadify asp.net(C#)文件多文件上传插件

mikel阅读(1199)

[转载]JQuery.Uploadify asp.net(C#)文件,多文件上传插件.

Uploadify是JQuery的一个上传插件,带进度显示, 支持多文件上传。不过官方提供的实例时php版本的

Uploadify唯一的缺点就是不支持中文按钮

官方下载  官方文档  官方演示

实现

Uploadify实现最低要求:

  • JQuery 1.4.x or greater
  • swfObject 2.2 or greater
  • Flash Player 9.0.24 or greater所需文件
  • cancel.png
  • JQuery.uploadify.v2.1.4.min.js
  • jQuery-1.4.2.min.js
  • swfobject.js
  • uploadify.css
  • uploadify.php
  • uploadify.swf基本代码
<script type="text/javascript" src="/uploadify/jquery-1.4.2.min.js"></script><script type="text/javascript" src="/uploadify/swfobject.js"></script>
<script type="text/javascript" src="/uploadify/jquery.uploadify.v2.1.4.min.js"></script><script type="text/javascript">// <![CDATA[
    $(document).ready(function() {   $('#file_upload').uploadify({     'uploader'  : '/uploadify/uploadify.swf',     'script'    : '/uploadify/uploadify.php',     'cancelImg' : '/uploadify/cancel.png',     'folder'    : '/uploads',     'auto'      : true   }); });
// ]]></script>

确保你有上传的文件夹的写入权限.

<input id="uploadify" type="file" name="uploadify" />

<a href="javascript:$('#uploadify').uploadifyUpload()">上传</a>|
<a href="javascript:$('#uploadify').uploadifyClearQueue()">取消上传</a>

主要参数

示例:

$(document).ready(function() {
$('#fileInput1').fileUpload({
'uploader': 'uploader.swf',//不多讲了
'script': '/AjaxByJQuery/file.do',//处理Action
'cancelImg': 'cancel.png',
'folder': '',//服务端默认保存路径
'scriptData':{'methed':'uploadFile','arg1','value1'},
//向后台传递参数,methed,arg1为参数名,uploadFile,value1为对应的参数值,服务端通过request["arg1"]
'buttonText':'UpLoadFile',//按钮显示文字,不支持中文,解决方案见下
//'buttonImg':'图片路径',//通过设置背景图片解决中文问题,就是把背景图做成按钮的样子
'multi':'true',//多文件上传开关
'fileExt':'*.xls;*.csv',//文件过滤器
'fileDesc':'.xls',//文件过滤器 详解见文档
'onComplete' : function(event,queueID,file,serverData,data){
//serverData为服务器端返回的字符串值
alert(serverData);
}
});
});
scriptData
向后台传递参数,methed,arg1为参数名,uploadFile,value1为对应的参数值,服务端通过request.getP
onComplete中serverData
后台传回前台的值
可选参数

uploadify函数的参数为json格式,可以对json对象的key值的修改来进行自定义的设置,如multi设置为true或false来控制是否可以进行多文件上传,下面就来介绍下这些key值的意思:

uploader : uploadify.swf 文件的相对路径,该swf文件是一个带有文字BROWSE的按钮,点击后淡出打开文件对话框,默认值:uploadify.swf。
script :   后台处理程序的相对路径 。默认值:uploadify.php
checkScript :用来判断上传选择的文件在服务器是否存在的后台处理程序的相对路径
fileDataName :设置一个名字,在服务器处理程序中根据该名字来取上传文件的数据。默认为Filedata
method : 提交方式Post 或Get 默认为Post
scriptAccess :flash脚本文件的访问模式,如果在本地测试设置为always,默认值:sameDomain
folder :  上传文件存放的目录 。
queueID : 文件队列的ID,该ID与存放文件队列的div的ID一致。 进度条放置的位置

  • image
    queueSizeLimit : 当允许多文件生成时,设置选择文件的个数,默认值:999 。
    multi : 设置为true时可以上传多个文件。
    auto :设置为true当选择文件后就直接上传了,为false需要点击上传按钮才上传 。fileDesc :这个属性值必须设置fileExt属性后才有效,用来设置选择文件对话框中的提示文本,如设置fileDesc为“请选择rar doc pdf文件”,打开文件选择框效果如下图:imagefileExt : 设置可以选择的文件的类型,格式如:’*.doc;*.pdf;*.rar’ 。
    sizeLimit : 上传文件的大小限制 。
    simUploadLimit : 允许同时上传的个数 默认值:1 。
    buttonText : 浏览按钮的文本,默认值:BROWSE 。
    buttonImg : 浏览按钮的图片的路径 。
    hideButton : 设置为true则隐藏浏览按钮的图片 。
    rollover : 值为true和false,设置为true时当鼠标移到浏览按钮上时有反转效果。
    width : 设置浏览按钮的宽度 ,默认值:110。
    height : 设置浏览按钮的高度 ,默认值:30。
    wmode : 设置该项为transparent 可以使浏览按钮的flash背景文件透明,并且flash文件会被置为页面的最高层。 默认值:opaque 。
    cancelImg :选择文件到文件队列中后的每一个文件上的关闭按钮图标,如下图:

    image

    上面介绍的key值的value都为字符串或是布尔类型,比较简单,接下来要介绍的key值的value为一个函数,可以在选择文件、出错或其他一些操作的时候返回一些信息给用户。

    onInit : 做一些初始化的工作

    onSelect :选择文件时触发,该函数有三个参数

  • event:事件对象。
  • queueID:文件的唯一标识,由6为随机字符组成。
  • fileObj:选择的文件对象,有name、size、creationDate、modificationDate、type 5个属性。
$(document).ready(function()
{
$("#uploadify").uploadify({
'uploader': 'JS/jquery.uploadify-v2.1.0/uploadify.swf',
'script': 'UploadHandler.ashx',
'cancelImg': 'JS/jquery.uploadify-v2.1.0/cancel.png',
'folder': 'UploadFile',
'queueID': 'fileQueue',
'auto': false,
'multi': true,
'onInit':function(){alert("1");},
'onSelect': function(e, queueId, fileObj)
{
alert("唯一标识:" + queueId + "\r\n" +
"文件名:" + fileObj.name + "\r\n" +
"文件大小:" + fileObj.size + "\r\n" +
"创建时间:" + fileObj.creationDate + "\r\n" +
"最后修改时间:" + fileObj.modificationDate + "\r\n" +
"文件类型:" + fileObj.type
);

}
});
});

onSelectOnce :在单文件或多文件上传时,选择文件时触发。该函数有两个参数event,data,data对象有以下几个属性:
fileCount:选择文件的总数。
filesSelected:同时选择文件的个数,如果一次选择了3个文件该属性值为3。
filesReplaced:如果文件队列中已经存在A和B两个文件,再次选择文件时又选择了A和B,该属性值为2。
allBytesTotal:所有选择的文件的总大小。

onCancel : 当点击文件队列中文件的关闭按钮或点击取消上传时触发。该函数有event、queueId、fileObj、data四个参数,前三个参数同onSelect 中的三个参数,data对象有两个属性fileCount和allBytesTotal。
fileCount:取消一个文件后,文件队列中剩余文件的个数。
allBytesTotal:取消一个文件后,文件队列中剩余文件的大小。

onClearQueue :当调用函数fileUploadClearQueue时触发。有event和data两个参数,同onCancel 中的两个对应参数。

onQueueFull :当设置了queueSizeLimit并且选择的文件个数超出了queueSizeLimit的值时触发。该函数有两个参数event和queueSizeLimit。

onError :当上传过程中发生错误时触发。该函数有event、queueId、fileObj、errorObj四个参数,其中前三个参数同上,errorObj对象有type和info两个属性。
type:错误的类型,有三种‘HTTP’, ‘IO’, or ‘Security’
info:错误的描述

onOpen :点击上传时触发,如果auto设置为true则是选择文件时触发,如果有多个文件上传则遍历整个文件队列。该函数有event、queueId、fileObj三个参数,参数的解释同上。

onProgress :点击上传时触发,如果auto设置为true则是选择文件时触发,如果有多个文件上传则遍历整个文件队列,在onOpen之后触发。该函数有 event、queueId、fileObj、data四个参数,前三个参数的解释同上。data对象有四个属性percentage、 bytesLoaded、allBytesLoaded、speed:
percentage:当前完成的百分比
bytesLoaded:当前上传的大小
allBytesLoaded:文件队列中已经上传完的大小
speed:上传速率 kb/s

onComplete:文件上传完成后触发。该函数有四个参数event、queueId、fileObj、response、data五个参数,前三个参数同上。response为后台处理程序返回的值,在上面的例子中为1或0,data有两个属性fileCount和speed
fileCount:剩余没有上传完成的文件的个数。
speed:文件上传的平均速率 kb/s

$('#file_upload').uploadify({
'uploader' : '/uploadify/uploadify.swf',
'script' : '/uploadify/uploadify.php',
'cancelImg' : '/uploadify/cancel.png',
'folder' : '/uploads',
'multi' : true,
'onComplete' : function(event, ID, fileObj, response, data) {
alert('There are ' + data.fileCount + ' files remaining in the queue.');
}
});

注:fileObj对象和上面讲到的有些不太一样,onComplete 的fileObj对象有个filePath属性可以取出上传文件的路径。

onAllComplete:文件队列中所有的文件上传完成后触发。该函数有event和data两个参数,data有四个属性,分别为:
filesUploaded :上传的所有文件个数。
errors :出现错误的个数。
allBytesLoaded :所有上传文件的总大小。
speed :平均上传速率 kb/s

$('#file_upload').uploadify({
'uploader' : '/uploadify/uploadify.swf',
'script' : '/uploadify/uploadify.php',
'cancelImg' : '/uploadify/cancel.png',
'folder' : '/uploads',
'onAllComplete' : function(event,data) {
alert(data.filesUploaded + ' files uploaded successfully!');
}
});

在上面的例子中已经用了uploadifyUpload和uploadifyClearQueue两个函数,除此之外还有几个函数:

uploadifySettings:可以动态修改上面介绍的那些key值,如下面代码

$('#uploadify').uploadifySettings('folder','JS');

如果上传按钮的事件写成下面这样,文件将会上传到uploadifySettings定义的目录中

<a href="javascript:$('#uploadify').uploadifySettings('folder','JS');
$('#uploadify').uploadifyUpload()">上传</a>

uploadifyCancel:该函数接受一个queueID作为参数,可以取消文件队列中指定queueID的文件。

$('#uploadify').uploadifyCancel(id);

常见错误:

1.文件大小超了.

image

后端接收代码

public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Charset = "utf-8";

HttpPostedFile file = context.Request.Files["Filedata"];
string uploadPath =
HttpContext.Current.Server.MapPath(@context.Request["folder"]) + "\\";

if (file != null)
{
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
file.SaveAs(uploadPath + file.FileName);
//下面这句代码缺少的话,上传成功后上传队列的显示不会自动消失
context.Response.Write("上传成功!");
}
else
{
context.Response.Write("0");
}
}

源码下载: Uploadify.zip

[原创]ASP.NET MVC中EasyUI的datagrid跨域调用

mikel阅读(1258)

最近项目中需要跨域调用其他项目的数据,其他项目也是使用的EasyUI的datagrid组件,开始以为直接在datagrid的url属性定义为其他项目的url地址即可,可是测试下发现的确是返回了json数据但是json数据提示“invalid label” 错误,网上搜索了下错误解决办法,参考 “JavaScript处理Json的invalid label错误解决办法“的方法利用datagrid的loadData方法加载并转换了json还是提示上述错误,感觉原因不在格式问题。

搜索了下JavaScript跨域调用的文章“JavaScript跨域访问问题解决方法”得到启发,发现原来是因为easyUI使用的是JQuery的异步方法加载数据,应该遵循JQuery的跨域访问规则,也就是上述文章中提到的url中需要加入jsoncallback=?回调函数参数,并且返回的json的格式必须修改为:回调函数名(json数据),而现在返回的数据只是json格式的数据没有回调函数名,自然提示格式错误,于是修改了ASP.NET MVC自定义的JsonResult类,具体如何编写自定义的JsonResult类见:自定义ASP.NET MVC JsonResult序列化结果

代码如下:

public class CustomJsonResult:JsonResult
{
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException(&quot;context&quot;);
}

HttpResponseBase response = context.HttpContext.Response;

if (!String.IsNullOrEmpty(ContentType))
{
response.ContentType = ContentType;
}
else
{
response.ContentType = &quot;application/json&quot;;
}
if (ContentEncoding != null)
{
response.ContentEncoding = ContentEncoding;
}
if (Data != null)
{
#pragma warning disable 0618
//跨域调用需要修改json格式jsoncallback
if (context.HttpContext.Request.Params.AllKeys.Contains(&quot;jsoncallback&quot;))
{
String callback = context.HttpContext.Request.Params[&quot;jsoncallback&quot;];
response.Write(callback+&quot;(&quot;+JsonConvert.SerializeObject(Data)+&quot;)&quot;);
}
else
{
response.Write(JsonConvert.SerializeObject(Data));
}
#pragma warning restore 0618
}
}
}

EasyUI的datagrid的代码如下:

    //datagrid
    $('#dg').datagrid({
        url:'http://localhost:9000/ManagementSystem/ListCurrent?department=sss&amp;jsoncallback=?',
        pageNumber: 1,
        pageSize: 20,
        pageList: [20, 40, 60, 80, 100],
        onDblClickRow: function(rowIndex) {
            edit();
        }
    });