[转载][MSSQL]如何高效查询表的总记录数 - kkun - 博客园

mikel阅读(1046)

[转载][MSSQL]如何高效查询表的总记录数 – kkun – 博客园.

如何高效查询表的总记录数?[总结-整理-马克]

首先想到的自然是在表主键上应用COUNT函数来查询了,这个是目前使用最多的方法,没有之一

复制代码
SELECT COUNT(1) ROWS FROM product
复制代码

这里再给出一些其它方法,这些方法或多或少会有一些限制,或者看起来不是那么”完美”,但依然有一定的借鉴意义,信息量不大,请客官慢用

另类方法1

充分利用系统自带的存储过程SP_SPACEUSED,详细的使用方式推荐谷哥或度娘,看代码

复制代码
EXEC SP_SPACEUSED 'PRODUCT'
复制代码

 

结果如下图所示

 

另类方法2

根据国际惯例,很多表都会设计一个步长为1的自增长整型(INT)列作为表主键,该做法优劣这里不展开讨论,仅基于这一”习惯”,外加一个假设:该字段连续无为断,则可以使用MAX函数了,限制较多哈

1,自增长列

2,该列连续

复制代码
SELECT MAX(ProductCode) TotalCount FROM Product
复制代码

输出

如果我有这样的自增主键表,可是不连续,那就不能用咯?其实您可以使用ROW_NUMBER()函数进行修复,再取MAX是一样的,为了不至于太水,这里仍然归为另类方法2,复习ROW_NUMBER的同学点这里

 

另类方法3

充分使用系统表中的信息,优点是速度够快!缺点是数据不精确,所以要结合您自身项目的特点来判定是否适合使用该方法,代码奉上

复制代码
SELECT ROWS FROM [sysindexes] WHERE id = OBJECT_ID('product') and indid < 2
复制代码

输出结果

另类方法3修复数据不精确方法,执行以下SQL脚本即可,请不要在生产环境使用!

复制代码
DBCC UPDATEUSAGE(0, 'product') with COUNT_ROWS
复制代码

 

该脚本执行后输出:DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

 

另类方法4,虚席以待,期待您的精彩点评!

 

上边介绍了一些系统表,系统存储过程,猜测您可能对下边的文章感兴趣

SQL SERVER 2008 函数大全 – 字符串函数

SQL2008系统统计函数

[MSSQL]GROUPING SETS,ROLLUP,CUBE初体验

[MSSQL]ROW_NUMBER函数

[MSQL]RANK函数

[MSSQL]NTILE另类分页有么有?!

[MSQL]也说SQL中显示星期几函数

[MSSQL]COALESCE与ISNULL函数

[MSSQL]PIVOT函数

[MSSQL]FOR XML AUTO I

[MSSQL]FOR XML AUTO II

[MSSQL]TRY…CATCH…通用格式

如果您喜欢该博客请点击右下角推荐按钮,您的推荐是作者创作的动力!

——————————————
除非特别声明,文章均为原创,版权与博客园共有,转载请保留出处

[转载]Jquery轻量级幻灯插件-OWL Carousel--支持触屏的移动浏览器 - 凤凰涅磐360yi - 博客园

mikel阅读(1174)

[转载]Jquery轻量级幻灯插件-OWL Carousel–支持触屏的移动浏览器 – 凤凰涅磐360yi – 博客园.

在项目中,需要做一个幻灯功能,领导说需要一个小清醒的啊,轻量级的。刚开始搜索到这个:

 CRAFTYSLIDE插件。但是用起来比较麻烦。后来找到这个JQuery 插件:OWL Carousel。咋起了这么个名字,真是不明白。

反正好用就行吧。很好用,分享给大家。

首先是说明一下OWL Carousel幻灯的主要功能。

  1. JQuery插件,品牌好,哈哈。基于JQuery开发,比较稳定

  2. 文件小。Css+js不到10k,压缩之后。

  3. 支持触屏。经过测试,在Android手机的主流浏览器:QQ、百度、UC、微信内置浏览器等支持

  4. 响应式设计。支持不用屏幕、触屏。支持div、图片等。支持全部显示、单个显示

  5. 简洁代码,使用方便

     

Demo截图:

支持div如下图.div内容你自己定义就行

jqueryOWL Carousel使用说明

 

 

 

 

 

 

 

支持图片

jqueryOWL Carousel使用说明

 

 

 

 

 

 

支持单个项目显示

jqueryOWL Carousel使用说明

 

 

 

 

 

 

 

 

使用方法:

引用js和css文件

复制代码
<!-- Basic stylesheet -->
<link rel="stylesheet" href="owl-carousel/owl.carousel.css">

<!-- Default Theme -->
<link rel="stylesheet" href="owl-carousel/owl.theme.css">

<!-- You can use latest version of jQuery  -->
<script src="jquery-1.9.1.min.js"></script>

<!-- Include js plugin -->
<script src="assets/owl-carousel/owl.carousel.js"></script>
复制代码

 

在你的页面中,创建一下结构的html代码:

复制代码

View Code

复制代码

 

最后,调用OWL Carousel插件提供的方法:

复制代码
$(document).ready(function() {

  $("#owl-example").owlCarousel();

});
复制代码

 

是不是很简单?

OWL Carousel参数说明:

参数 默认值 说明
slideSpeed 200 滑动间隔时间,毫秒
paginationSpeed false 是否支持分页
autoPlay false 是否自动播放。
goToFirst true 回到首页
goToFirstSpeed 1000 回到首页时间
stopOnHover false 设置成true不支持触摸
navigation false 是否显示上一个和下一个按钮。
navigationText [“prev”,”next”] 显示上下页的文字。不需要的话设置成false:“navigationText : false”
pagination true 显示分页
paginationNumbers false 是否显示分页数字
responsive true 是否开启响应式设计
items 5 一次展示项目个数
itemsDesktop [1199,4] 在桌面宽度受限的情况,显示项目数
itemsDesktopSmall [979,3] 同上
itemsTablet [768,2] 同上
itemsMobile [479,1] 同上
baseClass “owl-carousel” 样式
theme “owl-theme” 使用的主题

 外部调用的api接口:

1
<span style="font-size: 14px;"> </span>
复制代码
//Initialize Plugin
$(".owl-carousel").owlCarousel()

//get carousel instance data and store it in variable owl
var owl = $(".owl-carousel").data('owlCarousel');

//Public methods
owl.next()   // Go to next slide
owl.prev()   // Go to previous slide
owl.goTo(x)  // Go to x slide
 
owl.update() // Update Slide
 
owl.buildControlls()    // Build Controlls
owl.destroyControlls()  // Remove Controlls
 
owl.play() // Autoplay
owl.stop() // Autoplay Stop
复制代码
1

实例代码:支持div滑动

复制代码
<div id="owl-example" class="owl-carousel owl-theme" style="opacity: 1; display: block; ">

                <div class="owl-wrapper-outer"><div class="owl-wrapper" style="width: 4680px; left: 0px; display: block; -webkit-transform: translate3d(0px, 0px, 0px); "><div class="owl-item" style="width: 234px; "><div class="item darkCyan">
                  <img src="assets/img/demo-slides/touch.png" alt="Touch">
                    <h3>Touch</h3>
                    <h4>Can touch this</h4>
                </div></div><div class="owl-item" style="width: 234px; "><div class="item forestGreen">
                  <img src="assets/img/demo-slides/grab.png" alt="Grab">
                    <h3>Grab</h3>
                    <h4>Can grab this</h4>
                </div></div><div class="owl-item" style="width: 234px; "><div class="item orange">
                  <img src="assets/img/demo-slides/responsive.png" alt="Responsive">
                    <h3>Responsive</h3>
                    <h4>Fully responsive!</h4>
                </div></div><div class="owl-item" style="width: 234px; "><div class="item yellow">
                  <img src="assets/img/demo-slides/css3.png" alt="CSS3">
                    <h3>CSS3</h3>
                    <h4>3D Acceleration.</h4>
                </div></div><div class="owl-item" style="width: 234px; "><div class="item dodgerBlue">
                  <img src="assets/img/demo-slides/multi.png" alt="Multi">
                    <h3>Multiply</h3>
                    <h4>Owls on page.</h4>
                </div></div><div class="owl-item" style="width: 234px; "><div class="item skyBlue">
                  <img src="assets/img/demo-slides/modern.png" alt="Modern Browsers">
                    <h3>Modern</h3>
                    <h4>Browsers Compatibility</h4>
                </div></div><div class="owl-item" style="width: 234px; "><div class="item zombieGreen">
                  <img src="assets/img/demo-slides/zombie.png" alt="Zombie Browsers - old ones">
                    <h3>Zombie</h3>
                    <h4>Browsers Compatibility</h4>
                </div></div><div class="owl-item" style="width: 234px; "><div class="item violet">
                  <img src="assets/img/demo-slides/controls.png" alt="Take Control">
                    <h3>Take Control</h3>
                    <h4>The way you you like</h4>
                </div></div><div class="owl-item" style="width: 234px; "><div class="item yellowLight">
                  <img src="assets/img/demo-slides/feather.png" alt="Light">
                    <h3>Light</h3>
                    <h4>As a feather</h4>
                </div></div><div class="owl-item" style="width: 234px; "><div class="item steelGray">
                  <img src="assets/img/demo-slides/tons.png" alt="Tons of Opotions">
                    <h3>Tons</h3>
                    <h4>of options</h4>
                </div></div></div></div> 

              <div class="owl-controlls clickable"><div class="owl-pagination"><div class="owl-page active"><span class=""></span></div><div class="owl-page"><span class=""></span></div></div></div></div>
复制代码

 项目地址:https://github.com/OwlFonk/OwlCarousel

demo地址:http://owlgraphic.com/owlcarousel/demos/images.html

[转载]浅谈Squid在图片存储架构中的应用 - IT青藤屋 - 青藤园

mikel阅读(1058)

[转载]浅谈Squid在图片存储架构中的应用 – IT青藤屋 – 青藤园.

将近快一个月没写文章了,太懒散了,今天振作了一下,写了篇关于Squid的文章,Squid作为分布式代理缓存服务器真的非常的棒,希望本文对你有帮助。

 

版权声明:非商业自由转载,保留原文内容完整性,并署名作者王国峰原文链接

 

前言

 

上一篇我表明了自己对缓存的立场:缓存一切可以缓存的资源。并讨论了如何利用IIS自身的缓存功能来轻松满足中小规模的图片缓存需求。关于IIS的客户端缓存和服务器端缓存的介绍大家可以回顾这篇文章。自从上一篇文章发表后,有不少朋友向我反馈:用IIS自身的缓存功能负载有限,建议使用Varnish或Squid。是的,我非常同意,所以我今天就和大家来探讨一下分布式代理缓存服务器Squid在图片存储架构中的应用,文中的一些观点,如有错误,敬请指出,谢谢。

 

Squid简介

 

Squid是一款高性能分布式代理缓存服务器,它一般用来做前置Web Cache,加快用户访问Web的速度。为了说明其运行过程,我将仍旧沿用我前一篇的YD风格,再一次请出人见人爱、花见花开、车见爆胎的空空老师,请读者自觉送出掌声:

 

Squid君是时下最受欢迎的空空作品代理人,为了让所有空空迷能更快捷地欣赏到高质量的空空作品,Squid君天天加班加点,整理和保存空空的最新作品,并对其作进一步的优化处理,比如去码。

有一天,我无聊至极,便打电话给Squid君,向他要最新的空空写真图(向Squid发出下载请求);

Squid君仔细辨别了一下我的声音,发现是老朋友,于是便答应了我的请求(Squid中的ACL访问控制,只接受合法的请求);

Squid君对我说他手头刚好有一周前的空空写真,问我看过没有,我说发过来看看呗,于是他很快发给了我(Squid缓存命中,下载极快,哦耶!);

我收到写真图,发现是两天前已经看过了的,于是告诉Squid君要最新的,Squid君看了看库存,发现手头没有最新的了,于是就说让我等一会儿,他去问问其他的代理兄弟有没有,我说好的,谢谢(Squid支持分布式集群方式,各个父子节点、兄弟节点之间的缓存数据可以互相同步);

结果空欢喜一场,他回来和我说其他兄弟也没有,当我非常失落的时候,他突然说空空今天来杭州,他可以直接向空空要写真,我一开心就对他说,快去快去(当Squid缓存不命中时,只能从源服务器获取数据);

过了好久,Squid君回来了,他说见空空的人实在太多了,排了好久的队才拿到她最新的写真图呢,我谢过之后他就把写真很快地发给了我。之后他说他一定要把这个写真保存起来,以便提供给其他空空迷和其他兄弟代理(Squid会把从源服务器获取的数据保存到自己的缓存中,如果下一个用户提出同样的下载请求,Squid直接把缓存中的数据给用户,当然也可以把数据奉送给其他兄弟代理,独乐乐不如众乐乐)。

 

到这里,我相信你已经大概明白Squid的工作过程了吧,下面我就对Squid特点做一下简要概括:

 

  1. 开源,基于GNU通用公共许可证,意味着你可以在同等开源协议下使用和修改Squid。
  2. 支持多种协议,目前支持http、ftp、gopher、wais、ssl等网络协议。
  3. 支持分布式集群,Squid使用TCP(HTTP)和UDP(ICP/HTCP)通讯来确定邻居cache的状态。
  4. 支持访问控制,通过设置ACL和ARL来限制某些访问。

 

Squid官方网站http://www.squid-cache.org/

 

你可以在官网上下载Squid以及阅读相关文档,当然接下来我也会用Chinese向大家介绍Squid的用法。

 

Squid配置详细说明

 

下面是一份详细的Squid的配置清单及其说明:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#http_port指令告诉squid在哪个端口侦听HTTP请求。默认端口是3128,除下面的形式外,也可以是http_port 192.168.63.50:3128
http_port 3128
icp_port 3130
#缓存目录的设置,可以设置多个缓存目录,语法为:<cache_dir> <aufs|ufs> <目录所在> <MBytes大小> <dir1> <dir2>
cache_dir ufs /var/spool/squid 1000 64 1024
#下面是关于日志文件的放置目录与文件名!
cache_access_log /var/log/squid/access.log
cache_log /var/log/squid/cache.log
cache_store_log /var/log/squid/store.log
pid_filename /var/run/squid.pid
#关闭认证机制,有些版本的 squid 会自动的加入代理认证机制,而普通情况下是不需要的,故找到包括auth_param的行,给它们加上注释
#auth_param basic children 5
#auth_param basic realm Squid proxy-caching web server
#auth_param basic credentialsttl 2 hours
#设置squid用户及用户组、管理员账号
cache_effective_user squid
cache_effective_group squid
cache_mgr youraccount@your.e.mail
# 与内存有关的配置:因为我的系统内存很小,所以只给 8 MB!如果您的物理内存很大的情况下,例如 512 MB,可以考虑加大到 64 或 128 MB。
cache_mem 128 MB
# 与磁盘容量有关的配置(注:下列的 90 与 95 是百分比 ),如果您的 cache_dir 所在磁盘很大时,可以考虑将 4096 改成 32768 KB
cache_swap_low 90
cache_swap_high 95
maximum_object_size 4096 KB
# 与内存保存资料有关的配置
maximum_object_size_in_memory 8 KB
#定义acl(访问控制列表), 语法为:acl<acl> <acl名称> <acl类型> <配置的内容>
#黑体为用户自定义部分
acl All src 0/0
acl Manager proto cache_object
acl Localhost src 127.0.0.1/32
acl Safe_ports port 80 21 443 563 70 210 280 488 591 777 1025-65535
acl SSL_ports 443 563
acl CONNECT method CONNECT
acl MyNetwork src 192.168.0.0/16
#利用前面定义的acl,定义访问控制规则
http_access allow Manager Localhost
http_access deny Manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow MyNetwork
http_access deny All
#定义与其它代理服务器的关系,语法: <cache_peer> <主机名称> <类别> <http_port> <icp_port> <其它参数>
cache_peer 192.168.60.6 parent 4480 7 no-query default
#设置与其它代理服务器的关系:
# <cache_peer_access> <上层 Proxy > <allow|deny> <acl名称>
#cache_peer_access 192.168.60.6 allow aclxxx
#cache_peer_access 192.168.60.6 deny !aclxxx
coredump_dir /var/spool/squid

注意:以上的配置说明来自这里

配置好以后,我们就可以启动squid了,启动的步骤如下:

 

1). 我们可以运行下面的命令来检查配置文件的正确性:

 

# squid -k parse

 

只有这一步正确你才可以进行下一步的操作

 

2). 初始化cache目录.即建立缓存目录的存储格式

 

只需在第一次启动squid服务之前执行(在初次运行squid之前,或者无论何时你增加了新的cache_dir,你必须初始化cache目录。)

 

# squid -z

 

cache目录初始化可能花费一些时间,依赖于cache目录的大小和数量,以及磁盘驱动器的速度。假如你想观察这个过程,请使用-X选项:

 

# squid -zX

 

3). 启动squid服务

 

# service squid start

 

假定squid安装在/usr/local/squid目录下,也可以

 

# /usr/local/squid/sbin/squid -sD

 

最后,我推荐你去看看Squid权威指南,并希望你可以利用Squid成功搭建一个分布式图片缓存系统,Squid真的很棒!

 

为了你和你家人的健康,转载请注明原文出处:http://www.itivy.com/ivy/archive/2012/3/10/squid-usage.html

另外,我觉得你可能还会对下面架构相关的文章感兴趣:
优酷网架构学习笔记
百万级访问量网站的技术准备工作
Facebook图片存储架构的学习
facebook图片存储架构技术全解析

[转载]茗洋Easy UI 1.3.2 部分问题解决系列专题[Combo模糊匹配中文问题 修复] - AaronYang - 博客园

mikel阅读(1327)

[转载]茗洋Easy UI 1.3.2 部分问题解决系列专题[Combo模糊匹配中文问题 修复] – AaronYang – 博客园.

本次给大家带来的EasyUI的我研究拓展的新特性

我使用的是  EasyUI 1.3.2版本的,项目是ASP.NET MVC3,但是本篇讲解用不上ASP.NET MVC,仅仅修改官方Demo你就知道怎么用了

但这次我都是自己修改EasyUI源码完成的

首先大家先下载官方的 EasyUI 1.3.2    【 下载 】 先保证大家都是在同一个起跑线的,放心吧,我会教你们怎么改的,还有思路

 

1. EasyUI Combo 在火狐和谷歌下 中文 模糊匹配问题

大家下载好官方的EasyUI的最新版1.3.2后,打开  属于你们的目录

\JQuery-easyui-1.3.2\demo\combobox 文件,截图如下

image

我们先看原先的效果,打开remotedata.html

image

效果:

last

通过这个,我们已经可以看到,EasyUI自带的匹配直接输英文的可以,如果通过中文状态的输入英文会不匹配,但是再按任何一个键时候又开始匹配了。英文都已经有这个问题了,那中文呢,当然也是。

我们替换这个文件下的

image

JSON代码如下,换成中文:

[{
    "id":1,
    "text":"山东省",
    "desc":"Write once, run anywhere"
},{
    "id":2,
    "text":"C#",
    "desc":"One of the programming languages designed for the Common Language Infrastructure"
},{
    "id":3,
    "text":"北京市",
    "selected":true,
    "desc":"A dynamic, reflective, general-purpose object-oriented programming language"
},{
    "id":4,
    "text":"上海市",
    "desc":"A high-level, general-purpose, interpreted, dynamic programming language"
},{
    "id":5,
    "text":"天津市",
    "desc":"A family of general-purpose, high-level programming languages"
}]

我就是把英文换成了中文,刷新那个页面,效果如下

zaogao

这样的自动匹配效果肯定不是你想要的吧

接下来我们修改 JQuery.easyui.min.js,我用Notepad++打开的

image

Ctrl+F查找 keydown.combo ,我的在9871行

image

image

有人说,将keydown.combo改成 keyup.combo,本人亲自试过,没用…

定位这行代码后,我们在9867行代码下

添加如下代码就可以解决

 

_75b.bind("input" ,function(e)
{
    if(_758.timer){
    clearTimeout(_758.timer);
    }
    _758.timer=setTimeout(function(){
    var q=_75b.val();
    if(_758.previousValue!=q){
    _758.previousValue=q;
    $(_757).combo("showPanel");
    opts.keyHandler.query.call(_757,_75b.val());
    _767(_757,true);
    }
    },opts.delay);
});

 

图解位置:

image

除了

_75b.bind("input" ,function(e)
{



其他代码:肯定不是我自己写的,我没那么神,只是看它的原理,这行代码下面有


});

是自己写的,其他的,是从下面粘贴过来的,在这里粘贴过来的(AaronYang)

image

把这行代码复制到上面去试试,就可以了

我修改好的js下载      【下载

刷新那个页面,我们继续再看下效果:

end

[转载]每日学习心得:SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析) - 星星之火116 - 博客园

mikel阅读(1485)

[转载]每日学习心得:SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析) – 星星之火116 – 博客园.

2013-8-20

1.    SQL查询表的行列转换/小计/统计(with  rollup,with cube,pivot解析)

在实际的项目开发中有很多项目都会有报表模块,今天就通过一个小的SQL查询统计来讲解一下实际开发中比较常用的行列转换/小计/统计等报表统计相关的常用知识点。

题目如下:

查询sales 和stores表,得出1993年每个store每季度销售数量及小计和总计,查询出的结果如下

其中sales表的数据结构如下:

其中stores表的数据结构如下:

1.1 普通方法(容易理解)

初看题目,第一感觉是竖表转横表,首先想到的是使用case when,

所以

第一步操作如下:

select st.stor_name,SUM(sa.qty) as Total,
       (case when datepart(qq,sa.ord_date)=1 then SUM(sa.qty) else 0 end) as Qtr1,
       (case when datepart(qq,sa.ord_date)=2 then SUM(sa.qty) else 0 end) as Qtr2,
      (case when datepart(qq,sa.ord_date)=3 then SUM(sa.qty) else 0 end) as Qtr3,
       (case when datepart(qq,sa.ord_date)=4 then SUM(sa.qty) else 0 end) as Qtr4
       from stores st left join sales sa
       on st.stor_id=sa.stor_id
       where DATEPART(yy,sa.ord_date)=1993
       group by st.stor_name,sa.ord_date

 

检索出结果如下:

这个时候由检索的结果可知,其中部分商店的统计信息没有合并统计,原因在于分组的时候我们是按商店名和日期分组的,

第二步操作,将第一步检索的信息,再次按店名分组统计,sql语句如下:

select A.stor_name as stor_name ,SUM(A.Total) as Total,SUM(A.Qtr1) as Qtr1,
       SUM(A.Qtr2) as Qtr2,SUM(A.Qtr3) as Qtr3,SUM(A.Qtr4) as Qtr4
       from
       (
       --按时间和stor_name分组统计出对应的stor一年的销售明细
       select st.stor_name,SUM(sa.qty) as Total,
       (case when datepart(qq,sa.ord_date)=1 then SUM(sa.qty) else 0 end) as Qtr1,
       (case when datepart(qq,sa.ord_date)=2 then SUM(sa.qty) else 0 end) as Qtr2,
       (case when datepart(qq,sa.ord_date)=3 then SUM(sa.qty) else 0 end) as Qtr3,
       (case when datepart(qq,sa.ord_date)=4 then SUM(sa.qty) else 0 end) as Qtr4
       from stores st left join sales sa
       on st.stor_id=sa.stor_id
       where DATEPART(yy,sa.ord_date)=1993
       group by st.stor_name,sa.ord_date) as A
group by A.stor_name

 

统计结果如下:

这个时候已经很接近标准答案了,但是还有一个统计行需要统计列出

第三步,将第二步统计的结果再和总计的结果Union一下就可以实现标准的结果

–对每个stor一年的销售明细进行汇总,之后按stor名分组

select A.stor_name as stor_name ,SUM(A.Total) as Total,SUM(A.Qtr1) as Qtr1,
       SUM(A.Qtr2) as Qtr2,SUM(A.Qtr3) as Qtr3,SUM(A.Qtr4) as Qtr4
       from
       (
       --按时间和stor_name分组统计出对应的stor一年的销售明细
       select st.stor_name,SUM(sa.qty) as Total,
       (case when datepart(qq,sa.ord_date)=1 then SUM(sa.qty) else 0 end) as Qtr1,
       (case when datepart(qq,sa.ord_date)=2 then SUM(sa.qty) else 0 end) as Qtr2,
       (case when datepart(qq,sa.ord_date)=3 then SUM(sa.qty) else 0 end) as Qtr3,
       (case when datepart(qq,sa.ord_date)=4 then SUM(sa.qty) else 0 end) as Qtr4
       from stores st left join sales sa
       on st.stor_id=sa.stor_id
       where DATEPART(yy,sa.ord_date)=1993
       group by st.stor_name,sa.ord_date) as A
group by A.stor_name
union
--汇总统计信息
select 'Total',SUM(Total),SUM(Qtr1),SUM(Qtr2),SUM(Qtr3),SUM(Qtr4) from
    (
    --每个store一年的销售明细
      select A.stor_name as stor_name ,SUM(A.Total) as Total,SUM(A.Qtr1) as Qtr1,
       SUM(A.Qtr2) as Qtr2,SUM(A.Qtr3) as Qtr3,SUM(A.Qtr4) as Qtr4
       from
       (
       select st.stor_name,SUM(sa.qty) as Total,
       (case when datepart(qq,sa.ord_date)=1 then SUM(sa.qty) else 0 end) as Qtr1,
       (case when datepart(qq,sa.ord_date)=2 then SUM(sa.qty) else 0 end) as Qtr2,
       (case when datepart(qq,sa.ord_date)=3 then SUM(sa.qty) else 0 end) as Qtr3,
       (case when datepart(qq,sa.ord_date)=4 then SUM(sa.qty) else 0 end) as Qtr4
       from stores st left join sales sa
       on st.stor_id=sa.stor_id
       where DATEPART(yy,sa.ord_date)=1993
       group by st.stor_name,sa.ord_date) as A
group by A.stor_name
) as B

 

执行之后就可以得出我们想要的结果。

总结一下解题的整个思路,首先看题目要求求出每个店铺每年,每季度的销售统计,同时最后还要有总计行,统计全年/每个季度的销售总额。

接着通过case when语句查询出每个商店每年每季度的销售总统计,因为是按商店名和时间分组的,所以在查询出大体的数据结构之后,还需要再对结果进行按商店分组统计, 这样就统计出了符合答案要求的数据,最后在将统计出的结果与以结果为基础的再次统计union一下就得出了最终的答案。看起来很复杂的一个查询,只要把思 路理清之后一步一步实现就很容易了。

虽然我们经过查询实现了题目的要求,但是再让我们回过头来看看我们的查询语句,数据少的时候这样查询还没什么问题,但是如果数据量过大就会有很严重 的性能问题,同时,这样的sql查询语句过于庞大,有木有可以优化的方案呢?答案是肯定的。下面就给大家讲一下优化的查询解决方案。

1.2 With rollup  + case when count

首先我们的查询思路还是一下的,先用case when语句构建出大体的查询框架,唯一不同的是在group by 之后我们多了with rollup语句。代码如下:

SELECT ISNULL(stor_name,'Total') AS stor_name,SUM(qty) AS Total,
         SUM(CASE WHEN DATEPART(qq,ord_date)=1 THEN qty ELSE 0 END) AS Qtr1,
         SUM(CASE WHEN DATEPART(qq,ord_date)=2 THEN qty ELSE 0 END) AS Qtr2,
         SUM(CASE WHEN DATEPART(qq,ord_date)=3 THEN qty ELSE 0 END) AS Qtr3,
         SUM(CASE WHEN DATEPART(qq,ord_date)=4 THEN qty ELSE 0 END) AS Qtr4
FROM stores t INNER JOIN sales s ON s.stor_id = t.stor_id
WHERE YEAR(s.ord_date) = '1993'
GROUP BY stor_name WITH ROLLUP

 

在group by 之后加上with rollup,我们执行一下查询语句,就会发现马上出现了我们想要的结果,这是为什么呢?

在生成包含小计和合计的报表时,ROLLUP 运算符很有用。GROUP BY子句允许一个将额外行添加到简略输出端 WITH ROLLUP 修饰符。这些行代表高层(或高聚集)简略操作。ROLLUP 因而允许你在多层分析的角度回答有关问询的问题。或者你可以使用 ROLLUP, 它能用一个问询提供双层分析。将一个 WITH ROLLUP修饰符添加到GROUP BY 语句,使询问产生另一行结果,也就是在上例中采用rollup之后,在按stor_name分组之后,还能检索出本组类的整体聚合信息。

如果有多重分组列的情况时,ROLLUP产生的效果更加复杂。这时,每次在除了最后一个分类列之外的任何列出现一个 “break” (值的改变) ,则问讯会产生一个高聚集累计行。

1.3 With cube  +  povit

上例中我们讲了使用with rullup来实现统计分组,那么还木有比with rollup 更加简便的查询呢?答案是肯定的。

首先我们想按照商店和时间分组统计出每家商店每年/季度的销售情况,这个时候我们需要借助于with cube语句。代码如下:

select isnull(t.stor_name, 'Total') as 'stor_name',
                      isnull(datepart(qq, ord_date),0) as 'Qtr', sum(qty) as 'qty'
         from sales s
         join stores t on s.stor_id = t.stor_id
         where year(s.ord_date) = 1993
         group by datepart(qq, ord_date), t.stor_name with cube

 

执行结果如下:

With cube语句跟with rollup语句作用很相像,它们的区别在于with CUBE 生成的结果集显示了所选列中值的所有组合的聚合,而with ROLLUP 生成的结果集显示了所选列中值的某一层次结构的聚合

第二步,我们将原始数据经过第一步的查询之后转换成了个标准的竖表,下边要做的就是如何将这个竖表转换成横表,我们在上边都是用case when的语法来实现这种表的横竖转换,这里我们换一种方式来实现。这里我们用povit方法来实现。代码如下:

select stor_name, isnull([0],0) as 'Total',
            isnull([1],0) as 'Qtr1',isnull([2],0) as 'Qtr2',
            isnull([3],0) as 'Qtr3', isnull([4],0) as 'Qtr4'
from
(
         select isnull(t.stor_name, 'Total') as 'stor_name',
                     isnull(datepart(qq, ord_date),0) as 'Qtr', sum(qty) as 'qty'
         from sales s
         join stores t on s.stor_id = t.stor_id
         where year(s.ord_date) = 1993
         group by datepart(qq, ord_date), t.stor_name with cube
) as tmp
pivot
(
         sum(qty) for Qtr in ([0], [1], [2], [3], [4])
) as pvt

 

上边代码示例中高亮部分即为使用pivot进行表的横竖转换的关键代码。

PIVOT用于行转列,在SQL Server 2000可以用聚合函数配合CASE语句实现,

PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P

这跟我们上边示例中使用的高亮标注的部分的方法是一样的

 

总结:

通过这样一个简单的查询,引出了今天要讲的表的行列转换(case when 和 pivot两种方法),表数据的统计(with rollup 和with cube方法),这也就达到了总结的目的。重要的不是讲这些方法怎么怎么用,主要是讲求解决问题的一个思路,以及在解决问题后对性能及效率的优化,希望可 以对大家有些帮助。

[转载]C#采集代理服务器ip并设置IE代理--HtmlAgilityPack实战代码 - 凤凰涅磐360yi - 博客园

mikel阅读(1445)

[转载]C#采集代理服务器ip并设置IE代理–HtmlAgilityPack实战代码 – 凤凰涅磐360yi – 博客园.

今天在博客园看到一篇文章,说是C#采集某某的数据,其实做采集小软件很久了,

用的最好的还是HtmlAgilityPack,真的没话说,非常方便快捷。

这里有详细介绍[.Net解析html文档类库HtmlAgilityPack完整使用说明–采集软件开发尤其好用].

本文不做详细说明了。主要还是上代码啊。毕竟业务应用才是我们开发人员努力编码的最终目的,

谁也不会为了单纯写点代码就自我满足了,满足业务需求才是主要的。

最近朋友叫我帮忙写一个小程序,获取某个网站的代理。也不怕大家知道了,就是这个网站

http://www.youdaili.cn/   牛逼吧??好像你要批量的代理ip还得花钱买的。

但是现在我就告诉你不用花钱的方法,就是自己去复制,哈哈,开玩笑。

程序员都是懒人,谁会去复制,还是交给程序自动实现吧–那就是采集程序。

言归正传,今天就是主要介绍使用C#组件HtmlAgilityPack进行获取代理服务器ip和端口,

并手动设置到IE中的一个小程序。当然咯,开源哦。

代码萌点这里。百度网盘 http://pan.baidu.com/share/link?shareid=2118473016&uk=1765114824

流程很简单:打开主页,获取今天最新的代理网站地址,打开该链接,再去获取代理ip即可。

道理很简单,实现也很简单。

用程序打开网站主页http://www.youdaili.cn/  ,里面会有一个new的标示,但是我们不用这个标示,

我们用日期!这个最准确的。

C#采集代理

我们可以看到08-19的最新代理就在那里。但是怎么让程序得到那?

首先我们可以用chrome的代码工具查看源代码,

chrome代理查看工具

我们想要得到的链接是在ul的li下面。

所有我们可以得到这样的正则表达式Xpath://ul/li/a

对应程序代码就是:

    iplist = new List<Model.IpModel>();//我的实体

            HtmlAgilityPack.HtmlWeb hw = new HtmlAgilityPack.HtmlWeb();//用的HtmlAgilityPack

            hw.AutoDetectEncoding = false;

             //现在下面的代码很重要。

            HttpWebRequest req;

            req = WebRequest.Create(new Uri(@”http://www.youdaili.cn/”)) as HttpWebRequest;

            req.Method = “GET”;

          HttpWebResponse rs = (HttpWebResponse)req.GetResponse();

            System.IO.StreamReader sr = new StreamReader(rs.GetResponseStream(), System.Text.Encoding.GetEncoding(“utf-8”));

            try

            {

                HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();

                doc.Load(sr);

                GetHrefs(doc); //然后就是上面所说的用的正则表达式了。

            }

            catch (Exception e)

            {

                Console.WriteLine(e.Message.ToString());

                Console.WriteLine(e.StackTrace);

            }

大家可能注意到上面标红的地方说明很重要。主要是youdaili.cn的网站编码有点问题。只有这样才能得出gb2312的网页源代码。

然后就是上面所说的用的正则表达式了。

 private void GetHrefs(HtmlAgilityPack.HtmlDocument _doc)

        {

            string todaydaili = DateTime.Now.ToString(“MM-dd”);

            HtmlNodeCollection hrefs = _doc.DocumentNode.SelectNodes(“//ul/li/a”);

            if (hrefs == null)

                return;

            foreach (HtmlNode href in hrefs)

            {

                if (href.Attributes[“title”] != null && href.Attributes[“href”] != null)

                {

                    string tilte = href.Attributes[“title”].Value;

                    string urll = href.Attributes[“href”].Value;

                    if (tilte.IndexOf(todaydaili) >= 0 && urll.Length > 0)

                    {

                        IpUrl model = new IpUrl();

                        if (urll.IndexOf(“guonei”) > 0)

                        {

                            model.DaiLi = 0;

                            model.Url = urll;

                            IpUrlList.Add(model);

                        }

                        if (urll.IndexOf(“guowai”) > 0)

                        {

                            model.DaiLi = 1;

                            model.Url = urll;

                            IpUrlList.Add(model);

                        }

                    }

                }

            }

            string url = “”;

            int tmppage = 1;

            foreach(IpUrl urla in IpUrlList)

            {

                for (int startpage = 1; startpage <= 10; startpage++)

                {

                    this.lb_result.Text = “正在采集第” + tmppage.ToString() + “页IP列表请稍后………”;

                    url = urla.Url.Replace(“.html”,””);

                    if (tmppage != 1)

                    {

                        url = url + “_” + startpage.ToString() + “.html”;

                    }

                    else

                    {

                        url = url + “.html”;

                    }

                    CaiJiIp(url, tmppage, urla.DaiLi);

                    tmppage++;

                }

            }

            this.lb_result.Text = “本次采集采集完毕!”;

            this.btn_caiji.Enabled = true;

            this.timer1.Stop();

        }

采集之后,我现在是保存到内存,还没有实际保存数据,各位自行解决数据保存问题吧。

采集之后的代理数据,怎么使用概不负责。haha。

转发注明来源哦:IT分享 http://suchso.com

[转载].Net解析html文档类库HtmlAgilityPack完整使用说明--采集软件开发尤其好用 - 项目实战 - IT工作生活这点事。Just Such So!

mikel阅读(1017)

[转载].Net解析html文档类库HtmlAgilityPack完整使用说明–采集软件开发尤其好用 – 项目实战 – IT工作生活这点事。Just Such So!.

在前几篇文章中([搜房网房产数据采集程序demo–GeckoWebBrowser实例] )都有提到一个解析html的C#类库HtmlAgilityPack,

今天终于有时间整理一下,并把Demo分享一下。

HtmlAgilityPack是一个基于.Net的、第三方免费开源的微型类库,主要用于在服务器端解析html文档(在B/S结构的程序中客户端可以用JavaScriptjquery解析html)。截止到本文发表时,HtmlAgilityPack的最新版本为 1.4.6。下载地址:http://htmlagilitypack.codeplex.com/。最新版本支持Linq to Objects ( LINQ to Xml ).

准备:

如果你有安装Nuget的话,可以直接查找安装即可。

下 载后解压缩后有3个文件,这里只需要将其中的HtmlAgilityPack.dll(程序集)、HtmlAgilityPack.xml(文档,用于 Visual Studio 2008中代码智能提示和帮助说明之用)引入解决方案中即可使用,无需安装任何东西,非常好用。

C#类文件开头引入using HtmlAgilityPack;就可以使用该命名空间下的类型了。实际使用中,几乎都是以HtmlDocument类为主线的,这一点非常类似于微 软.net framework中的XmlDocument类。XmlDocument类是操作的是xml文档,而HtmlDocument类操作的是html文档 (其实也可以操作xml文档),它们的操作方式都是基于Dom,所不同的是后者取消了诸如GetElementsByTagName这样的方法,强化了 GetElementById方法(在HtmlDocument中可以直接使用,而XmlDocument则不可以)。

HtmlAgilityPack中定位节点基本上都用Xpath表达式,Xpath表达式的参考文档可见:http://www.w3school.com.cn/xpath/xpath_syntax.asp。自行学习。

不过可以先用几个简单就可以。比如,我们用到最多可能就是针对某个元素(div)、或者某个class属性的div、或者某个id的div,或者以什么开头的div,

类似这样的Xpath还是比较简单的。

Xpath举几个例子,下面的代码中我们就会用到:

“//comment()”在XPath中表示“所有注释节点”

1、获取网页title:doc.DocumentNode.SelectSingleNode(“//title”).InnerText;
解释:XPath中“//title”表示所有title节点。SelectSingleNode用于获取满足条件的唯一的节点。
2、获取所有的超链接:doc.DocumentNode.Descendants(“a”)
3、获取name为kw的input,也就是相当于getElementsByName():
var kwBox = doc.DocumentNode.SelectSingleNode(“//input[@name=’kw’]”);

解释:”//input[@name=’kw’]”也是XPath的语法,表示:name属性等于kw的input标签。

//li/h3/a[@href]:所有li下面的h3包含a超级链接有href属性才符合。有的a可能是支持的js事件

//div[starts-with(@class,’content_single’)]:所有符合条件的div,并且它的class是由字符串content_single 开头的。

//标示获取documet下的所有符合条件。/div标示从根目录开始的符合条件的。

以上是准备工作。下面说一下HtmlAgilityPack读取web页面,并解析的方法步骤。

1.读取url:

               HtmlAgilityPack.HtmlWeb hw = new HtmlAgilityPack.HtmlWeb();

HtmlAgilityPack.HtmlDocument doccc = hw.Load(url);//是你需要解析的url

ArrayList ImagePtahs = GetHrefs(doccc);

这里可能会遇到2个问题。

一个是编码问题,一个是gzip不支持的问题。

首先编码问题解决办法:就是不用HtmlAgilityPack去获取Url的data数据,自己获取了。大家可能就问了:我自己获取了他不给我解析那?

没事,他不会那么笨的。谁的肉不是吃啊?

方法如下:

             WebProxy proxyObject = new WebProxy(IP, port);//这里我是用的代理。

//向指定地址发送请求

HttpWebRequest HttpWReq = (HttpWebRequest)WebRequest.Create(url);

HttpWReq.Proxy = proxyObject;

HttpWReq.Timeout = 10000;

HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse();

StreamReader sr = new StreamReader(HttpWResp.GetResponseStream(), System.Text.Encoding.GetEncoding(“UTF-8”));

//注意上面的编码了吗??

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();

doc.Load(sr);

int res = CheckIsGoodProxy(doc); //这是我解析的函数,还没到那一步。不解释了。

sr.Close();

HttpWResp.Close();

HttpWReq.Abort();

另一个问题就是很奇怪了。gzip的问题开启了gzip压缩的网页请求时会报错。报错信息为gzip”不是受支持的编码名。

在谷歌上搜索了半天,终于找到解决方案,而且不必更换HttpRequest或WebClient进行请求。同时还可以用此方法设置cookie,render伪装等等。。。
解决后代码如下:在你发起请求的是修改一下。

HtmlWeb webClient = new HtmlWeb();

HtmlAgilityPack.HtmlWeb.PreRequestHandler handler = delegate(HttpWebRequest request)

{

request.Headers[HttpRequestHeader.AcceptEncoding] = “gzip, deflate”;

request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

request.CookieContainer = new System.Net.CookieContainer();

return true;

};

webClient.PreRequest += handler;

HtmlDocument doc = webClient.Load(this.getUrl());

可能最新版本的HtmlAgilityPack会修复这个问题吧。期待中。

2.用Xpath解析。

这一步就比较简单了。就用Xpath选出你想要的数据,遍历他们,取出他们的value即可。

实例代码:

   private ArrayList GetHrefs(HtmlAgilityPack.HtmlDocument _doc)

{

try

{

Images = new ArrayList();

HtmlNodeCollection hrefs = _doc.DocumentNode.SelectNodes(“//li/h3/a[@href]”);

HtmlNodeCollection hrefs2 = _doc.DocumentNode.SelectNodes(“//div[starts-with(@class,’content_single’)]”);

if (hrefs == null)

return new ArrayList();

foreach (HtmlNode href in hrefs)

{

//  Images.Add(href.Attributes[“src”].Value);

string hreff = href.Attributes[“href”].Value;// 排除  博海拾贝第二百零二期】吃完薯条寂寞了

string title = href.Attributes[“title”].Value;

if (title.IndexOf(“邪恶”) >= 0)

{

continue;

}

if (title.IndexOf(“恶搞”) >= 0)

{

continue;

}

if (title.IndexOf(“雷人”) >= 0)

{

continue;

}

///执行数据保存的逻辑

}

}

catch (Exception ex)

{

ShowLogMsg(“出错了:”+ex.Message+ex.StackTrace);

return new ArrayList();

}

}

 

每一个Htmlnode,你要获取他的数据用这个方法:  img.Attributes[“src”].Value

 

整个过程就是这样的简单。大家有不明白或者有问题可以留言交流。


转发请注明来自:IT分享 http://suchso.com

[转载]基于easyui的webform扩展 - ahl5esoft - 博客园

mikel阅读(1272)

[转载]基于easyui的webform扩展 – ahl5esoft – 博客园.

回顾

前端基于easyui的mvc扩展》、《前端基于easyui的mvc扩展(续)》 前两篇介绍了mvc内如何基于easyui进行扩展,在mvc里面有很多简化的语法可以让开发人员快速开发,既然我们已经对mvc进行了扩展,那么当然也 不能漏掉了基础的web form了。首先我们来比较一下mvc和web form,如果前端不使用razor,都是用aspx页面的话,使用的语法是一样的,只是mvc内提供了HtmlHelper、Model、 ViewData等来简化开发。

  也就是说,如果我们使用如下的方式,其实在web form里面也是可行的,但是与mvc不同的是,web form内并没有像HtmlHelper的对象可以直接进行扩展,因此我们只能重新创建一个类来实现这些功能,既然无法使用类似HtmlHelper的对 象扩展,那么model对象也就必须在编码标签的时候手动传入了,大致代码如下:

<%User user =newUser{Name="测试",StateId=2}; %>
<%=EasyUIHelper.ValidateText(u => u.Name, user)%>
<%=EasyUIHelper.Datebox(u => u.Name, user)%>
<%=EasyUIHelper.Combobox<User>(u => u.StateId, user,"States","{ id: 'myCob', 'data-options': 'width: 100, editable: false' }")%>

实现

  那么要达到以上的效果其实也不难,因为我们在前两篇已经进行了实现了,只要将其重构一下,使其可以支持在web form内工作便可以了,那么首先我们遇到的问题便是如何把表达式树转化为属性,这个主题我在《获取Lambda表达式内表达式的值》该文章中已经进行了讲解,调整后代码大致如下:

publicstaticstringValidateText(Expression<Func<TModel,object>> expression,TModel model,string attributeJson,Dictionary<string,string> attributes){string propertyName =PropertyHelper.ResloveName(expression);//关于获取表达式值的文章PropertyInfo property =typeof(TModel).GetProperty(propertyName);TagBuilder tag =newTagBuilder("input");
    //增加name、type属性ValidationAttribute[] validationAttrs;if(property.TryGetAttributes(out validationAttrs)){//请阅读转换规则代码}var extraAttributes =string.IsNullOrEmpty(attributeJson)? attributes :JsonHelper.Deserialize<IDictionary<string,string>>(attributeJson);//基于Newtonsoft转化json的公用方法//添加属性return tag.ToString();}

  这样前端的代码就顺利转换完成了,剩下的便是如何让表单提交到服务端后,怎么样进行验证呢,大概的流程如下:

  1. 将提交到服务端的表单直接转化为对应的实体类
  2. 读取实体类各个属性以及属性内的验证特性,一一进行进行验证
  3. 如果中间没有验证失败的话,那么就说明实体是符合验证要求的,可进行其他操作

  第一步其实就是利用反射将属性相对应的值一一赋值给相应的属性而已,这里我们就不重复去实现了。

  获取属性验证特性,我们可以通过扩展MemberInfo(因为PropertyInfo和MethodInfo都是MemberInfo的派生类)来获取特性,大致代码如下:

publicstaticboolTryGetAttributes(thisMemberInfo member,outTAttribute[] attributes,bool inherit =false)whereTAttribute:Attribute{
    attributes =null;var objs = member.GetCustomAttributes(typeof(TAttribute), inherit);if(objs.Length==0)returnfalse;

    attributes =Array.ConvertAll(objs, obj => obj asTAttribute);returntrue;}

  对验证特性进行验证的代码大致如下:

//遍历属性ValidationAttribute[] validationAttributes =//获取验证特性foreach(var validation in validationAttributes){if(validation isRegularExpressionAttribute){var regularAttr = validation asRegularExpressionAttribute;var reg =newRegex(regularAttr.Pattern);if(value !=null&&!reg.IsMatch(value.ToString()))returnfalse;}else{ValidationResult result = validation.GetValidationResult(value,newValidationContext(instance,null,null));if(result !=ValidationResult.Success)returnfalse;}}

  这里之所以要将RegularExpressionAttribute 单独抽出来判断是因为System.ComponentModel.DataAnnotations.dll(v4.0.0.0)内的实现有BUG,没有 根据正则正确的实现GetValidationResult方法。

效果

//实体
public class User
{
    private string m_Name = null;
    [Required(ErrorMessage = "用户名不能为空!")]
    [StringLength(10, MinimumLength = 4, ErrorMessage = "用户名长度必须在4-10之间")]
    [DisplayName("用户名:")]
    public string Name
    {
        get { return m_Name; }
        set { m_Name = value; }
    }
    //略
}

//前端
<% 
    FormBuilder form = new FormBuilder();
    User user = new User { Name = "测试", StateId = 2 }; %>
<%=form.CreateBeginHtml("/Handlers/MvcHandler.ashx", "fmTest")%>
<%=EasyUIHelper.ValidateText(u => u.Name, user)%>
<br />
<%=EasyUIHelper.Combobox(u => u.StateId, user, "States", "{ id: 'myCob', 'data-options': 'width: 100, editable: false'}")%>
<br />
<input type="submit" value="提交" />
<%=form.CreateEndHtml() %>
<script type="text/javascript">
$('#fmTest').easyuiForm();
</script>

结尾

  谢谢大家,如文章有任何问题和错误请指出,谢谢!

[转载]z-index 应用简单总结 - 色拉油 - 博客园

mikel阅读(1045)

[转载]z-index 应用简单总结 – 色拉油 – 博客园.

做过页面布局的同学对z-index属性应该是很熟悉了,z-index是针对网页显示 中的一个特殊属性。因为显示器是显示的图案是一个二维平面,拥有x轴和y轴来表示位置属性。为了表示三维立体的概念如显示元素的上下层的叠加顺序引入了 z-index属性来表示z轴的区别。表示一个元素在叠加顺序上的上下立体关系。

z-index值较大的元素将叠加在z-index值较小的元素之上。对于未指定此属性的定位对象,z-index 值为正数的对象会在其之上,而 z-index 值为负数的对象在其之下。

简单演示

复制代码
<div style="width:200px;height:200px;background-color:#0e0;"></div>
    <div style="position:relative; top:-50px; width:100px;height:100px;background-color:#00e;"><div>
复制代码

两个DIV,第二个向上移动50px,正常情况应该是这样的

image

第二个div遮住了第一个div,对第二个添加z-index属性

复制代码
<div style="width:200px;height:200px;background-color:#0e0;"></div>
    <div style="position:relative; top:-50px; width:100px;height:100px;background-color:#00e;z-index:-5;"><div>
复制代码

结果就会变成这个样子,z-index 最简单的应用就是这样

image

只对定位元素有效

z-index属性适用于定位元素(position属性值为 relative 或 absolute 或 fixed的对象),用来确定定位元素在垂直于显示屏方向(称为Z轴)上的层叠顺序,也就是说如果元素是没有定位的,对其设置的z-index会是无效的。

复制代码
<div style="width:200px;height:200px;background-color:#0e0;z-index:30"></div>
<div style="position:relative; top:-50px; width:100px;height:100px;background-color:#00e;z-index:10;"><div>
复制代码

 

 

 

 

虽然第一个div的z-index比第二个div大,但是由于第一个div未定位,其z-index属性未起作用,所以仍然会被第二个div覆盖。

image

相同z-index谁上谁下

相同的z-index其实有两种情况

1.如果两个元素都没有定位发生位置重合现象或者两个都已定位元素且z-index相同发生位置重合现象,那么按文档流顺序,后面的覆盖前面的。

复制代码
<div style="position:relative;width:200px;height:200px;background-color:#0e0;"></div>
<div style="position:relative; top:-50px; width:100px;height:100px;background-color:#00e;"><div>
复制代码

image

2.如果两个元素都没有设置z-index,使用默认值,一个定位一个没有定位,那么定位元素覆盖未定位元素

复制代码
<div style="position:relative;top:50px;width:200px;height:200px;background-color:#0e0;"></div>
<div style=" width:100px;height:100px;background-color:#00e;"><div>
复制代码

image

父子关系处理

如果父元素z-index有效,那么子元素无论是否设置z-index都和父元素一致,会在父元素上方

复制代码
<div style="position:relative;width:200px;height:200px;background-color:#0e0;z-index:10;">
        <div style="position:relative;width:100px;height:100px;background-color:#00e;z-index:-5;"><div>
    </div>
复制代码

虽然子元素设置z-index比父元素小,但是子元素仍然出现在父元素上方

image

如果父元素z-index失效(未定位或者使用默认值),那么定位子元素的z-index设置生效

复制代码
<div style="position:relative;width:200px;height:200px;background-color:#0e0;">
        <div style="position:relative;width:100px;height:100px;background-color:#00e;z-index:-5;"><div>
</div>
复制代码

子元素z-index=-5生效,被父元素覆盖

image

兄弟之间子元素

如果兄弟元素的z-index生效,那么其子元素覆盖关系有父元素决定

复制代码
<div style="position:relative;width:100px;height:100px;background-color:#0e0;z-index:5;">
        <div style="position:relative;width:50px;height:250px;background-color:#00e;z-index:50;"></div>
    </div>

    <div style="position:relative;width:100px;height:100px;background-color:#0e0;z-index:10;margin-top:4px;">
        <div style="position:relative;width:30px;height:150px;background-color:#e0e;z-index:-10;"></div>
    </div>
复制代码

虽然第一个div的子元素的z-index比较高,但是由于其父元素z-index比第二个div低,所以第一个div子元素会被第二个div及其子元素覆盖

image

应用

经常会有这样一种错误在table中最后各行一个td放一个div,点击弹出子菜单做一些删除、修改什么的操作,但是每次弹出的菜单都会被下面各行的div覆盖

复制代码
<!DOCTYPE html>
<html>
    <head>
        <title>Test</title>
        <style type="text/css" >
            html,body
            {
                height:100%;
                width:100%;
                padding:0;
                margin:0;
            }

            .menu
            {
                background-color:#0e0;
                position:relative;
                z-index:10;
            }

            .options
            {
                display:none;
                position:absolute;
                top:
                z-index:30;
            }

            .options div
            {
                background-color:#00e;
            }
        </style>
    </head>
    <body>
    <table border="1" cellpadding="4px" cellspacing="0">
        <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Options</th>
        </tr>
        <tr>
            <td>Byron</td>
            <td>24</td>
            <td>
                <div class="menu" >
                    <div>Options</div>
                    <div class="options" style="display:block;position:absolute;top:20px;">
                        <div>Opion1</div>
                        <div>Opion2</div>
                        <div>Opion3</div>
                        <div>Opion4</div>
                    </div>
                </div>
            </td>
        </tr>
        <tr>
            <td>Byron</td>
            <td>24</td>
            <td>
                <div class="menu">
                    <div>Options</div>
                    <div class="options" >
                        <div>Opion1</div>
                        <div>Opion2</div>
                        <div>Opion3</div>
                        <div>Opion4</div>
                    </div>
                </div>
            </td>
        </tr>
        <tr>
            <td>Byron</td>
            <td>24</td>
            <td>
                <div class="menu">
                    <div>Options</div>
                    <div class="options" >
                        <div>Opion1</div>
                        <div>Opion2</div>
                        <div>Opion3</div>
                        <div>Opion4</div>
                    </div>
                </div>
            </td>
        </tr>
    </table>
    </body>
<html>
复制代码

 

期望样式 image 实际样式 image

 

这时候习惯于增大options 的z-index却发现于事无补,为什么呢?因为每个menu的z-index相同,它们的层叠顺序按文档流顺序,无论子元素z-index调到多大,上 面menu的options还是会被下面menu遮盖。这时候我的做法一般是把options放到外面,所有的menu用一个,使menu与 options没有父子关系,或者干脆在点击menu的时候把它的z-index调大,这样其子元素就不会被遮盖住了。

最后

本文的例子都是以符合W3C的Chrome浏览器做验证,但在IE6,7 z-index的默认值并不是auto而是0,这样会导致很多奇怪现象,这时候就需要考虑这点了。

[转载]前端基于easyui的mvc扩展(续) - ahl5esoft - 博客园

mikel阅读(1241)

[转载]前端基于easyui的mvc扩展(续) – ahl5esoft – 博客园.

  上一篇讲解了基于easyui的mvc扩展的基本实现,已经降低了在mvc内使用easyui的难度,但是仍然还有一些问题:

  1. 当我们要给生成的控件设置一些其他的属性(如:id)或者想要设置easyui控件的一些其他的可配置项
  2. 对于form表单提交时,也要让form表单基于easyui的验证机制来进行验证

  这里要先提 一下,上一篇的TagBuilder并不是微软自带的(位于System.Web.Mvc下),而是自己实现的,理由嘛,既然我们编码了mvc下对于 easyui的扩展,那么同样也可以去扩展普通的web form(后面的文章会再进行扩展),TagBuilder的实现方式跟微软提供的很相像,大家自己实现吧,^_^。

实现

  由于所要增 加的额外属性是以key、value方式存在的,如:id=”myId” or onclick=”findRecords”等,那么我们看以通过增加一个Dictionary<string, string>参数的方式来将我们需要的配置传给构造easyui html的方法,大致的代码如下:

Html.Combobox(m => m.StateId,"States",newDictionary<string,string>{{"id","cboState"},{"data-options","width: 100, editable: false"}})

  TagBuilder内只要对传入的字典进行此存储,然后在生成Html的时候将KeyValuePair<string, string>转化为key=”value”形式的字符串就可以了。

  而对于form表单结合easyui的验证原本easyui便提供了form表单的功能,只需要我们使用如下代码,便可以进行验证:

$('#myForm').form({
    onSubmit:function(){var isValid = $(this).form('validate');return isValid;},
    success:function(data){//这里不像jQuery那样可以返回json对象,data永远都是一个字符串,除非使用ajax form表单进行自己的扩展}});

  由于mvc内对于表单验证已经提供了支持,但是因为我们自己进行了自定义的扩 展,那么在执行controll的Action的时候,mvc虽然会帮我们对表单的实体进行验证,但并不会主动在验证失败的情况下阻止Action的执 行,因此我们需要自己寻找其他的方式在表单实体验证失败的情况下,将失败的信息返回到客户端进行提示。

  我们知道所有的Controller都继承自 System.Web.Mvc.Controller(它是继承自IController的),System.Web.Mvc.Controller有一 个受保护的OnActionExecuting方式,当我们对方法的ActionExecutingContext的Result进行赋值的情况下,它会 阻止原本要继续执行的Action的触发,而且Result内的值会回传给客户端,因此我们可以在此方法内对于表单实体是否验证失败来完成我们的操作,代码如下:

protectedoverridevoidOnActionExecuting(ActionExecutingContext filterContext){if(ViewData.ModelState.IsValid){base.OnActionExecuting(filterContext);}else{
        filterContext.Result=Content("{\"success\":false, \"message\":\"表单数据异常\"}");}}

  这里要注意了,如果使用mvc自带的Json方法来回传数据的话,传递到客户端永远都只是{},这里大家可以使用Json.Net来将对象转化为json。

  到了这里,该有的功能我们基本上都已经完成了,其实还有一些小问题没有解决, 那就是当我们配置控件属性的时候,如果是函数的情况下,就只能将函数必须是全局的或者要写在属性的值里面,实在很不方便,或者大家可以跟我一样,用其他的 属性来代替这些配置,我使用的方式如下:

@Html.Combobox(m => m.StateId,"States",newDictionary<string,string>{{"easyui","onSelect:selectState,formatter:formatterState"}})@Html.Linkbutton("上传",newDictionary<string,string>{{"bind":"click:uploadFile"}})

  然后在js文件或者<script>脚本内对以上的格式进行解析,这样就可以根据自己的方式来声明函数了。

  其次就是老是要写一大串的字典来声明额外的属性实在是很麻烦的事情,那么也可以使用json的方式将字符串直接写入,代码如下:

@Html.ValidatePassword(m => m.Password,@"{ validType: 'remote[\'/user/CheckPassword\', \'password\']', invalidMessage: '密码有误!' }")

  那么只要在后台将其解析为Dictionary<string,string>就可以了,方便了许多,有其他喜欢的格式也可以自己去定义,然后编码相关的解析方法也是可以实现的。

  那么今天的后续部分就到这里结束了,有错误的地方请大家指出,谢谢大家!