csharp

166
www.happy12.com 010-82387501 论坛地址: http://www.sisheng.net.cn/forum/forum.php 1说明情况:学习的不同性,一开始就是 C 语言,就是理论要与实际结合(要与计算机组成原理结合,要与模型结合) 以理解为主 实践 要解 决问题 用计算机语言去解决实际问题 2当天得问题当天解决,没有付出就没有收获,期望加努力就可以达到目标 3课程的主要内容:C#web 问题、大型的服务器集成、wf 问题,前一半.net,后面就是基于 web 的项目开发,面向对象为核心 oop(好程序) 要学会背代码理解代码创造代码扩展 4概念串联原理:机原理、单片用(看书力),个证件(基础很重要) Passual 语言,现在的计算机 冯洛伊曼计算机 存储程序的思想 存储运算的步骤实就是程序 code and Data 存储 现在的是 PC 台电脑 是为持人图灵 本很高 PC 苹果 自己做操作程序 IBM 盖茨 CPM 操作系统 ibm.doc 计算组成原理; CPU 、内(程序+数据是内存只01 数据 字节 byte bit CPU 寄存取数据 有一个叫指 令寄存存中位置指针换取的程序与数据 通电 CPUBIOS固定程序、启动引导程序)—检查板上自检把硬件都检查扇区 指令寄存IP(内取数据)、堆栈寄存SPstack,是为了取数据类比货栈记住个启齿的地,就是一准点记录指针存储实可以用个做垃圾回收) 汇编及语言与程序 cpu 指令不同,汇编语言是汇编程序是汇编语言转化成为机器语言(语言是一过多语言 编译汇编语言 机器trobosC IDE 集成开发环境 Integrated Development( 代码 编辑器、编译调试户界 工具。代码编写功分析功编译功debug 体化的开发套。) 是开发、修改、发就是集成开发编译速度块 好得就是编译后就是对 microsoft 编译MFC 类库 自己编译器,开发很高,开发出系统 cpu 的问题 后就出现了 java 次编写虚拟机的原出一cpu 用模拟虚拟指令 MFC 要容后合悲剧 后就出现了.net 技术dephi 跑车金钱宝轮 C 架构师 .net 么?实是一虚拟虚拟用的计算机 移植.net windows 直接hellow world dir 编译csc /?查看帮助说明 csc hellow.cs 已经变异完exe 单单 hellow 就可以Mkdic D:\Dir 出目dir 进入指定cd cd 特殊名称 cd ..\.. ,一就是当前目 cd. Type 实出Csc 编译成为 csc Cls 清屏 理解:面向对象的语言 C# 对于程序都存在入口程序开始就是 main Ipconfig 指令 查看自己ip Ping 查看连接 Find /? 查看帮助

Upload: nicolas-yan

Post on 01-Nov-2014

59 views

Category:

Documents


8 download

TRANSCRIPT

Page 1: Csharp

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php 1、 说明情况:学习的不同性,一开始就是 C语言,就是理论要与实际结合(要与计算机组成原理结合,要与模型结合) 以理解为主 实践 要解决问题 用计算机语言去解决实际问题

2、 当天得问题当天解决,没有付出就没有收获,期望加努力就可以达到目标 3、 课程的主要内容:C#(web问题、大型的服务器集成、wf问题,前一半.net,后面就是基于 web的项目开发,面向对象为核心 oop(好程序) 要学会背代码理解代码创造代码) 适当扩展

4、 概念串联: ① 基础原理:微机原理、单片机应用(看书的能力),适当考一个证件(基础很重要) ② Passual语言,现在的计算机 冯洛伊曼计算机 存储程序的思想 存储运算的步骤,其实就是程序 code and Data 存储 ③ 现在的是 PC机 第一台电脑 是为了解密 主持人是图灵 成本很高

PC机 苹果 自己做的操作程序 IBM 盖茨 CPM操作系统 ibm.doc 计算组成原理; CPU 、内存 (程序+数据)但是内存只有 01的数据 然后换成字节 byte bit CPU的寄存器从内存获取数据 有一个叫指令寄存器 从内存中的位置(指针)换取对应的程序与数据 通电 CPU— BIOS(固定程序、启动引导程序)—检查主板上得自检(把硬件都检查一遍) 硬盘 硬盘第一扇区 指令寄存器 IP(内存获取数据)、堆栈寄存器 SP(栈 stack,是为了取数据,类比货栈,记住一个启齿的地方,就是一个基准点,暂存器获取记录的新的指针,覆盖性存储,其实可以用这个做垃圾回收) 汇编及其语言与程序 ,因为 cpu 的指令不同,所以很难 汇编语言是单词 汇编程序是把汇编语言转化成为机器语言(高级语言其实也是一样 只不过多了一层) 高级语言 编译器 汇编语言 机器码 trobosC解析 IDE集成开发环境 Integrated Development(代码编辑器、编译器、调试器和图形用户界面工具。代码编写功能、分析功能、编译功能、debug 功能等一体化的开发软件套。) 即是开发、修改、发布 这个就是集成开发环境 编译速度块 好得就是编译器 然后就是对 microsoft 的编译器了 MFC 微软基础类库 自己写一个可见可写的编译器,软件开发代价很高,开发出来的单一系统 单一cpu的问题 然后就出现了 java 一次编写到处运行 虚拟机的原因 用软件模拟出一个 cpu 利用模拟虚拟的指令 比MFC还要容易 然后合作 然后悲剧 然后就出现了.net平台 吸引工程师 挖人 技术天才 dephi 跑车加金钱加尊重 宝轮 C的架构师 .net是什么?其实是一个虚拟机 虚拟通用的计算机 保持移植性 .net与 windows融合了 直接写 hellow world dir 编译器 csc /?查看帮助说明 csc hellow.cs 就已经变异完了 生成了一个 exe文件 然后单单 hellow就可以了执行了 Mkdic 创建新文件夹 D:\文件名 Dir 列出目录 dir 文件名 进入指定文件 cd 改变目录 文件夹 cd 文件名 特殊目录名称 cd ..\.. 两个点 ,一个点就是当前目 cd. Type 现实出文本 Csc编译成为 csc Cls清屏 理解:纯面向对象的语言 C# 执行顺序 对于每一个程序来说都存在一个入口点 程序开始执行 第一个的方法就是 main Ipconfig在命令的指令 查看自己的 ip Ping 查看连接 Find /? 查看帮助

命令行参数

Page 2: Csharp

www.happy12.com 010-82387501

Csc后 执行的时候 hellow空格 mike 那么程序要改成 public class Demo { public static void Main(System.String[] args) { System.Console.WriteLine(args.Length);注意的 length的格式都是需要大小写要 System.Console.WriteLine("Hellow"+args[0]);//注意的是 在输入程序名的时候就是添加 jack了 System.Console.WriteLine("Hellow,{0}",args[0]); } } Compiler编译器 基本问题 由值的类型进行延伸 type 所以就来了一个约定了 基本类型约定 存数据的问题 Int 栈就连续的 4哥字节 我们就查看 msdn 8位就是一个字节 8位 Long是 8个字节 64位 short 2个字节

有符号与无符号的问题

有符号就会 unsigned signed short ushort byte sbyte

类型转换的问题;

1、int 可以转换为 long 空间足够装下 类型相似、空间足够 整数

汇总:怎么学,计算机的原理,.net的关系(虚拟机),命令器的使用 csc源码机器码,我觉得还是那个命令器比较好

Forlder文件夹

Directory目录

下午 1、 参数 pargamer 获取参数的方式;命令行,输入流,输出流,错误流里面进行输入与输出 输入流:键盘 输出流,错误流:显示器 Console.ReadLine 标准输出流 你要创建一个新的吗? 程序一启动就会自动生成一个出流 输入流 String line=System.Console.ReadLine(); 类型转换 System.Convert.ToInt32(line); 判断,输出 Console.WriteLine(“”);新增一行 Console.Write()同行 写了太多的 System,。那么就添加一个 using System; /r/n微软的换行 /n换行的 Linux \r换行的苹果 using System; public class Math { public static void Main(String[] args)

Page 3: Csharp

www.happy12.com 010-82387501

{ Console.Write("1+2=?,请您输入答案"); int answer =Convert.ToInt32(Console.ReadLine()); if(answer==3) { Console.WriteLine("\r\n答案正确"); } else { Console.WriteLine("\r\n答案错误"); } }

} 字符串要用“”括起来 也叫字面量 Const不能被修改的变量 可以保持好 预防性错误 字面量 变量 常量 Pase分析 类型转换 int answer= int.Pase(值); 伪随机数 random 随机数类 System.Random random = new,System,Random(); Int number = random.Next(0,20); String.Format(“{0}+{1}=?”,a,b); using System; public class Math { public static void Main(String[] args) { System.Random myRandom = new System.Random(); int a =myRandom.Next(0,20); int b = myRandom.Next(30,50); string question = String.Format("{0}+{1}=? 请输入答案",a,b); Console.Write(question ); int answer =int.Parse(Console.ReadLine()); if(answer==(a+b)) { Console.WriteLine("\r\n答案正确"); } else { Console.WriteLine("\r\n答案错误"); } } 为什么 random两个对象产生的都一样(由于里面是参考毫秒的 所以计算机的计算间隔实在是太短了) 顺序结构、判断结构、循环结构 For (int i=0;I<10;i++) { //先执行后判断 } 迭代器 1、 开发工具 notepad vi turboC IDE VisualStudio C#Developer 只要是可以写文本的,就可以编写程序 2、 cmd命令行工具 .net命令行工具 。net系统文件夹 .MicroSoft.Net.framework 让路径里面有,计算机 属性 高级系统设置 环境变量 系统变量 path 再加上 csc的物理地址打开文件 3、 notepad hellow 用 txt

Page 4: Csharp

www.happy12.com 010-82387501

4、 输入的不是数字 抛出异常的解决方法 5、 方法的抽象,关注点的分离(模块开发)吃狗食 解开耦合度抽象出方法 即是把输入的东西搞成一个方法 无限循环 方法的建造 方法名,返回值 return(还是无返回值)通过调用一个方法来优化程序的架构与体系,就是方法的问题 6、 VS行号问题 工具 选项 文本选择器 C# 行号 (语句自动完成) 7、 Return 两个 的解决方案 第一:特殊的值,利用特殊的值返回状态值 ,主程序再进行判断 break直接跳出 continue继续执行 第二种就是返回结构 struct 就是创造一个新的错误类型 就是自己用得数值类型

public struct Result

{

public string result;

}

主程序调用 Result myResult= GetResult(a, b);

string result = myResult.result;

方法抽象

Result myResult;

int time = 0;

string math = "";

math = Console.ReadLine();

for (;math != ""&&int.Parse(math)==a+b;time++)

{

Console.Write("剩下次数{0},请您再次输入答案:",3-time);

math = Console.ReadLine();

}

if (time == 3)

{

myResult.result = "自动跳到下一题";

wrong++;

}

else

{

myResult.result = "恭喜您,您答对了。";

right++;

}

return myResult;

8、 C#的语句与语法 方法有很多 但是都是在 namespace的中的一个类里面,而第一个执行的方法就是 main的方法 而方法也有很多,但是最高级也是一定要执行的一个方法 main() 顺序执行的程序(强制结束执行 return) 循环语句 for 语句(先判断,再执行) do while语句(先执行后判断) Do{} While(count<10) ;不包括 10的那次 using System; public class Demo { static void Main (string[] args ) { int count=0; int result =0; do { count++; result=result+count; } while(count<=500); Console.WriteLine("结果是{0}",result); } } 斐波那契级数 引出的递推 (递推比递归的要快 ) using System; public class Demo { static void Main (string[] args ) {

Page 5: Csharp

www.happy12.com 010-82387501

int Month1=1,Month2=1,Month3,month=3; do { Month3=Month1+Month2; Month1=Month2; Month2=Month3; Console.Write("第{0}个月兔子数:{1}:",month,Month3); month++; } while(month<=8); } } 递归算法其实是内部自身调用的方法 using System; public class Demo { static void Main(string[] args) { Console.WriteLine(Progress(8)); } public static int Progress(int month) { if(month==0) return 0; if(month==1) return 1; return Progress(month - 1) + Progress(month-2); } } 2、 作用域的介绍,{}作用域,与作用域内部的变量的作用

3、 开发环境的简介

4、 如何创建一个简单的程序,控制台应用程序,使用简单,适合做概念分析

名字:项目名称

存储位置:

解决方案名:

不要因为 IDE的强大而被 IDE 高级语言开发环境 (编译器与开发平台)误导了。一定要为我所用

5、 要是多文件的情况,那么在编译的时候就可以一同打包,这个就是项目文件 project

6、 要是多个项目,那么就是就是解决方案 solution

7、 为解决方案建造目录 那么就是会创建一个与解决方案同名的文件夹 ,里面有 项目名文件 还有解决方案启动项 sln,可以用 txt打开

8、 Project xml 文件

9、 到命令行编译,csc program.cs 就是 IDE自动生成的项目文件

10、Bin程序所在的文件夹 编译 生成解决方案 f6 Desktop\ConsoleSolution\Console\bin\Debug,但是在 VS里面哪里的 main是不能预先传递 String[]args)的,但是

我们在命令行的时候倒是可以在执行的时候 Hellow Mike 利用空格来进行传参

10、调试 F5

11、新的命令行工具,开始所有程序,附件 windows PowerShell \C 的补齐功能

12、Debug里面的 vvshost.exe 其实就是与 vs相关的一个程序 主要是预先编译提示错误 辅助编程用的

文件解析结束

12、方法 方法的名称 static void Plus (int a, intb) {}

13有返回值的方法,形参 a,b 但是真正调用的时候就确实是实参了,return a+b; void 空返回值

14方法里面形参最优,但是无形参方法 全局变量最优

15传参延伸(重载)

就是方法一样,但是传递的参数不同的问题,而且在编程的时候 VS还能够给予提示的功能

用数组的方法解决多个参数的传递问题,而且还可以利用可变数组(可变参数)

Static int Add (int[] arry){fot 语句与 length的使用} 记住方法都是要 static 的 ,而且方法名的第一字母是大写

class Program

{

static void Main(string[] args)

{

int[] arry = {1,2,3};

int total = Add(arry);

System.Console.WriteLine(total);

System.Console.ReadLine();

}

public static int Add(int[] arry)

Page 6: Csharp

www.happy12.com 010-82387501 {

int result=0;

for(int i=0;i<arry.Length;i++)

{

result=result+arry[i];

}

return result;

}

}

15语法糖 int total =Add(1,2,3)

static int Add ( params int [] arry){} params在方法中直接当做是数组,好处就是调用方方便调用class Program

{

static void Main(string[] args)

{

int total = Add(1,2,3);

System.Console.WriteLine(total);

System.Console.ReadLine();

}

public static int Add(params int[] arry)

{

int result=0;

for(int i=0;i<arry.Length;i++)

{

result=result+arry[i];

}

return result;

}

}

在 writeline 也调用 params

下午

16面向对象的功能,答题分析,记录 (信息分析法,流程分析法,动作分析法,对象分析法)

系统分析:1、系统随机出题目;2、系统保存题目模块(a,b,标答,你回答的结果,答题的尝试次数,答题时间,最后答题结果,是正确,还是,所有用户的汇总,数据

结构 dataset的问题);3、架构分析,4、窗体分析

17C语言 对大型的程序 方法控制 命名的规则都有规范 开发很困难 是不是手段的问题?然后 oop诞生了

Oop的思想 要是用全局的变量的话 适合计算机 但是不适合人的思维 而 oop就是想程序员好想 离机器要好点 更加贴近生活

为什么我们会知道笔记本,就是人有一种抽象的能力,人知道笔记本的用途,但是也见到过很多不同的笔记本,自己还有一个笔记本,老子给了老子一个苹果。而且知道

笔记本的属性 相同的类型 人也会分类 鱼,不知道是什么鱼,但是你就知道是鱼。

人们开始创作就是 鱼类(类) 白马是不是马? 白马也是一个白马类 白马类是马类的子类 一匹马 具体的某一匹马

那么什么是马呢? 这些思维应用到系统开发里面就是 oop 把问题看成一个整体 封装 多态 程序中处理那些类型的数据然后对这些程序就抽象出我们需要的数据类型

面向对象就是要用我们创造的类型来编写程序 解决问题

18控制坐标(x,y)表示点 point 一个问题就是一个整体 ,所以我们可以搞一个解决问题或者表示坐标点的类

5、 构造函数的问题(在类内部的层面)初始化 构造函数可以编写多个不同参数的重载,没有参数的构造函数,默认构造函数

6、 西沟方法,垃圾处理 释放内存

7、 对象实例

Console.SetCursorPosition(10,20);//转移光标的位置,后面的 hellow也是可以改变后面输出的位置 10行 20列

Console.WriteLine(“”Hellow);

8、 从类外访问私有变量的方法 继承 封装(读写) 多态度

封装(读写) 封装语法糖

private int x;

public int X//封装,语法糖,方便使用

{

get { return x; }

set { x = value; }

}

Page 7: Csharp

www.happy12.com 010-82387501

19清屏;Console.Clear();

20线程的暂停与使用的方法

System.Threading.Thread.Sleep(100ms);

Console.WindowWidthWith 窗体的欢度

其实清除就是Console.WriteLine();

for(int x=0;x< Console.WindowWidth;j++)

{

for (int y=0;y<rows;y++)

{

Console.SetCursorPosition(x,y);

Console.WriteLine("");

}

}

1、 复习,对象 object 的问题,类的问题 template 模板 类在图纸上的设计

利用 class类 创造出一个对象 object 就是 class object = new class();

设计师就是要搭建这些类

类里面有两种内容,数据与方法

封装的问题 就是封好数据变量 装好方法(行为、函数,做些什么操作,注意方法名的首字母要大写,构造函数的作用于重载,默认、普通)

继承、

多态

高级语言是更加贴近人的,所以在 C与 C++里面才自动执行析构函数,在 C#会自动全部初始化为 0

系统功能,api函数问题 msdn 就是系统内部的 API函数 直接调用 而掌握也是很重要的

2、 用类来归类 但是有信息流分析法 事务分析法 动作分析法

第一个类 object 基类 万物都是类 是一个超类 类型层次的根

派生类 public class Piont:Object

继承关系 父类的特征可以被子类继承 Point 分两个 一个是 object的方法与数据

还有一部分是属于自己的

派生类重写 基类里面有一个虚方法 ToString(); override 重写掉基类的方法

using System;

// The Point class is derived from System.Object.

class Point :Object

{

public int x, y;

public Point(int x, int y)

{

this.x = x;

this.y = y;

}

public override bool Equals(object obj)

{

// If this and obj do not refer to the same type, then they are not equal.

if (obj.GetType() != this.GetType()) return false;

// Return true if x and y fields match.

Point other = (Point) obj;

return (this.x == other.x) && (this.y == other.y);

}

// Return the XOR of the x and y fields.

public override int GetHashCode()

{

return x ^ y;

}

// Return the point's value as a string.

public override String ToString()

{

return String.Format("({0}, {1})", x, y);

Page 8: Csharp

www.happy12.com 010-82387501 }

public override string ToString()

{

return base.ToString();

}

// Return a copy of this point object by making a simple field copy.

public Point Copy()

{

return (Point) this.MemberwiseClone();

}

}

public sealed class App {

static void Main()

{

// Construct a Point object.

Point p1 = new Point(1,2);

// Make another Point object that is a copy of the first.

Point p2 = p1.Copy();

// Make another variable that references the first Point object.

Point p3 = p1;

// The line below displays false because p1 and p2 refer to two different objects.

Console.WriteLine(Object.ReferenceEquals(p1, p2));

// The line below displays true because p1 and p2 refer to two different objects that have the same value.

Console.WriteLine(Object.Equals(p1, p2));

// The line below displays true because p1 and p3 refer to one object.

Console.WriteLine(Object.ReferenceEquals(p1, p3));

// The line below displays: p1's value is: (1, 2)

Console.WriteLine("p1's value is: {0}", p1.ToString());

}

}

// This code example produces the following output:

//

// False

// True

// True

// p1's value is: (1, 2)

//

3、 熟悉派生类的重写:

Override string ToString()

4、 类的对象问题

5、 有值有引用对象),而堆就是引用实例 栈 sp(仅仅是值,还有引用实例的名字 P) 寄存器 外面有一个叫堆 寄存器 栈空间小 很容易溢出 数据量大的时候就放

在堆里 那么哪些咋放? 数据类型的问题 分为 值类型 整形的类型就放在栈 与 引用类型 类类型 放在堆里面 方法都是在类里面 还有一个实例的名字 P 会放

在栈里面,对堆里面 P所包含的东西 进行引用 在 new的时候 就根据方法的大小划分初始存储大小 就先赋值 再进行构造函数(在堆里面) 然后才道 栈里面设

置一个 P作为对象的引用 p1.x 与 p2.x不同

6、判断对象的类型,那么就是叫号 hashcode 对每一个对象都有一个号 GetHashCode 用作特殊类型的 GetHashCode 方法的默认实现不保证针对不同的对象返回唯一值。

而且,.NET Framework 不保证 GetHashCode 方法的默认实现以及它所返回的值在不同版本的 .NET Framework 中是相同的。因此,在进行哈希运算时,该方法的默认实

现不得用作唯一对象标识符。

7、GetHashCode 方法可以由派生类型重写。值类型必须重写此方法,以提供适合该类型的哈希函数和在哈希表中提供有用的分布。为了获得最佳结果,哈希代码必须基

于实例字段或属性(而非静态字段或属性)的值。利用 hashcode 来判断是否是同一个对象 1

重写解决问题重出的问题,就是利用重写 hashcode 给 x y搞一个组合 hashcode 进行判断

就是对系统 hanshcode 而言 的确是会因为 p1 p2的不同 而生成的 x+y的结果也是不同,但是现在我们就可以重写 ,令到 不关于 P1P2 而且还要活跃思维定义一个顺序

9、 解决题目的问题 现在要每一个问题对应一个对象 平 P1到 P2

Page 9: Csharp

www.happy12.com 010-82387501

9、ItemGroup 添加跟中 用 txt打开解决方案文件

Microsoft Visual Studio Solution File, Format Version 11.00

# Visual Studio 2010

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApplication1", "ConsoleApplication1\ConsoleApplication1.csproj",

"{5D299E12-E07C-4B77-8E13-25CEFD393C7C}"

EndProject

Global

GlobalSection(SolutionConfigurationPlatforms) = preSolution

Debug|x86 = Debug|x86

Release|x86 = Release|x86

EndGlobalSection

GlobalSection(ProjectConfigurationPlatforms) = postSolution

{5D299E12-E07C-4B77-8E13-25CEFD393C7C}.Debug|x86.ActiveCfg = Debug|x86

{5D299E12-E07C-4B77-8E13-25CEFD393C7C}.Debug|x86.Build.0 = Debug|x86

{5D299E12-E07C-4B77-8E13-25CEFD393C7C}.Release|x86.ActiveCfg = Release|x86

{5D299E12-E07C-4B77-8E13-25CEFD393C7C}.Release|x86.Build.0 = Release|x86

EndGlobalSection

GlobalSection(SolutionProperties) = preSolution

HideSolutionNode = FALSE

EndGlobalSection

EndGlobal

10、用 txt打开项目文件

<ItemGroup>

<Reference Include="System" />

<Reference Include="System.Core" />

<Reference Include="System.Xml.Linq" />

<Reference Include="System.Data.DataSetExtensions" />

<Reference Include="Microsoft.CSharp" />

<Reference Include="System.Data" />

<Reference Include="System.Xml" />

</ItemGroup>

<ItemGroup>

<Compile Include="Class1.cs" />

<Compile Include="Program.cs" />

<Compile Include="Properties\AssemblyInfo.cs" />

</ItemGroup>

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

Other similar extension points exist, see Microsoft.Common.targets.

<Target Name="BeforeBuild">

</Target>

<Target Name="AfterBuild">

</Target>

-->

Page 10: Csharp

www.happy12.com 010-82387501

11、开发注意事项 还要注意管理员方法与客户方法

喜欢问题 从 问题 考试 就是划分好对象 就可以让程序员关注对应的负责部分,便于维护,减少工作困难度

12、试卷的问题,保存试题的时候就必须要实例化 10个问题吗? 不一定,我们可以实例化一个新的数组,利用下标来区分

private Question[] questions;

public Page(int number, int nan)

{

Console.WriteLine("本卷考题有 {0} 条",number);

questions=new Question[10];

}

13、利用特殊值 监控 三种循环的特点 执行与判断的先后的问题

14、利用哨兵模式 与 内外判断模式 可以减少 bug率

方法调用了两次,就是可以把动作放在 while里面,要由语句合并的思维,在实际开发中要进行一定的语句合并

一个方法不要超过 66行 就是一页代码 paper里面有 questions questions 里面有 question

然后 question 里面有显示题目与判断对于错的方法

1、复习,UML图,先分析,再布局,再编码 先无视细节 软件工程的设计方法 人月神话 软件开发没有银弹 比较成功就是 UML 通用建模语言 3个前辈 架构师 都

发明了一个情况 3个人的优势 UML visio图 startUML(仿制 Rose) 直接生成类图 类到图 图到类 v MDA开发模式 基于建模的软件开发 就画图就是开发了 何

时结束 控制条件 结束条件的问题

2、开始上课:今天. UML的使用 找错误等等得基本技巧 什么事 winfrom?

3、VS UML的使用 ClassDiagram cd 右键添加 fields字段 关联 尾 使用了头 右键显示基类

4、Windows 窗体入门 System. Windows.Form 怎么让命名不重复呢?

5、命名空间就来了,把类放在不同的类里面 属于命名空间下的一个类 在同一个项目里面 或者一个页面要是要进行跨类必须要在前面添加命名空间 经常使用的话 可

以夹 using 空间名 这样才可以不写命名空间

Partial 关键字 部分类 form1:form,说明 要把同名的类编译到一起 Desginer 就是这几个类同时要编译

6、基本问题 颜色类 前景色 ForeColor 背景色 BackColor

位置 location x,y 定位 dock停靠 anchor相对位置

大小 size 标题 text

ControalBox 显示上面的最小最大关闭

AutoScroll 这个调整大小的时候,true过于小得时候显示滚动条

Name名字 ID

MainMeunScript 当为 MDI窗体的时候

Opacity透明度

shouwInTaskBar 出现在任务栏

8、添加现有项,还可以在主程序 搞好对应的东西

9、加断点

F9 F11一行 F10以方法为单位 hift+F11条出方法

局部变量的窗口 监视窗口

1、组件与空间的问题。组件就是通用零件,标准化生产,组件化开发,最早的就是MFC函数 Library,其实类就是一种组件,可以重用,不用再重写,test开发的时候类就像是组件,高内聚低耦合 越少关系越方便用,而用在界面的类就叫做控件的类,而且风格统一 2、画一个控件,frm—paint画 Graphics g= e.Graphics; g.DrawRectangle(Pens.Black,10,20,40,20); 添加鼠标的事件// 也是在 frm MoseClicj e.x= e.y= Raectangle r = new Rectanle(10,20,40,20); If(x>=r&&y<=r.x+r.with&&y>=r.y&&r.y+r.Heiht) { Message.Show(“Click”); } 3、设计工作,类图+序列图 4、关于用 object判断是否出同一题目,用 bool equals 相等方法,而且参数还是 object的

Page 11: Csharp

www.happy12.com 010-82387501

If(q1.equals(q2)){} 但是 equals里面的方法是系统内部的,所以我们要再 question里面重写 equals 看来 equals就是为了重写而存在的 5、继承的问题,方法可以调用,但是我们也可以重写。继承的意义在于统一,统一一样的类型都是人,包子与饺子的问题,equals本身是虚方法,就是要再前面搞一个 virtual修饰 F 允许派生类重写此方法 记得 Question that = obj as Question 不写就是基类的 重写了之后就是对应类的 6、重写 virtual 允许重写 7、抽象 abstract 抽象类必须写(接口) 把虚方法更加进一步 抽象,派生类必须实现 单纯就是 public abstract string GetName(); Abstract class 抽象类 没有实现的抽象方法,所以不能被实例化 强制派生必须有某个方法 抽象类与抽象的方法 必须在派生类中实现 所以不能 new dog(); 所以只能够是用派生类 不能用基类 8、开发中的使用 设计驱动 磁盘等资料 表示 磁盘驱动器 的对象 DriveInfo driveinfo System,IO. DriveInfo di = new DriveInfo(“C”); Di.totalsize //磁盘容量 DriveFormat//磁盘格式 AvailableFreeSpace//剩余空间 所有磁盘 当前对象的对象目录信息() System,IO. DriveInfo[] di = new DriveInfo.GetDrives(); Di[i.name] 取得当前程序执行的当前目录,(环境类) System.Environment.CurrentDirectory CurrentDirectory 所执行的 exe对象 System.IO.DriveInfo directory = new System.IO.DirectoryInfo(System.Environment.CurrentDirectory); 对象的 path的信息 借助这个对象来操纵磁盘驱动器 (驱动器 文件 目录) 驱动器 DriveInfo System,IO. DriveInfo di = new DriveInfo(“C”); Di.totalsize //磁盘容量 DriveFormat//磁盘格式 AvailableFreeSpace//剩余空间 所有磁盘 System,IO. DriveInfo[] di = new DriveInfo.GetDrives(); Di[i.name] 目录(路径,包括转义字符的问题)CurrentDirectory 取得当前程序执行的当前目录,(环境类) System.Environment.CurrentDirectory CurrentDirectory 所执行的 exe对象 当前对象的对象目录信息() System.IO.DriveInfo directory = new System.IO.DirectoryInfo(System.Environment.CurrentDirectory); 对象的 path的信息 文件 FileInfo System.IO.FileInfo fi = new System.IO.FileInfo(filepath); If(fi.Exists) {存在} 驱动器从 object派生 创建一种特殊的文件就是用来存别的文件的名 这种特殊的文件就教做目录,先找出目录文件 这个就是一个子目录 不能直接修改目录的内容,只能操作文件来修改目录里面的信息 所以 目录与文件是有一个共同的积累 FileSystemInfo(absract) 即是说在磁盘上存得要不是文件要不是目录,但是不能 new,因为创建的时候会存在抑或性 由于目录与文件都是 FileSystemInfo的派生类的对象,所以也是可以利用 FileSystemInfo基类来引用派生类的对象实例 System,IO.FileSystemInfo myFlieInfo = fi ; 那么我们就可以做到什么的好处呢?那就是可以表示一个目录下面的所有存在对象,容易表示,可以装载 目录名就是 current的文件名,其中也包含文件的名的集合

Page 12: Csharp

www.happy12.com 010-82387501

文件对象 fielInfo 通过名称来区分的 saved.dat 指出文件名 包含路径 Directory 连写两个\\的问题 或者用@“” 9、fat32最早是微软管理磁盘的一个系统,里面有一个分区表,01对应相面的扇区的使用情况,所以 1个字节就是控制 8个,掌握磁盘的使用情况,微软 dos的方式,存储方便,使用广泛 (缺点简单,没地方存储访问角色) Ntfs(下一代磁盘存储系统) 10、下午 操作文件的内容 流 strem 就是解决输入输出的问题,但是因为芯片不同 单片机不同,就是把所有的资料看成是一个字节一个字节的输出,所以就又驱动一东西 基于字节序列进行输入输出,都由这个 S ystem.IO 是一个抽象基类 规定输入输出的标准方式是什么 输出:程序 内存 输出 WriteByte 允许重写 然后保存到文件中 FileStream 写在文件中 针对文件系统的文件进行写入读取的操作 所以文件操作基本都是使用 FileStream System.IO.FileStream fs = new System.IO.FileStream(“path”);//当前目录: string path =System.Environment.CurrentDirectory; //文件目录 string filepath = path +\\saved.dat 那么多个程序操作一个文件咋办?最好就是占用原则,一档要 close 要是允许多程度访问同一个文件。 但是要声明给操作系统 System.IO.FileStream fs= new System.IO.FileStream(filePath,System.IO.FileMode.Append追加 Truncate清空 creat有得覆盖 没有就新建 Fs.WriteByte(20) 但是占用了 4K的扇区,都是 16进制度 Fs.Close90//关闭文件 VS打开文件 open with 选择二进制编译器查看 16进制下面的 数字 游戏的存盘文件 流的工作流程 看起来非常地向数组 append 表示当前的位置的属性 Console.WriteLine(fs.Position); Position的用法, fs.Readbyte(); 空的话读到一个-1 特殊的返回值 要返回 3个字节外表示了一个 -1 没有实际的数被读到 通过程序调整 positiona fs.Seek()0,System.IO.SeekOrigin.Begin; fs.ReadByte(); 绝对路径与相对路径,相对路径(“”);//相对路径是相对于当前的目录 、怎么存呢?第一步:抽象出一个 save的方法 Void Save ( FielStream fs) { Stream.WriteByte();//一个一个地保存,有一个技巧 (byte) 所有的东西最后全部都是数字 要适当进行判断限定 语法糖 (byte) (this.IsPass?1:0) ?前面的表达式要不是真要么是假 逻辑表达式 那么要是一下子就存整个试卷呢、 保存的试卷包含两个部分的数据; 当前题目 index 与 那么再一道一道地保存试题 快速监测窗体的调试技巧 } 那么读取是全呢? Load加载 打开读取的是 open 读取的时候还需要相同的进度 显示-1再是对应的问题 System.IO.FileStream fs

= new System.IO.FileStream("saved.dat", System.IO.FileMode.Create);

// 增加一个保存的方法

public void Save(System.IO.FileStream stream)

{

// 依次保存题目的数据

stream.WriteByte( ( byte) this.a );

stream.WriteByte( ( byte) this.b);

// 因为 bool 不是数字

if (this.isPass)

{

stream.WriteByte(1);

}

else

{

stream.WriteByte(0);

}

// ? 逻辑表达式

//stream.WriteByte( (byte) ( this.isPass?1:0 ) );

Page 13: Csharp

www.happy12.com 010-82387501

stream.WriteByte( ( byte) this.questionNo);

}

// 读取试卷

System.IO.FileStream fs2

= new System.IO.FileStream("saved.dat", System.IO.FileMode.Open);

// 读取的方法

public void Load(System.IO.FileStream stream)

{

// 读取的时候,还需要按照同样的顺序

this.a = stream.ReadByte();

this.b = stream.ReadByte();

// 没有保存答案,所以,读取之后,必须自己计算一下

this.answer = this.a + this.b;

if (stream.ReadByte() == 1)

{

this.isPass = true;

}

else

{

this.isPass = false;

}

this.questionNo = stream.ReadByte();

}

内存中是很短暂的,但是写入磁盘的话 读写 但是有一个东西叫缓存区,就是吧多次的磁盘操作集中到一次,close 就是声明要写入磁盘,然后清空囧与数据 1、 复习 IO的命名空间,流就是一个一个的字节数列,position当前的流处理的位置,刚打开的流都是 0 默认调用 架构师 就是负责划分类的 大量的实践与系统分析 多分析设计

2、 怎么做下一题 做到第几道题 3、 继续学习 继承 有基类 派生类 虚方法 toString(); equals() 可以重写 也可以不重写,扩展的机制 4、 抽象 abstracts 不能继承 只能重写 好处就是强制性,vir 所以就是 2级联控 5、 sealed修饰符(阻止继承) 6、 virural 可以被任何的派生类重写 7、 一般方法,其实继承就是继承的, 基类的那个就叫 base.的方法,特指基类 this就是派生类 8、 另外两个派生类 一个是 MemoryStream 还有一个 BufferedStream (多态的问题) MemoryStream 数据多的时候会非常地幔,涉及到速度的都市瓶颈的问题 速度与价格的问题 真的是很快嘛?但是的确是快一点点 那么我们就适当减少速度 磁道 扇区 找到对应的位置 那么我们可以压缩操作磁盘的读写速度 从而达到提速的效果 快递的启示 对策,自己放在一块,自己做的方法 块的读写 block 将需要保存的数据 用一个整块来保存 搞到一个字节数组里面 System.IO.FileStream fs2

= new System.IO.FileStream("saved.dat", System.IO.FileMode.Open);

Stream也是对文件搞好 Byte[] buffer = new byte [4]; Buffer[0]=(byte)数据 Stream.write(buffer,0,4);//write是以字节数组为参数的,还能够对应下标,还能设置,要保存的长度 public void Save(System.IO.FileStream stream)

{

// 将需要保存的数据以一个整块的方法进行保存

byte[] buffer = new byte[4];

buffer[0] = (byte)this.a;

buffer[1] = (byte)this.b;

buffer[2] = (byte)(this.isPass ? 1 : 0);

buffer[3] = (byte)this.questionNo;

// 将 buffer 数组中,从 0 下标开始,共计 4 个字节进行保存

stream.Write(buffer, 0, 4);

}

读一块的方法 、Stream已经是包含文件的 stream了 Byte[] readbuffer = new byte[4];

Page 14: Csharp

www.happy12.com 010-82387501

Ing length = Stream.read(buffer,0,4);//从哪里读,返回的是一个 int,但是数组实际读取的字节数,就是实际上读取的字节数, // 读取的方法

public void Load(System.IO.FileStream stream)

{

// 整块读取的时候,需要先定义一个数组来保存读取的内容

byte[] buffer = new byte[4];

// Read 方法将从流中 Position 位置开始,读取指定数量的字节 ,这里是 4

// buffer 表示读取的字节保存的数组,第二个参数表示从数组的哪个下标开始保存

// Read 方法将会返回一个整数,表示实际读取的字节数

int length = stream.Read(buffer, 0, 4);

// 我们需要从这个字节数组中拆分数据

this.a = buffer[0];

this.b = buffer[1];

// 没有保存答案,所以,读取之后,必须自己计算一下

this.answer = this.a + this.b;

if (buffer[2] == 1)

{

this.isPass = true;

}

else

{

this.isPass = false;

}

this.questionNo = buffer[3];

}

那么这样就把读磁盘的速度减少到一次,共两次 这两个流的好处 一个试卷存一次 内部的字节提取的问题(封转的保密性) 第一个 memorystream 读到内存 速度极快 但是容量少的话,还是很好的 //使用memoryStream,就是在内存中

System.Random random = new Random();

System.IO.MemoryStream ms = new System.IO.MemoryStream();

Block.Question question = new Question(random,1);

question.Save(ms); //因为都是属于派生类,写道了内存流中去了,写完之后

ms.Close();

byte[] buffer = ms.ToArray(); //精华

Console.WriteLine(BitConverter.ToString(buffer));//内存操作,不用数数,直接一起保存到硬盘

//保存到文件

System.IO.FileStream fs = new System.IO.FileStream("saved.dat", System.IO.FileMode.Create);

fs.Write(buffer,0,buffer.Length);

fs.Close();

那么通用性 // 增加一个保存的方法

public void Save(System.IO.Stream stream)

{

// 将需要保存的数据以一个整块的方法进行保存

byte[] buffer = new byte[4];

buffer[0] = (byte)this.a;

buffer[1] = (byte)this.b;

buffer[2] = (byte)(this.isPass ? 1 : 0);

buffer[3] = (byte)this.questionNo;

// 将 buffer 数组中,从 0 下标开始,共计 4 个字节进行保存

stream.Write(buffer, 0, 4);

}

Page 15: Csharp

www.happy12.com 010-82387501

大量数据的时候 //大量数据的时候bufferstream,专门开辟了一个数组,也是内存型的,可以指定大小,当满了一块就先输出,然后下一个数组就开始继续存储,那么我们只要

//写就好了

System.Random random = new Random();

System.IO.FileStream fs = new System.IO.FileStream("saved.dat", System.IO.FileMode.Create);

System.IO.BufferedStream bs = new System.IO.BufferedStream(fs,40*1023);//不负责实际的输入与输出,只管存储

Block.Question question = new Question(random, 1);

question.Save(bs); //因为都是属于派生类,写道了内存流中去了,写完之后,多态来了

bs.Close();//文件流也会直接关闭,直接保存

load事件 //load BufferedStream

System.IO.FileStream fs = new System.IO.FileStream("saved.dat", System.IO.FileMode.Open);

System.IO.BufferedStream bs = new System.IO.BufferedStream(fs);

Block.Question question = new Question();

question.Load(bs); //因为都是属于派生类,写道了内存流中去了,写完之后

bs.Close();

Console.WriteLine(question.ToString());

选择保存控件使用 启发 stream 的 readbyte也是顺序而来的 ,而且是逐个地读取我们一个字节的内容 下午:存盘文件的问题 存盘中文的时候的配置文档都是,SDK提干工具 原理 2进制 字符 ASC2 人机信息交换吗 字符与数字之间的关系表 汉文是象形文字 英文是拼音性 128的 可打印字符 不可打印字符 UNIX\N MAC \R残次不全的小空格,是网站编码的基础 但是 ASCII只能写英文 、 ISO国际标准化组织专门制定标准 ISO9000 还限定了所有的新的规定 ISO8859一系列的编码 其中之一就是 拉丁语式的拼音 ASCII 0-127 ISO 8859 0-127 128-255 8859-1 英文的国际编码表 GB2312 中文编码标准 存常用字 有 6763 分级 字数是不全的 罩子程序 点阵 分两个部分 0到 127 就是 ASCII 繁体字(台湾,正体字)转换成为简体字 繁体字的编码 BIG5 日本 日文编码 大中华文化圈 近代才发明韩文 100年前 清朝末年 首尔 汉城 发 EMAIL的话 就悲催了 新的字符编码 CJK中日韩全编码 超级编码 美国UniCode 代码联盟 计算机公司 单字节编码 double DBCS双字节编码 汉化 影响到软件的销售与普及 本地化团队 开发的代价很高,全世界就一种编码表 人类用得所有字符 UniCode 被广泛的使用 用做多的就是双字节的 UniCode ISO的问题 10646 接受了 UniCode标准 认可的标准 世界上唯一的编码表 现在核心都是 UniCode, 字符转换的功能,在未来基本上都是 UniCode 学习资料 文章 9、 字符编码 的类 System.text.Encoding getbyte()可以是串 也可以是字符 getstring() 在程序中使用 不使用 new而是使用其他类型来得到一个对象实例 也叫做工厂模式 System.Text.Encoding Assii = System.Text.Encoding.GetEncoding(20127);

Console.WriteLine(Assii.WebName);

System.Text.Encoding assii = System.Text.Encoding.ASCII;

Console.WriteLine(assii.WebName);

//编码 e

Byte[] butes = assii.GetBytes( "100");

Console.WriteLine(BitConverter.ToString(butes));

//解码 100

String s = assii.GetString(butes);

Console.WriteLine(s);

10、 字符编码是一一对应的 AscII GB2312 ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/script56/html/vsmscANSITable.htm 11、 UniCode 是字符与码点一一对应 ,而且还要声明存储的方式 但是双字节的最多 最后是 fffff 、 12、 Char 型 char char1=”Z”; char char2 =”\x0058” ; char(88) 前面的 256个还是 ASCII 13、 Utf的缺点 美国只需要一半 过多的 0会出现出错 因为 0是字符串结束的标志 千年虫的问题 670年代的程序员 为了省下空间 就存

701212 那么是 1970还是 2070 UTF=UniCode传输方式 变形模式 出了一个公式就可以得到表达形式 utf8是变长的 但是都是对应同一个码点,长度不确定

System.Text.Encoding utf8 = System.Text.Encoding.UTF8;

String ASCII ="ABCD";

byte[] asciibyte = utf8.GetBytes(ASCII);

Console.WriteLine(BitConverter.ToString(asciibyte));

String gb="陈诚";

byte[] utf8_2 = utf8.GetBytes(gb);

Console.WriteLine(BitConverter.ToString(utf8_2));

Console.Read();

所以我们就要加点标识进行区分,对不同的 Unicode编码规定了特定的前缀 或者是前序 Console.WriteLine(BitConvert.ToString(Utf8.GetPreamble()));//EF BB BF表示后面的内容是应 UTF8的编码方式来写的 ANSI就是本机码 936魔幻数字 ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/fxref_mscorlib/html/c590603b-8901-253c-78bf-171950a57438.htm System.Text.Encoding GB312 = System.Text.Encoding.GetEncoding(936);

Page 16: Csharp

www.happy12.com 010-82387501

Linux适合开发 怎么样存盘呢? SaveUTF8();//以字符的形式来存 int i = 12;

//对于值类型的数据都已经重写了toString的方法

string s = i.ToString();

Console.WriteLine(i);

Console.WriteLine(s);

System.Text.Encoding utf8 = System.Text.Encoding.UTF8;

byte[] bytes = utf8.GetBytes(s);

Console.WriteLine(BitConverter.ToString(bytes));

System.IO.FileStream fs = new System.IO.FileStream("saved.dat",System.IO.FileMode.Create);

fs.Write(bytes,0,bytes.Length);

fs.Close();

到后面是一个题目一个串,中间用, 隔开 string.Format(); 现在的是可以写入但是却是不能读取 加载到当前问题,记录题号 存是可以的,下午就是读得问题 //编码 e

Byte[] butes = assii.GetBytes( "100");

Console.WriteLine(BitConverter.ToString(butes));

//解码 100

String s = assii.GetString(butes);

Console.WriteLine(s);

// 读取的方法

public void Load(System.IO.Stream stream)

{

// 准备一个临时保存读取内容的数组

byte[] buffer = new byte[100];

// 定义一个保存当前 buffer 位置的变量

int index = 0;

// 因为需要判断流中读取的数据,所以,先读,后判断

// 用来判断是否完成一道题

int hi = -1;

int lo = -1;

int b;

do

{

// 一次读取一个字节

b = stream.ReadByte();

if( b == 13 )

{

// 保存高字节

hi = 13;

}

// 如果不是 13,再接着判断

else if (hi == 13 && b == 10)

{

lo = 10;

}

else

{

// 普通的数字,保存起来

buffer[index] = ( byte) b;

index = index + 1;

}

//

Page 17: Csharp

www.happy12.com 010-82387501

}

while( !(hi==13 && lo == 10) );

// 当循环结束的时候,我们已经得到了一道题

// 题目就放在 buffer 数组中, 其中的前 index 个字节就是我们需要的数据

System.Text.Encoding utf8 = System.Text.Encoding.UTF8;

// 进行解码,得到题目的字符串表示形式

string s = utf8.GetString(buffer, 0, index);

Console.WriteLine(s);

// 现在得到的是一个由 , 分割的字符串

// 字符串类提供了一个 Split 方法,直接帮助我们根据特定的分割符来拆分字符串

string[] parts = s.Split(',');

for (int i = 0; i < parts.Length; i++)

{

Console.WriteLine(parts[i]);

}

// 显然,在这里应该拆分为 4 个部分

// 将字符串形式重新转换回数字

this.a = int.Parse(parts[0]); // 回顾一下,数字转换为字符串 ToString

this.b = int.Parse(parts[1]);

// 答案需要在读取之后计算

this.answer = this.a + this.b;

if (parts[2] == "1")

{

this.isPass = true;

}

else

{

this.isPass = false;

}

this.questionNo = int.Parse(parts[3]);

封装的问题

对字符的操作就是字符流,以字符为单位进行读和写。但是必须要指定编码,封装在字符流的类里,保存为字节流

字符流也要继承自 stream 字符流派生的话就有问题 就是多态的问题 能用父类来表示,不管你是什么马必须首先都是马 但是马+车=马车

继承的关系就必须是得关系 ,所以字符流看起来是流,但是处理 字符 的问题完全是变了,那么就不是的。那么字符流就变成有两个基类了。

一个就是 IO.TextWriter 输出为字符 还能输出换行

TextWriter 是 StreamWriter 和 StringWriter 的抽象基类,它们将字符分别写入流和字符串。创建一个 TextWriter 实例,将对象写入字符串,或将字符串写入文

件,或序列化 XML。也可使用 TextWriter 的实例将文本写入自定义后备存储区(所使用的 API 与用于字符串或流的 API 相同),或者增加对文本格式化的支持。

学习类的原则 成员 基类抽象类 方法

Write writeLine 内部还潜逃一个流还有一个 newLine的对象

StreamWriter最基本的用法流与编码都给他

System.IO.StreamWriter writer

= new System.IO.StreamWriter("save2.txt");

writer.WriteLine(199);

writer.Close();

// 实际的目的地

System.IO.FileStream fs

= new System.IO.FileStream("save.txt", System.IO.FileMode.Create);

System.IO.BufferedStream bs

= new System.IO.BufferedStream(fs, 10 * 1024);

// 使用的编码

System.Text.Encoding utf8

= System.Text.Encoding.UTF8;

// 创建一个字符输出流的实例,使用文件进行输出

System.IO.StreamWriter writer2

= new System.IO.StreamWriter(bs, utf8);

writer2.Write(120);

writer2.Close();

Page 18: Csharp

www.happy12.com 010-82387501

TextReaders 字符序列的类 peek窥探

读文件直接字符

// 默认编码是 utf8

System.IO.StreamReader reader

= new System.IO.StreamReader("save2.txt");

string line = reader.ReadLine();

reader.Close();

Console.WriteLine(line);

//实现目的

System.IO.FileStream fs

= new System.IO.FileStream("save2.txt", System.IO.FileMode.Open);

System.Text.Encoding utf8

= System.Text.Encoding.UTF8;

System.IO.StreamReader reader2

= new System.IO.StreamReader(fs, utf8);

string line2 = reader.ReadLine();

reader2.Close();

Console.WriteLine(line2);

实际目的 System.IO.FielStream fs – new System.IO.FielStream(“saved.txt”

,System.IO.FileMode.Creat);

//使用编码

加密的原理:加密的技术在二战以前都是技巧型的,转化成特殊的符号,如何解密? 最多的字母 E最多,替换加密都悲剧了。加密算法,算法标准,密钥就是一个串,

趣味性降低,常见的加密算法都有了,只要提供密钥,

复制文件 Copy ToOutput Directory 就是 debug的文件夹目录下面,就是拷贝到下面的部分。就是添加了文件 txt之后的问题嘛,但是要选择是否复制到 debug的

文件夹里面,这样才算是好的。

什么是控制台 就是要完成输入 输出 就是因为会自动生成 3个流 每一个程序创造的时候都会自动提供 3个标准流 但是在.net的环境下就变得很好地使用了。

System.IO.TextWriter tw = Console.Out;

tw.WriteLine("Hellow.world.");

System.IO.FileStream fs2 = new System.IO.FileStream("saved.txt",System.IO.FileMode.Create);

System.IO.TextWriter tws = new System.IO.StreamWriter(fs2, System.Text.Encoding.UTF8);

Console.SetOut(tws);

System.IO.FileStream fs3 = new System.IO.FileStream("saved.txt",System.IO.FileMode.Open);

System.IO.TextReader trs = new System.IO.StreamReader(fs3, System.Text.Encoding.UTF8);

Console.SetIn(trs);

单一继承的模式,那么就坐了一个变种就是接口。特殊的抽象基类

简单的接口的使用,接口是抽象的类,里面只有方法名,没有实现,接口不能被实例化,只能是继承接口,但是一般称为实现接口可以通过接口来限制对象啊的访问,行

为(动作的控制),某对象要实现某动作,就是不知道是什么类,但是都可以做什么动作,就是可以把共同的方法抽取出来就是 接口 抽象动作

定义接口 实现接口(继承) 实现接口的成员(类中)

//接口里面只有方法 Public interface I+接口的名称 Iclose { Void close (); } Public class : Iclose { Public void close () { 关闭了 } } 也可以是 Public class { Iscole is =new Close(); Public void Close() {} { 以前是叫操作系统要内存,泄露就是程序突然不运行了,那么内存就被拒了,就像是一个水桶。不可能一眼就看出问题在哪 托管 就是.net的运行 CLR控制下得内存 ,其实就是保姆,管家,要有借有还,有垃圾回收机制 就是申请的内存问题 非托管 就是要跟操作搞命令了。比如说文件流,就是 CLR与操作系统一起控制,那么 close就是跟操作系统说,我不用了,你处理吧。

Page 19: Csharp

www.happy12.com 010-82387501

文件,画图,数据库,网络 因为大家都是悬疑使用清理内存的,所以就不能继承了,所以就必须是用接口了 Idisposable 释放 Disispose(); 要显式地释放资源 Disispose(); Dispose();与 close();类似 那么出异常咋办? 还有什么呢?这么就要处理了 catch 还有 finaly 都要处理 Try {}(程序,有异常的话,就执行 catch)catch( Exception ex) (捕获到了异常,异常的处理问题 e.message) finaly(最终,就是不管出不出异常都一定会执行) Java就是语言简单 类库简单 基本的都写了,加深的没有 封装方法 C#提供了什么呢? System.IO.FileStream fs2 = new System.IO.FileStream("saved.txt",System.IO.FileMode.Create);

Using的好处 代码块即使出现了异常,也会保证一定调用对象的 disposable的方法,都放在后台了,帮助我们释放非托管的资源 Using (//必须提供一个实现了 Idisposable接口的对象应用 fs2) { 执行的程序 } 开发中所面临的问题 11、 希望一切都自动化 各种各样的动作都自动化 如何进行测试?如何测试我们前面写的工作 12、 TDD测试的思想 提供专门的工具 天才程序员 测试驱动的开发,就是先写测试 再写程序,用测试区引导我们的开发进度 13、 在写类的方法之前我为什么要写这个类,可以先写一个测试的程序,不断改正我们的程序 不至于改变方向,我做了一个修改,那么我们可以利用测试的来衡量进度。Nunit的使用 Xunit msUnit

14、 分部分开发,一个做 From,class library类库项目 没有了 main方法 out type Class Library 类库项目 DLL动态链接库 与 EXE就差了一个诚如入口点 可重用可部署的单位 t怎么去判断的方法呢? 一涉及到人机交互

15、 用程序来检查(后缀 questiontes) 用于测试的类,贴一个标签 添加引用 .net — nuni.framwork — 贴标签类[nuni.framwork.TestFixture]每个测试就是一个普通的方法,有特殊的要求,1、public 2、void 3\无参 命名为:有一定的含义、

16、 [nuni.framwork.Test] Public void IsPassInitValue() { //这里先创建一道题,然后读取 IsPass的属性,看看是否为 false,如果为 false通过测试,否则失败 Test.Question q = new Question (random,1); Nunit.Framework.Asseert.IsFalse(Question.Ispass); //断言,提供了多种用于判断与我们预期是否相同的方法 } 然后就生成了 然后就是要用软件打开 基本都是解决方案 项目 文件 Nunit里面都是有得 要 new 一个项目 .nunit 保存在哪?保存了之后确实没有马桑存,要选了保存才可以看见,因为刚创建的时候还是在内存的 可以用文本打开 xml文件 17、 其他的标签 重复[nuni.framwork.Repeat(100)] //重复 100次 那么这样进展都是可以训的 namespace test_ClassLibrary1

{

[NUnit.Framework.TestFixture]

public class TestQuestion

{

[NUnit.Framework.Test]

[NUnit.Framework.Repeat(100)]

public void IsPass()

{

System.Random randmom = new Random();

Question q = new Question(randmom, 1);

NUnit.Framework. Assert.IsFalse(q.isPass);

}

}

}

18、 其他的东西,连测试文档都写不出来,那么就是类的设计出问题了,除了功能还要考虑可测试性。为了便于测试定义一个只读得属性 [NUnit.Framework.Test]

[NUnit.Framework.Repeat(100)]

public void Answer()

{

System.Random randmom = new Random();

Question q = new Question(randmom, 1);

int answer = q.A + q.B;

q.Validate(answer);

NUnit.Framework.Assert.IsFalse(q.isPass);

}

Page 20: Csharp

www.happy12.com 010-82387501

19、 文件的保存与读取 写一个复杂的(临时 mock代替对象) [NUnit.Framework.Test]

public void SaveLoad()

{

System.Random random = new Random();

Test.Question question

= new Question(random, 1);

// 临时的,冒充的对象来代替实际的对象

// Mock 对象

System.IO.MemoryStream ms

= new System.IO.MemoryStream();

question.Save(ms);

// 新的问题

Test.Question question2

= new Question();

// 特别注意的地方,Position

ms.Seek(0, System.IO.SeekOrigin.Begin);

question2.Load(ms);

NUnit.Framework.Assert.AreEqual(question.A, question2.A);

NUnit.Framework.Assert.AreEqual(question.B, question2.B);

NUnit.Framework.Assert.AreEqual(question.No, question2.No);

}

测试要足够简单,就是面向对象要提升到输出 输入都十分明确的问题。一般的公司都会由每天的构建核算的东西,所以我们这个时候就很有必要时先测试文档再搞开发的问题 [NUnit.Framework.Test]

public void PaperSaveLoad()

{

System.Random random = new Random();

Test.TestPaper paper = new TestPaper( random );

System.IO.MemoryStream ms = new System.IO.MemoryStream();

paper.Save(ms);

ms.Seek(0, System.IO. SeekOrigin.Begin);

Test.TestPaper paper2 = new TestPaper(random);

paper2.Load(ms);

Assert.AreEqual(paper.Index, paper2.Index);

// 分别读取一道题

// 题目应该是相同的

Test.Question q1 = paper.GetNextQuestion();

Test.Question q2 = paper2.GetNextQuestion();

Assert.AreEqual(q1.A, q2.A);

Assert.AreEqual(q1.B, q2.B);

Assert.AreEqual(q1.No, q2.No);

}

flush 1、 接口 代码重用 , 托管资源,.net 体系下的,首 CLR(公共语言运行环境)管理得内存 模拟出程序的运行环境,但是大量的操作,比如文件操作还是要依赖于操作系统 ,但是也是有一定的指令去告诉我们的操作系统资源我用完了。 Using ()里面必须带有一个有 dispose的应用 try catch finaly 与 using 的区别

2、 Flushj就是不管在缓存区有多少先全部存储到设备里面再说,close是关闭了之后就不能再用了。写类的出发点得问题。内存流与对象的关系 3、 还是从对象上去解决问题,DLL 是什么 最早的程序都是 EXE 编译出来就是一个程序 一个程序就是一个完整的程序 但是随着程序越来越复杂,那么要怎么解决呢? 最好就是一个整体,然后就出现;额函数库 class library 就是写好了一堆的方法 lib 一个 lib就是一个二进制编译完的文件 第一 库里面是一个一个的整体,那么我们就要借助工具直接调用,那么就是编译好得机器指令 保密 运行速度块, 用户利用 link程序就可以把库中的程序找出来,最难的就是 C语言的库 库的时代

4、 但是随着越来越长,exe很强大,但是到最后连内存行业装不下了。DLL时代了来了。为什么装不下呢? 以前的叫做静态链接,现在的叫做动态链接,就是内存只有一份,而且不是直接把内存烤到内存,而是记录了调用 DLL的 path发现内存中有了的话,就是公用 动态链接库时代的灾难,DLL地狱 标准的 DLL,DLL的更新问题 过分依赖于一个动态链接库 会引起 DLL的连锁反映 微软想了一个东西 叫做保护

Page 21: Csharp

www.happy12.com 010-82387501

5、 .net时代 强签名,出现这样的原因是因为存储的信息不同,加多一个说明 专门写一个签名来区分 DLL的所属性 ,即使文件同名 windows也知道这个是不同的

6、 编译链接与库 C语言 打开 DLL的是 2进制语言 ,那么怎么看 DLL文件呢? 7、 这样看 DLL 引用下得小方块就是 DLL 对象查看器 那么部署的基本单位,那么以后我们只要做好 uaing 的工作其实就可以解决了。分成两个部分,一个是 debug 一个是全局共享程序集的问题 ,那么以后就不用再拷贝,而且必须是强签名 渔歌名字叫 JAC 打补丁其实就是一个 DLL ,但是 DLL有很多种 都有专门的格式 windows – Microsoft.net – Framework - (把版本全部补齐)-按类型排序 – ilasm.exe 反汇编程序

tic 静态 美剧 作用域 Static 是什么呢? 从读取试卷的时候发觉不好 ,是因为我们要调用 load的实例的方法 在对象实例了才能使用的方法 要打破凑的原则 没有了默认构造函数,那么咋办? 其实不需要在对象实例上进行,那么准则就是 有必要在对象实例上实例嘛? 通过 static去修饰,static一般称为类级的成员。那么再使用类级方法的时候就 直接 写类 Test,Question Load();//所以不需要对象实例了,直接写类名 那么生成的是一个对象,那么load方法就要改成 quretion的返回值 那么 load里面的方法里面额 this都要进行修改了 单纯的定义不会存在,就是 Quretion q ;这个空的错误 一个叫做值类型与引用类型。与计算机的体系结构有关系 内存放数据有关是 cup不那么块 那么咋办/ 把内存分成块 一块叫堆栈(cpu 堆栈寄存器,指令简单,块) 一块就做堆 cpu 堆栈寄存器(数据寄存器) 所以现在的数据基本都放在堆栈里面 但是堆栈基本都是一 M 那么大。所以这个时候就选择地把大块的数据放堆里面,那么就把指针放到堆栈。值类型的大小都基本是比较小得 大容量的时候基本都是引用类型,那么 new的所有的对象都会在堆里面分配的地,堆栈就记录好了一个名字,要是 question q 就是 new 在堆栈记住对象引用(不叫地址) 堆里面放对象的值 所以 new的对象可以直接放在堆里 作用域:类内部的问题 由于 q.a与 q.b的问题 private引申到的作用域的问题 使用静态的作用与影响 从赛狗比赛的延伸 UML的分析 最好是有记录的 visio ross 不要钱的叫 staruml 新建一个项目 有选择的 有很多不同的风格 模型浏览器 use case用例图 main 双击打开 use case model 椭圆 人型 线 人在使用功能 系统要作什么 人?对象 场景 不要怕多。一般由系统分析师来画 s 分析模型 明确任务我们要干嘛 那么怎么划分类呢? 架构师也是很悲催的 类可以分为 3中 一种是边界类 软件如用户的边界,用户怎么使用 最直观的窗体就是界面,但是也有看不见的,比如 webservice Winform窗体 boundary 中间的那个就叫做控制类 承上启下的左右 ,就是可以操作的,本身不是实体,写逻辑 主要是逻辑控制而不是 还有一种是实体类 是软件的核心 解决问题的核心,找实体类的方法,是 信息事务动作 第三个叫做设计模型;类 接口就是要写了 成员的问题了 方法的问题了 第四种就做序列图 (顺序图):类与类之间的调用关系,相互之间的关系分析出来 类与方法 窗体的实现的实现的问题了。 最后一个就是实现模型 得到最后的设计模型 部署模型 程序集的关系 与问题 序列图 Use case4 MainForm DuKe Match Add SsquenceDiagram 变成代码 生成代码— 选择模型—生成 CS 逆向工程_DukeZ 还能够甚至生成 代码 还可以根据代码是 对象(类) 事务(流程) 信息流(数据,类的实例对象) 动作 (逆向生成图 赛狗分析方法 Analysis 分析 实现 设计 实际 工作中的开发模式 现在基本是 敏捷开发 传统开发模式 工作分配任务的方式 2000 4中开发模式 面临传统开发模式逐渐 老化 难以满足新的软件开发需求 个体与交互 ,生于过程与工具 文档 传统就是在明确了所有的文档之后才开始开发,分发任务 先主体再满足 但是预知的可能性变低,不可能那么全 初步式的开发 领到所有的人员都参加到项目的讨论中来连用户也参与过来 就是先小后大 然后就可以接近客户的需求 迭代式的开发 对新的员工的参与 与客户有更多的协作 可容修改率高 减少开发者的思维 多点用户的思维 从界面开始着手到整个系统的把握 减少程序员化的软件的可能,过分的面向对象不能这样,我们要面向服务 面向切面 迭代式开发 可视化的开发过程 白板开发 项目的进度 全部可视化 领工 也是为了进度一致性 技术总监 产品经理 要效率 而不要深究 项目经理 要把握好 所以我们的项目可支持随意咨询开发 技术总监要超级猛 原则与价值观 沟通 实践 一人一个小工作位 不适合敏捷开发 圆桌式的开发 其实做销售也是很不错得 sstam集成性的开发 就相当于做游戏,怎么玩好这个游戏,玩通关 重构的问题 因为新的程序集的加入,那么就要跟 9的模块重构 但晒核心漏极不要变,遵循原来的业务逻辑 软件公司的基本都要加班,赶得很紧的话,需要加班,多了时间的话,要用至少一半的时间开发出系统 但是进度的透明化 就不适合这样 节约 30%的开发时间 可以提升了 10%的满意度,但是却是牺牲了程序员的自由

Page 22: Csharp

www.happy12.com 010-82387501

服务器的访问量与数据量的解决的优化的问题, 基本模式阿帕奇 IIS ,可以自动写一个内存池 连接池的概念 就是利用游标来较少链接的访问 数据碎片好被拒 资源的不必要的浪费 敏捷开发的数据库 也要依靠代码 代码优先的原则 scrum sp 敏捷开发的方式很多。 Rup统一软件过程 14、 适合所有的类都适合的时候,类成员。由于语法糖的存在所以程序会自动地需找索引,所以要看内部的成员存在否 要是存在则对应的是所在的对象的成员。压缩程序 单个字符表示变量

15、 静态成员的使用的场景:类成员、一个类也是一组数据,定义了一个类也是一个数据,不是静态的话仅仅是类的定义,仅仅是类的一组

数据,当实例化的时候才成为一个内存中的类对象。就是类数据与类对象存在,那么静态的成员就是存在于类本身的对象里,所以就是只有

一个对象。也就是说关于变量的话就是一个公用,最新覆盖,当方法是静态的话,但是方法却是分为两种类型,一种是 new 实例方法(典型特点 this),一种是静态方法 new不可用,

16、 什么时候用。同一类全部都使用 ,就是直接传值就可以直接使用的方法,利用获得目录的方法。Math 算数类都是静态的 就是可以直接利用 sin的方法都是静态,先使用后取值。1类级的数据,2为了减少实例化的操作 一般叫做 SQL 助手类 方便使用。其实设计模式就是把,类的定义 使用的频率都是要设置好,其中之一就是 helper助手类

17、 其实我觉得静态的方法我觉得有点像那个 单向控制器 18、 上课:值类型与引用类型的问题 值与引用 所有的东西都有一个基本类型 System.object 但是不是全部派生的都是引用类型,一种叫值类型 value 一种叫做引用类型。 System.valueType Value: int char bool 基本上都是小型的内存单元 引用类型:class CTS公共语言类型系统

、 堆栈的再次研究 19、 一周学习的内容 常量 变量 结构 数组 链表 ARRYLIST LIST 集合 泛型 设计模式 委托事件 熟读问题 matrix 我就是传说中的母机 20、 数据 同类型 长度不可变 固定 连续记录 后来就出现链表(数据对象+连接对象 ) 对高级的数据结构就很难理解了 新的数据技巧(数据结构) 经常使用在系统编程 每一个单位我们基本上是称作一个节点 node现在就是要定义节点的类型 在链表中需要额外的空间来保存呢保节点之间的链接

21、 单链表 那么基本的原理就是节点的相互的指向的问题 所以循环变量的引用是很必要的 链表远比数组要麻烦 就是解决未知大小的问题 化整为零的特点 其实第二个记录部分不是值,而是下面的一个真正的引用的实例 namespace LinkListSample

{

// 链表中的每一个单位称为一个节点 Node

// 定义节点的类型定义

public class Node

{

// 数据

private string name;

public string Name

{

set { this.name = value; }

get { return this.name; }

}

// 在链表中,需要耗费额外的空间来保存节点之间的链接

// 先看最简单的单链表

private Node next; // 保存下一个节点的引用,这个就是很厉害的

public Node Next

{

set { this.next = value; }

get { return this.next; }

}

// 方法

}

class Program

{

static void Main(string[] args)

{

// 数组方式

string[] names = new string[10];

// 使用单链表来保存

// 第一个名称

Node node_single = new Node() { Name="First", Next= null};

// 第二个名称

Node node_gdg = new Node() { Name = "郭德纲", Next = null };

Node header = node_single; // header 中保存链表中第一个节点的引用

header.Next = node_gdg; // 第一个节点中的 Next ,保存第二个节点的引用

node_gdg.Next = null; // 现在,第二个节点之后,就结束。

// 通过链表来取得保存在其中的名字

// 也是循环,但是,对于链表无从知道有多少个节点

Page 23: Csharp

www.happy12.com 010-82387501

// 判断结束,需要通过 Next 引用

// 对于链表来说,必须保存链表头节点的引用

// 引入一个表示当前节点的变量

Node current = header; // 开始的时候, current 指向 header 代表的节点,下面有递推的思想(而递归就是自身调用自身)

while (current != null)

{

// 当前有一个节点

Console.WriteLine(current.Name);

// 下一次,准备访问下一个节点

// 需要将当前的节点指向下一个节点

current = current.Next; // *********

}

Console.WriteLine("已经全部访问完成。");

}

}

}

那么我们如何封装这个类呢? 保存很多数据 可以任意添加 可以查看全部 特例法也是很好的。 适当的时候要遍历列表 如何封装,基本的数据的对象,一般的方法,补全的对象,对象的控制(程序算法的再次优化),bug修复的问题 如何解决特例的问题 就是说在实例化的时候就预先搞了一个对象站位点(构造函数),但是后面还是要修改后面的读取数据的顺序 也急速和 ihead的实际的意义就是实际存在,全部直接使用头的 next的方法 那么数的方法就是 内部的一个变量 在摸个位置插入 对应索引的输出(对于链式列表也只是一个一个地数,要把原来吃的特例全部改变,必须吧情况全部分析,老实说我很喜欢归类逻辑),当超过position的范围的时候我们也是可以调用一个错误类型的。 namespace LinkListSample

{

// 实现一个单链表,Node current方法里面的中间的变量

public class MyLinkedList

{

// 数据和成员

// 数据

// 对于单链表来说,必须保存链表的头

private Node header;

// 构造函数

public MyLinkedList()

{

this.header = null;

}

//tostring的方法

public void ShowList()

{

// 遍历列表

// 当前节点

Node current = this.header;

while (current != null)

{

Console.WriteLine(current.Name);

current = current.Next;

}

}

// 增加一个保存的数据

public void Add(string name )

{

Node node = new Node();

node.Name = name; // 保存数据

node.Next = null;

if (header != null)

{

Node current = this.header;

while (current.Next != null) // 当有节点的时候,不断向下找

{

current = current.Next;

}

current.Next = node;

}

else

{

Page 24: Csharp

www.happy12.com 010-82387501

this.header = node;

return;

}

//// 在链表中,每一组数据,表示为一个节点

//Node node = new Node();

//node.Name = name; // 保存数据

//node.Next = null;

//// 当第一个节点被加入的时候,需要特殊处理

//// 当 header 还是空引用的时候,就是正在加入第一个节点

//if (this.header == null)

//{

// // 特殊处理

// this.header = node;

// return;

//}

//// 只有一个节点,才能使用

//// this.header = node;

//// 其实是将新节点接到链表最后一个节点之后

//// 找到最后一个节点

//// 第一个有得情况,定义一个表示当前节点的临时变量

//Node current = this.header;

//while (current.Next != null) // 当有节点的时候,不断向下找

//{

// current = current.Next;

//}

//// 当循环结束的时候,一定找到了最后的节点

}

}

}

测试方法 边缘波动域,还是不够认真专注 数据的存储结构 数组,链表的方式就有点不一样了。但是我们想他们的使用方式一样,这个就是叫做逻辑结构。只要我们对他们的数据结构通过逻辑结构的修改,

那么就可以是相似的。那么我们来看看遍历这个问题。 从头到后取出来读一遍, 怎么样抽取出共同点得问题,现在老师就是在传授一个 趋向统一的抽象思维。 迭代器(遍历) Ienumerator 对非泛型结合的简单迭代 就是一个爱一个地遍历一遍 就是不管底层是数组还是链表 都希望在逻辑结构上进行统一。 Reseet复位 movenext下一个(返回的是 bool) current的属性 其实调用了这个接口的话,那么我们就可以有了遍历的功能 public class MyLinkedList:System.Collections.Ienumerator 使用次接口的时候 仅仅是保留Add方法,但是要实现Reseet复位 movenext下一个(返回的是bool) current的属性的方法 我们希望越高级越抽象 最后直接调用是最好的。用统一的,不管底层的东西来编程。自己定义的接口的方法,来体会接口的使用。 Throw new Expection(); 调用了静态的方法object.ReferenceEquals(this.header,this.current);看是否move过,因为要是move的话,head会有next

自定义异常

把相关的功能都藏在类里面,这个就是在内聚的问题

嵌套类的超级利用就是不允许外部知道,其实我的那个类就是Node,令你闻所未闻,绝对的保密

只要支持这个接口,再抽象,就知道迭代器(独立的对象)把遍历的功能与集合的功能拆开 迭代器就是允许我们用 foreach // C# 中语法糖

// foreach 关键字中使用的集合,

// 必须实现接口 System.Collections.IEnumerable

foreach (string name in list)

{

Console.WriteLine(name);

}

// 为了支持遍历,返回一个支持遍历的接口的对象

// 迭代器

public System.Collections.IEnumerator GetEnumerator()

{

// 创建一个用来迭代这个集合的迭代器对象

MyLinkedListEnumerator enumerator

Page 25: Csharp

www.happy12.com 010-82387501

= new MyLinkedListEnumerator(this.header);

return enumerator;

}

List对象中 public class MyLinkedList4: System.Collections.IEnumerable

就是真正的对象是 站头 head(越是高级就越复杂,但是日后使用就越简单) 为了支持遍历,返回一个支持遍历的接口的对象,这个对象就是迭代器,对 对象的完全内聚,那么实际相关的类对象 list()都不知道了。 类的功能越单一,那么日后维护越便捷 获得一个迭代器 , 但是迭代器的类就必须继承对应的 Ienumerator借口了 所以在里面就必须建立紧密的关系,就是在构造函数,声明要传递对象 .net最经典的处理方法 list类,迭代器类 Ienumerable 就是 判断对象类有没有迭代器,迭代器类是否有接口 有好处,这个又来语法糖 foreach 关键字使用的集合必须要实现对应的接口 foreach ()的时候里面的主体必须是要支持支持System.Collections.IEnumerable

20、 可迭代 // C# 中语法糖

// foreach 关键字中使用的集合,

// 必须实现接口 System.Collections.IEnumerable

foreach (string name in list) //组合

{

Console.WriteLine(name);

}

// 为了支持遍历,返回一个支持遍历的接口的对象

// 迭代器

public System.Collections.IEnumerator GetEnumerator()

{

// 创建一个用来迭代这个集合的迭代器对象

MyLinkedListEnumerator enumerator= new MyLinkedListEnumerator(this.header);

return enumerator;

}

namespace LinkListSample

{

// 专门用来迭代 MyLinkedList 的迭代器

public class MyLinkedListEnumerator

: System.Collections. IEnumerator

{

private Node header;

private Node current;

// 当然要与我们的 MyLinkedList 有紧密的关系

// 要求构造函数中得到列表中的 header 指向的节点

public MyLinkedListEnumerator( Node header )

{

this.header = header;

this.current = this.header;

}

public object Current

{

get

{

if (Object.ReferenceEquals(this.header, this.current))

{

throw new System.InvalidOperationException ("在访问当前值之前,必须 MoveNext.");

}

return this.current.Name;

}

}

public bool MoveNext()

{

bool isExist = false;

Page 26: Csharp

www.happy12.com 010-82387501

if (this.current.Next != null)

{

this.current = this.current.Next;

isExist = true;

}

return isExist;

}

public void Reset()

{

this.current = this.header;

}

}

}

21、 using (){}就是要支持 System.Idisposeable 集合的问题 : (1)System.Collections.Ienumerator 遍历 current 、 movwnext、reset

using System.Collections.Generic; System.Collections 命名空间包含接口和类,这些接口和类定义各种对象(如列表、队列、位数组、哈希表和字典)的

集合。

接口的实例,盲人摸象。大柱子,扇子,绳子,肚子,棍子,从不同的角度去认识和理解它,从基类派生,不可改变。从很多角度去看问题。通过接口来了解集

合的诞生。对大家要有更多的帮助。

(2)Icollection copy to count 定义所有非泛型结合的大小(有索引,赋予数组特性,基于数组的列表),枚举数和同步方法。Copy to 将链表存在数组 index

count,

public interface ISet : System.Collections.IEnumerable, System.Collections.ICollection

{

//void Add(object obj);

bool Contains(object obj);

void clear();

}

但是还是不能使用索引(集合的逻辑结构)只读的 获取个数

数组(物理的存储结构)的是length

多线程 一个线程没问题, 动态存储,但是数值却是不行的。一半在操作,一半在遍历,如何解决这些问题?就是线程同步,就需要一个同步对象。

所以为了操作性更好,所以很多时候我们选择了集合而不是数组。

(3)Ilist 接口(高级的数据结构,不是高级的物理存储结构),表示可按照索引单独访问的对象的非泛型集合(索引器)。代表一个列表,增加了很多的方

法。

Add、 clear、 contains(包含) 、copyto、 GetEnumerator、 Indexof、 Insert 、Remove Remove at 。属性:count Item 索引器(看起来很像数组),

比数组要灵活,而且还有集合的机动性。

ArryList 的使用 预测大小一开始是 4 个 但是这个仅仅是内部的一个成员。当超过了 4 个的时候,容量那就是变成 8 个,但是是以 2 的倍数放的,但是会带来

性能的损失。就是先集合在数组在集合再数组地运转,数据结构越高级,效率会降低,但是功能越来越强悍。

那么怎么去解决这个的问题呢?MS 还是定义了好几个构造函数了,里面根据参数的不同,可以实现出不同的 arrylist,它内部是一个在集合与数组的相互的切

换,所以要优化程序的话还是要好好了解内部 运行与执行的机制。内部成员是 object的类,所以可以是任意的类型,要是要添加属于自己的类型的话我建议还

是重写一下 tostring 的方法。但是老师的这个例子 froeach都是取出的是 object类型的 所以 list中最好还是要放同种类型的东西。存什么就拿出什么

强制类型转换,.net 是一个强类型的语言,也就是说每一个变量所存的数据都是有类型的。强类型的语言就是预先检查错误,保证程序的安全运行。那么就是

遵循万物皆有类。因为 class的存在,我们可以创造出属于我们自己的类型。但是游客继承多态,那么在实际状况的使用的时候会变得复杂一些。所以这个这个

时候微软就推出 object的基类对象。那么我们现在的 object P = new Person ();所以存进去得还是那个对象,但是存进去的时候还是转换代 object的基类对

象。但是由于 object的区别的抹平性,所以会有点危险,因为拿出来的还是 object

//所以这里的 string还是强制的类型转换的

foreach (string name in list)

{

Console.WriteLine(name);

}

foreach (object obj in list) //组合

{

//强制类型转换cast,但是这个是错得,是有条件的,即是类型本来就是要符合(person是object,但是person就不是string类型,所以还是要理解清楚,所

以就是装箱与拆箱的问题,所以类型转换有两个基本的特点,一个是小byte到大int,另一个是类型相合,比如:就是person确实不是string,启示,看问题要

看关键点)

String name=(string)obj;

Page 27: Csharp

www.happy12.com 010-82387501

Console.WriteLine(name);

}

还有一个类型转换 引出 as 但不是强制类型转换

foreach (object obj in list) //组合

{

//as,用于引用类型,如果类型不相容会返回一个空引用,那就是什么也没有,同常在as之后加上一个判断,以得到转换是否成功

String name = obj as string;

Console.WriteLine(name);

}

装箱与拆箱(类的转换的理解)其实就是为一个堆栈里的值,装一个壳,放到我们的堆里面,减少内存的占用的问题(其实也就是为了把值类型的数据放进 arrylist,

而且取出来还是 int,这样就为了保持数据的完整性,但是会牺牲一部分的性能,因为每一个值,都是一个对象)

也就是利用了 object来处理值(堆栈,而托管的堆是存储引用类型的内部数据的)类型的传递的问题

Java采取的办法是,再创建一个类,定义一个包装的类,就是每一个值的对象就要一个包装的类的对象。

C# 装箱其实就是由系统帮助我们创建一个对象实例,就是直接赋值,其实数据没用从堆栈移走。

从 arrylist 取出来的都是对象;我放进去是一个值,拿出来就是对象了?到了之后,箱子就没用了

但是我们也不知道本来得类型,但是要是对象引用是对象装箱的,那么系统就会知道这个被装箱的对象的类型。就是说,知道我们与它的实际类型匹配的话,直

接用强转换 cast就可以拆箱取值。

字典 table 就是一个关键字对应一组数据。Key 键 value值,一对一对的就称为条目。支持遍历,其实返回是一个条目类型。

本身是条目的集合,有 keys的集合,也有 values的集合

List可以放,但是拿得时候就悲催了,字典就是根据 key来找到 values ,那么我们就不用数下标,我们可以拿到一个标识顺利地拿到我们的对象。

字典的存储结构是 hash哈希,字典其实就是为了找,通常内部不会按 list来存,逻辑结构是:链表集合。

一般的算法是稳定算法,那么哈希的精妙在与杂凑,先创建一块大得空间给你,根据你要加的数据,来算出要存在哪,怎么算呢?hash算法。

不是根据存数据的位置算得,是根据 key的哈希算法算出存在哪的下标位置,下次要查询的时候再次根据的我们的哈希算法算出的位置就直接获取到我们需要插

选的对象。就是说利用二层逻辑存在对应的内存单元,就是内存与其他资料建立关联,这样就不用去查找了,直接匹配就好了。

#region 绑定到txtBianHao的调拨自动编号

public string SelectDiaoBoZiDongBianHao(Model. JXC_CangKuDiaoBo_TianJia myDiaoBoDaDanTianJia )

{

Dictionary<string, SqlParameter> MyDictionary = new Dictionary<string, SqlParameter>();

MyDictionary .Add ("type",new SqlParameter ("@type",SqlDbType.Int ));

MyDictionary.Add("DiaoBoZiDongBianHao", new SqlParameter("@ZiDongBianHao", SqlDbType.NVarChar, 150));

MyDictionary ["type"].Value =myDiaoBoDaDanTianJia .ZiDongBianHaoType1 ;

MyDictionary ["DiaoBoZiDongBianHao"].Direction=ParameterDirection .Output ;

return Convert.ToString(DAL.SQLHelper.ExecuteScalar("XiTong_ShengChengZiDongBianHao" , CommandType.StoredProcedure, MyDictionary,

"DiaoBoZiDongBianHao"));

}

#endregion

直接上汇编来写,那么编译器我们倒不如直接用 hash 表,去记录我们的位置,所以这个就可以减少了很多的遍历的时间。Hashtable 的办法位置重复的时候如

何解决冲突?拉链算法,搞一个链表那么一个位置就可以存好几个。

GetHashCode();与字典的关系 看起来一样的,但是 hashcode 不一样,所以在字典里面的还是不同的。所以除了 equals()还要重写 GetHashCode 的方法

所以比较相等的 euqals GetHashCode 还有运算符重载 3种 方法

// 判断两个对象是否值相等,也就是说,是否代表同样的含义

// Object 的默认实现是判断是否同一个对象实例

// 不是同一个对象实例就不会相等

public override bool Equals(object obj)

{

if (obj == null)

{

// 不可能

return false;

}

Person other = obj as Person;

if (other == null)

{

// 与自己不是同一种类型

return false;

}

return this.name.Equals(other.name);

}

// 将会继承 GetHashCode 方法

// 为了能够在字典中作为 Key 的时候,也可以含义相等

// 必须重写 GetHashCode 方法

public override int GetHashCode()返回该字符串的哈希代码。

{

return this.name.GetHashCode();

Page 28: Csharp

www.happy12.com 010-82387501

}

哈希表黑洞,修改了值之后,就很难拿回来了,特别市 key是引用类型的,哈希表黑洞,

就是修改了以为类对象为 key的条目的那个类对象里面的值,那么本身哈希表的 value不变,但是哈希表的 key会变成新的引用

修改也只能是对象找出是根据 key,而是先照到原来的,在修改里面的 value

还有一种叫做 set,但是本身还是一个集,lsit是有序的,可以重复的;set是就是数学上讲的集合,就是由就行,不可以重复一样的数据借助与字典来搞一个

模拟出一个 set

数独游戏的原理,就是把数据用数字表示的解决方案的问题,对象的建模(领域对象)

也就是先出题在 解题的问题。 就是先定义 首先是因为是有序的问题 所以我还是觉得用 point 小关联

集合常见的接口都归纳一般

1、 public class MyLinkedListEnumerator: System.Collections.Ienumerator 迭代器接口 current当前object 、movenext 下一个bool、reset 返回 void

2、public class MyLinkedList4: System.Collections.Ienumerable 支持迭代接口 ublic System.Collections.IEnumerator GetEnumerator() 返回的是一

个接口 关联foreach

3、System.Collections.Icollection 集合接口 count 数目 int 、public void CopyTo(Array array, int index) 可以挨着放 ,public bool IsSynchronized

public object SyncRoot

4、System.Collections.Ilist 列表的接口 有序索引器, 可以重复 ArryList列表集合迭代器

5、System.Collections.Iditionary 字典接口 DictionaryEntry Key Value System.Collections.Hashtable( 无序,建不可以重复)

6、Iset 集(无序,不关心顺序,可重复) 基于hashtable的实现类

22、 如何利用高级的数据结构解决实际问题,解决 9宫格的问题,魔方 23、 因为是 所以我觉得要用 3维数组去解决问题 x,y,value 其实我们更加关注组的问题。 24、 所以一个格就是一个类 (构造函数的问题,利用值与数据集的问题),然后一个维度就是用数据集的问题去解决。其中把实际的东西 Contains 实现 IDictionary.Contains。其表现与 ContainsKey 完全一样。

此方法的运算复杂度是 O(1)。

从 .NET Framework 2.0 开始,此方法对 item 使用该集合对象的 Equals 和 CompareTo 方法来确定项是否存在。在 .NET Framework 的较早版本中,这是通过对集合

中的对象使用 item 参数的 Equals 和 CompareTo 方法来确定的。

此方法的表现与 Contains 完全一样。

此方法的运算复杂度是 O(1)。

从 .NET Framework 2.0 开始,此方法对 item 使用该集合对象的 Equals 和 CompareTo 方法来确定项是否存在。在 .NET Framework 的较早版本中,这是通过对集合

中的对象使用 item 参数的 Equals 和 CompareTo 方法来确定的。

1、什么是模式,其实是经验提升到理论的水平,很多时候都不是研发。所以很多时候要搜索多面的外国信息 总结提炼 观察者模式解决的问题是什么呢?就是很多的类,那就是要理清楚类与类之间的关系 界面也是有很多的类打交道。就很容易造成你中有我,我中有你。程序很容易庞大,界面与业务逻辑都纠结在一起。 而且很多时候不但要把硬件之间的关系分类 有时候还需要要针对持久 还有业务进行分类。 2、观察者模式(为了实现交互对象的松耦合之间的设计) 是主题仅仅知道观察者实现了某个接口。1、主题完全不用知道观察者是什么类,做了什么,有什么细节(接口开发) 2、第一封装好变化,3、观察者要继承接口,4、动态对观察者进行控制,不要面向实现编程,要面向对象、面向抽象编程,有一种东西叫依赖倒置。5、主题不会因为因为观察者而需要修改代码,主题仅仅是针对实现了接口的观察者发送通知 6、 is(同一种) has(有的关系) 是 is抽象基类 还是 has接口 7、在 1对多的依赖关系下,当主题的状态发生变化,那么所有的依赖者就会收到更新的操作,但是观察者必须在主题做好注册与登记(用集合,集 set比较复杂,实际上就那一个 list就可以解决了来记录)。观察者也可以是其他观察者的主题, 然后就是迭代观察者,其实就是调用一个方法,那么要求观察者有一个统一的接口,这样就很容易去适应需求的修改。令程序有弹性。 Don,t call me I will call you 好莱坞原则 解决强耦合的基本原则。

Page 29: Csharp

www.happy12.com 010-82387501

3、利用气象站的项目 API应用程序访问接口 就是 3个布告板根据检测的资料 实时更新,封装就是封装变化,减少波动 4、.net解决观察者模式,委托与事件 托管的环境就是好啊,对内存全部的预先的监控,速度会有点慢 所以在 C语言指针式很流行的 为什么不愿意用呢 因为这样不好用好。C语言迭代程序出现的问题就是因为指针没有用好的问题 所以程序很容易写错 很容易崩溃 然后就出现了函数指针的东西,每个方法都有一个指令地址,那么 CPU指令寄存器 就根据指令对方法进行调用 ,动态执行任何的方法,但是高级语言一般不行,但是 C语言就可以通过地址进行动态的方法执行,动态方法的调用,函数指针 ,C语言底层开打的核心语言 不就是 CPU读数的问题了,用得多学得少,因为实在是很难控制。强大与不稳定并存。 那么我们的微软如何解决这个问题呢?如下:动态调用一个方法是核心,那么微软就是 函数指针进行包装,在.net下实现了一个安全可靠的函数指针,称作委托。 Delegate 版若波罗蜜如是我闻 慢慢理解 符号而已 要解决什么问题呢?地址错了,必须是指向一个方法的地址,但是方法一般会有参数与返回值,这个时候把方法传进去的时候,方法再去堆栈把对应的参数进行调用 也就是调用的目标的方法,方法必须先吧参数安置在堆栈里,然后委托调用方法的时候,在后面才逐个调用函数的参数的堆栈。顺带关系。那么返回值的问题呢? 显示函数的地址 然后是参数(方法把参数放置在堆栈) 然后是返回值 最后的时候就再从堆栈里面抓取回原来的返回值 包装成为一个对象里面去解决,所以只能是全部描述正确的时候我们才能使用,但是。Net不允许你们拿到函数的地址,那么我们怎么写出这个功能呢? 25、 定义 委托的定义,也就是说委托起始是定义了方法的一盒总类,不关系方法的使用,只关注方法的类型 Public delegate int AddMethodDelegare (int x, int y); //函数地址方法名,参数,返回值要全部一致 AddMethodDelegare add = new AddMethodDelegare( math.add); //函数地址方法名,参数要一致同名还要了类型相同,返回值要全部一致 Add(参数 那么.netj就是利用委托执行了 接口里面的一个方法,那么就自动执行了。委托可以代表放大,可以忽略类,只关心方法的参数与返回值。 一般委托是用来反身调用的 总结与运用 主题与观察者,那么我们如何解决我们的松耦合的问题最后还是解决方法调用的问题,Java就是用接口来实现的 但是基类仅仅是只能有一个基类,那么必须我们实现观察者的接口,那么它的方法实现吗? .net 的委托,要求很少,那么定义了一个委托那么我们就可以在不实现接口的状态下,那么委托就是代表一类的方法。可以专门针对方法来进行一定的控制。 public int Div(int a, int b)

{

return a / b;

}

}

// 也就是说,委托定义了方法的类型

// 在 .NET 下,使用委托来定义方法的使用

// 不是在写真正的方法,而是在定义方法的使用类型

public delegate int AddMethodDelegate (int x ,int y);

// 重新定义使用一个整数参数的委托

public delegate int DoubleMethodDelegate (int x);

class Program

{

static void Main(string[] args)

{

// 通常如下使用

Math math = new Math();

int c = math.Add(2, 3);

Console.WriteLine(c);

// 下面使用委托来访问

AddMethodDelegate addPointer

= new AddMethodDelegate(math.Add);

// 直接通过委托来访问方法

// 在这里,委托代表了一个方法

int c2 = addPointer(2, 3);

// AddMethodDelegate errorDelegate

// = new AddMethodDelegate(math.Double);

DoubleMethodDelegate correctDelegate

= new DoubleMethodDelegate(math.Double);

Console.WriteLine(correctDelegate(2));

Page 30: Csharp

www.happy12.com 010-82387501

// 对于委托来说,关心的是方法的参数和返回类型

// 所以,对于除法的方法也可以使用

AddMethodDelegate divDelegate

= new AddMethodDelegate(math.Div);

Console.WriteLine(divDelegate(8, 2));

常见的几种委托 Action委托 void Action (); //为方法起了一个小名 特殊的方法使用方式,叫做匿名方法 就是利用委托来找到方法 static void Main(string[] args)

{

// 因为是实例方法

Demo demo = new Demo();

System.Action action

= new Action(demo.Hello);

// 以后,可以直接使用 action 来代表这个方法

action();

// 特殊的方法使用方法

// 匿名方法

System.Action action2 = new Action(delegate() { Console.WriteLine("Hellow"); });

action2();

// 匿名方法可以简化为如下的写法

System.Action action3 = delegate()

{

Console.WriteLine("Hellow");

};

action3();

// Lambda 表达式

// 匿名方法的更加简单的写法

System.Action action4 = () => Console.WriteLine("Hellow");

action4();

}

而且放在 action[]里面的时候,还能够编译一次 对于那个weatherdata这个例子,其实就是 主题里面有一个委托的数组,里面对象是 注册了 //注册,将观察者的方法 放入

public void RegisterObserver(Update method)

{

this.list.Add(method);

}

观察者的方法的委托(在实例化观察者的时候// 注册

subject.RegisterObserver(new Update(observer1.Update));

) 然后遍历通知 private System.Collections.ArrayList list;

public void NotifyObserver()

{

foreach (Update method in this.list)

{

method(1, 2, 3);

}

}

Page 31: Csharp

www.happy12.com 010-82387501

static void Main(string[] args)

{

// 主题对象

WeatherData subject = new WeatherData();

// 观察者

CurrentCooditionDisplay observer1 = new CurrentCooditionDisplay();

// 注册到列表

subject.RegisterObserver( new Update(observer1.Update));

// 通知

subject.NotifyObserver();

Console.WriteLine("..................................................." );

// 可以动态增加观察者

ForecastDisplay observer2 = new ForecastDisplay();

// 注册

subject.RegisterObserver(observer2.Update);

// 再次通知

subject.NotifyObserver();

Console.WriteLine("..........................." );

// 动态取消注册

subject.RemoveObserver(observer1.Update);

// 通知

subject.NotifyObserver();

}

委托集合 其实是二为一体

// 数据,现在使用委托,委托内已经包含了一个委托的集合

private Update list;

// 构造函数

public WeatherData2()

{

// 现在,初始化的时候没有需要表示的方法

}

public void RegisterObserver(Update method)

{

// 通过 += 符号进行保存

// 当 list 为 null 的时候,将会保存第一个委托

// 如果不同空,那么,将新的委托增加到委托集合中

this.list += method;

}

public void RemoveObserver(Update method)

{

// -= 从集合中移除

this.list-=method;

}

public void NotifyObserver()

{

// GetInvocationList() 返回保存在委托中的委托集合

foreach (Update m in this.list.GetInvocationList() )

{

m(1, 2, 3);

}

}

ForecastDisplay observer2 = new ForecastDisplay();

// 注册

subject.RegisterObserver(observer2.Update);

第三版 第四版

事件模式 event

打破了以前死得对象,就是主动性,活性。我们的获知是被动地接受的,最终这样的模式推动了事物的发展。也就是说万物都是主题

跟你事件定义的委托相同就可以了。状态 方法 事件 当我们的状态发生变化的时候i就主动地通知别人的。事件使用的惯例:触发事件的方法一般式protect的

收保护的,一般的名称是:有意义的名称 DataChanged OnDataChanged

Page 32: Csharp

www.happy12.com 010-82387501

如果需要在类外需要OnDataChanged的方法,那么你喜欢叫啥叫啥 TriggerDataChaged()

1、 数据库 专门开发数据管理的软件 专门呢管理数据的软件就是数据库 减轻开发人员的负担 一开始的是层次化的数据 网状数据库 后来也发现很麻烦 到 70 年 efco 开创了关系代数的数据库 技术难度大 oracle 拉里 创造性的人 关系数据库 大客户 美国国防部 随即开始出现关系数据库的旋风 IBM DB2 DBS3好猛啊,出现问题 但是兼容性很不同 最早的时候没规范 操纵数据库的 SQL语言 变成了标准语言 微软也推出了 SQLserver 免费数据库的诞生 myServer 数据库是一个软件,那么我们不需要 2进制保存数据了,但是却是要跟数据库产生交互,那么命令式 SQL 有技巧的 数据库就是万物皆关系 在使用上有一点区别 学 SQL的时候处理处理 先学共同点,再学特异性 安装 SQL 学习资料,电子书,深入浅出 SQL SQL2008技术内幕 索引视图的问题分析 冠军 老师以前是讲 Oracle数据库的、 SQLEXPR 与系统无关 个人版本、标准、企业版(服务器)、开发版 2、 操作的方式有两种 视图 命令 访问的口令 3、 输入帮助命令\h \q推出 4、 选中 按回车就是复制,但是必须是快速编辑模式 5、 ESC是清理整行 6、 保存所有数据的地方,存储在数据文件里面,DBA就需要关心,直接使用数据库,但是文件还是可以使用的,物理放入格里型。逻辑存储与物理存储(硬盘内存,数据库文件)

7、 首先必须要有数据库,包转所有数据的文件,数据库 8、 数据库 database,数据库包含所有使用的东西, 9、 表 table,二维表,一行就是一条数据,列就是 colum 要 确定表的列 第一库 第二表 第三列 列的类型,那么可以帮助我们过滤数据,防治脏数据入库

10、 那么我们需要记录什么信息呢? 11、 关系数据库先抽取出关系 建立一个二维表 数据库本身是一个容器,真正的信息是存储在表里面的。 12、 各种行业的数据库的数据的类型 名称、 Txt另存为 .sql 那么就会直接是 SQL文档了 Source C:\\\\文件的物理路径 数据库脚本里面一定呀设置好每一步,要不会直接跳过执行下一步 Tee 声明输出 /////这里的时候就是要执行输出保存到 这个指令下所有的操作都保存在对应的目录下 Notee 全部保存,tee截止 Show databases; 展现出所有的数据库 mysql> show databases; mysql> show tables; +------------------+ | Tables_in_drinks | +------------------+ | easy_drinks | +------------------+ 1 row in set (0.00 sec) mysql> show create table servers; 查看建表脚本 +--------------------+ | Database | +--------------------+ | information_schema | | gre_list | | mysql | | performance_schema | | test | +--------------------+ 13、 create 创建一个数据库(存储结构)

创建表 varchar会自动分配空间,但是还是会限定最大长度

Page 33: Csharp

www.happy12.com 010-82387501

多少行受到影响,使用多少时间

mysql> use gre_list;

Database changed

mysql> create table my_contacts(

-> last_name varchar(30) not null,

-> first_name varchar(20) not null ,

-> email varchar(50) not null,

-> birthday date,

-> profession varchar(50),

-> location varchar(50),

-> status varchar(20),

-> interests varchar(20),

-> seeking varchar(100) ); 最后一行不要加;号

这样得到的 show create table 名得到的数据 需要进行处理:用 create命令 26、 需要删除,最后一行的代码,作用是声明数据如何存储与使用的字符集 27、 删除所有的单引号 就可以了 28、 改为自增 last_name int not null Auto_increment, 29、

30、 当然还要先删除原来的表 create table my_contacts(

last_name int not null Auto_increment,

first_name varchar(20) not null ,

email varchar(50) not null,

birthday date,

profession varchar(50),

location varchar(50),

Page 34: Csharp

www.happy12.com 010-82387501

status varchar(20),

interests varchar(20),

seeking varchar(100) ,

Parmary kry (last_name) ); 最后一行不要加;号

检查 desc 表名;descry

14、 use 使用

15、 Drop 删除 use myMoneyDB; drop MoneyUsing;

16、 Alter 修改 添加列 Alter table 表名 Add column 列名 int not null Auto_increment自增 first 上调至第一行,当然还有 after 列名 转移到某列的后面 Add primary key (列名); 设定为主键

Page 35: Csharp

www.happy12.com 010-82387501

Alter table 表名 rename to 新表名;

修改名的同时 改变列的类型属性 与设置主键 Alter table 表 A change column 旧列名 新列名 int not null auto_increment, (这边的都是连列名也一起修改) Add primary key (新列名)

一次改两行

但是这样盲目地改数据,会出现类型兼容的问题。有的时候会数据截断,有时候甚至会丢失部分数据 要是我们想通过要是仅仅去扩张值的类型 而不想改变列的名字,我们可以用 modify Alter table 名 Modify column 列名 新的数据类型

Page 36: Csharp

www.happy12.com 010-82387501

Alter table 表名 Drop column 列名 ; 直接删除 Alter table 表名 Drop primary key ; 删除主键 Alter table 表 Change column 旧名 新名 int not null ; 删除 auto_increment

数据类型 根据存储的大小,作用进行选定 适合的数据用适合的类型,速度要最快 数值的选定是有条件的,比如邮编 适合 char(6) int是为了要计算 Varchar(30) 可变的 最大是 255个字符 SQL结构化查询语言是 8000个字节

Page 37: Csharp

www.happy12.com 010-82387501

Int integer 处理整形,也可以处理负数, Dec decimal 处理数值空间,一般是处理小数 decmail (a,b) a就是总数位,b是小数位 Char(30)、character 严谨负责的数据, 固定长度的,先分配 30个空间,不管你有没有 电话号码等非计算类的数字 BLOB 大量的文本数据 CLOB(oracle)分两段存储,会查询很多 Datetime适合记住未来的事件; timestamp 当下的时间 但是 time却不涉及日期 date是年月日 Bit true or false 行 row 或者是称为 record 列 column 列 或者称为 字段 数据库所有没有被赋值的字段都是 null 加一个约束不允许该字段为 null create table my_contacts(

-> last_name varchar(30) not null,

Default默认值 create table my_contacts(

-> last_name varchar(30) not null default ‘noname1’,

RDBMS错误反馈器

缺少了对应的 location的值 ERROR (136(21S01)) 有些时候答错字也会出现这种错误 即是对应错误还有打错字漏了符号会出现 1136 21S01 的错误

当最后一个值缺少逗号的时候:1046 4600

查询语句 最好把复杂的语句分行 Select * from 表名 *是通配符 表示所有一切 查询的一切的一切都要看数据表提供了什么信息 Where语句的引入 And 关键字的引入 Or关键字的引入 二者选其一 符号引入 > 大于号 <小于号 =等于 <>不等于 >= 大于或者等于 <=小于或者等于 以上是针对数组的比较大小的 有需要的时候还能够截取开头字母的位置 >=’L’ 开头的第一个的字母比 L要后或者直接是 L; <=’M’ 开头 第一个字母比M要早或者就是M

Page 38: Csharp

www.happy12.com 010-82387501

Where 字段 is null 当这个字段为空 模糊查询语句 where 字段 like ‘%CA%’ 前面的 CA%就是前面的是 CA %CA就是后面是 CA的 %%夹住,就是前面 后面 内容中间包含字段的 %也是一种通配符,代表任意数量的未知字符的替身 _的引入 where 字段 like ‘_im’ _是代表一个位置字符的替身 、 连续量 Between的引入,Between where scort between 20 and 30 同理 Between where 字段 between ‘A’ and ‘B’ 离散量 In 的引入 select 字段 from 表 where 字段 in (,,) 即是 in 是用来表述字段 in 在某个集合里面 其中在 in 的集合里面还可以嵌套集合语句 那么 not in 就是包含不在 in所对应的集合的所有可能

Not的引入 not一般是用于字段之前,一定是跟在 where之后,当与 and or 连用得时候要跟在 and or的后面 select * from 表 where not 年龄 < 20 即是查询 not单独作用在 where后面语句的所附的补集里面 不是大于 2就是小于等于 2 就是这样的意思 Not 条件 and 呢? 那么只是针对 条件一进行处理 插入语句 insett into 表 (字段)values (值) 字符类型的都要 ‘’ 括起来 但是数值类型的话 就不需要 仅仅是把原来的都 加上 mysql> insert into my_contacts (last_name,first_name) values ('cheng','chen'); Query OK, 1 row affected (0.05 sec)

Page 39: Csharp

www.happy12.com 010-82387501

有时候我们在 insert人名的时候会出现单引号 所以我们会在这个单引号前面 添加 \ 即是 \’

或者是在’的前面再添加 ‘ 变成 ‘’这样就可以达到效果

这种方法称为转义

Delete与 update 语句 联接 join 这样就可以从别人设计得很烂的数据库中获取不再重复的数据 Delete from 表 where 条件 Delete是可以删除一个 record 即是一行的 但是 delete是不能删除单一列的值或是某一列的所有值 但是 delete是可以同时删除多行的 只要合服条件的话 数据库的 CLR 是 RDBMS 还有 delete from 表 可以直接删除这个表里面的所有的行,但是还是会保留本来表的结构 Insert 与 delete语句的双步协作,其实就是 uodate语句 因为删除语句的特殊性,所以实际上我们都是先查询(条件全部设定好,再进行删除)这样就是比较靠谱的 所以这个时候就很想有一个一步到位的方法可以帮助我们实现添加与删除这就引出了我们的 update语句了。 Update 语句类似 delete语句也是可以操作一行或者多行语句。 Update 表名 set 字段 = 值 ,字=段值 where 条件 要是不添加 where 那么表下的所有的数据都会被对应更新 而且 update set 可以套用本身的运算符号的呢 const=const+1 等等 到后期还会有数值套用,还有文本变量上的操作,比如大小写的操作函数 Lower()。

数据库的设计原则与范式 2、 数据库的设计师根据信息要素、关系来设计的 3、 数据库的信息查找依赖于信息的使用方式的 4、 对于可有可无的东西,我们需要花点时间去好好斟酌;

Page 40: Csharp

www.happy12.com 010-82387501

5、 简短的查询,比囧长的业务查询来得更 6、 使用数据的方式将会与我们占用系统内存与硬盘息息相关,影响着服务器的整体表现 SQL换一句话其实就是关系数据库管理系统 Realtional Database Management System ,RDBMS 表的设计原则: 22、 挑出事物,对象信息浓缩法 23、 信息扩散聚拢法 24、 信息拆分成块 25、 事务需求拆分法 还有钓鱼者信息。往后还要拆分成为 钓鱼流水表 记录表 地区信息表 26、 数据的发散与聚合程度的分析(原子性的问题 atomic,业务的最小信息元)

数据库的原子性数据原则

即是当数据具有原子性,那么就不能再拆分得更小块了。但是我们这里理解原子性事根据业务的最小信息元进行的。

比如送外卖的只需要街道与门牌

但是房地产则是需要单独的街道 与门牌

P200

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php SQL返回的是一个集合,null 也是一种集合,称为空集 SQL换一句话其实就是关系数据库管理系统 Realtional Database Management System ,RDBMS 表的设计原则: 27、 挑出事物,对象信息浓缩法 28、 信息扩散聚拢法 29、 信息拆分成块 30、 事务需求拆分法 还有钓鱼者信息。往后还要拆分成为 钓鱼流水表 记录表 地区信息表 31、 数据的发散与聚合程度的分析(原子性的问题 atomic,业务的最小信息元) 保持原子性的步骤 你的表是描述什么事物, 你的表是为了适合什么操作语句的设计的, 列的内容要不要原子性的切块,让查询直逼要害 原子性的存在是为了切分适合的信息块 从而达到信息的最大化的使用,并不是无限切分就好,要看实际的应用 但是由于原子性数据的表容易设计,而且运行的所需时间较短(查询信息的指向性比较强),所以对大量的数据处理的时候要加分效果 原子性数据的规则有 7、 同一列中不能存在多个类型相同的值,除非是 BLOB 8、 同一个表中也不能存在有多个存储相同类型数据的列,除非是像教务系统那样子对应每一个列具有不同的意义

Page 41: Csharp

www.happy12.com 010-82387501

让数据具有原子性是设计出规范化数据表的第一步 (当数据库技术顾问度假的时候,数据库设计师们如何快速的了解数据库呢?) 但是到后期你可能会因为数据量以及性能的问题打破这种规范化 规范化建表的优点, 可以减少表中重复数据的存储,减少数据库的大小 因为数据库的切割使得你的查询的指向性更强,查找的数据少,查找得更加快速 但是最后归根到底还是 避免存储重复的数据节省我们的硬盘空间 为什么我们要设计规范化的数据表呢? 因为你的数据库投入使用后数据库的大小日益增大,设计规范化的表 可以时刻保持你应对以后查询 (主要是应对数据库过分膨胀后的 查询缓慢的问题) 根据查询优化的角度设计表的问题 过多的数据集合集成到一列里面查询的效率很低很低,

1NF 原子性的设计是第一范式 你的表是描述什么事物,对象信息主体 你的表是为了适合什么操作语句的设计的, 根据操作设计合适的列 列的内容要不要原子性的切块,让查询直逼要害 根据目标信息对信息集合切块 9、 同一列中不能存在多个类型相同的值,除非是 BLOB 一列不能多值

Page 42: Csharp

www.happy12.com 010-82387501

10、 同一个表中也不能存在有多个存储相同类型数据的列,除非是像教务系统那样子对应每一个列具有不同的意义 一表不能多列 但是这个时候还仅仅是完成了一半,还有另外一半,引入主键 primary key 最后的原因,数据库中包含二维表 无重复的行,列的数据是同一类型 每列唯一的列名 表的格是单值的 主键的作用,可以根据主键查询出我们唯一需要的信息 独一无二地识别出每条记录,主键中的数据在该数据表中是不能重复的。SSM社会保障基金号码是可以拿来迭代,但是由于她的珍贵程度,所以一般是不用来作为主键的,防止客户资料的曝光,防止别人浑水摸鱼 要求 主键不能为空 插入记录的时候必须指定主键的值 主键必须简洁 主键值不能被修改 那么我们现在就会使用 ID 作为实际主键 Code 最为辅助主键 这个是属于人造主键 那么可分性就很强了,也有自然主键比如:身份车牌号等等

mysql> show create table servers;显示表的创建方式 | servers | CREATE TABLE `servers` ( `Server_name` char(64) NOT NULL DEFAULT '', `Host` char(64) NOT NULL DEFAULT '', `Db` char(64) NOT NULL DEFAULT '', `Username` char(64) NOT NULL DEFAULT '', `Password` char(64) NOT NULL DEFAULT '', `Port` int(4) NOT NULL DEFAULT '0', `Socket` char(64) NOT NULL DEFAULT '', `Wrapper` char(64) NOT NULL DEFAULT '', `Owner` char(64) NOT NULL DEFAULT '', PRIMARY KEY (`Server_name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='MySQL Foreign Servers table' | 这样得到的 show create table 名得到的数据 需要进行处理:用 create命令 31、 需要删除,最后一行的代码,作用是声明数据如何存储与使用的字符集 32、 删除所有的单引号 就可以了 33、 改为自增 last_name int not null Auto_increment, 34、

Page 43: Csharp

www.happy12.com 010-82387501

35、 当然还要先删除原来的表 mysql> create table my_contacts(

-> last_name int not null Auto_increment,

-> first_name varchar(20) not null ,

-> email varchar(50) not null,

-> birthday date,

-> profession varchar(50),

-> location varchar(50),

-> status varchar(20),

-> interests varchar(20),

-> seeking varchar(100) ,

Parmary kry (名 ) ); 最后一行不要加;号

创建带主键的表 名 Int NOT NULL DEFAULT auto_increment , PRIMARY KEY (`Server_name`)

Page 44: Csharp

www.happy12.com 010-82387501

直接在表中修改 Desc 表名 添加列 Alter table 表名 Add column 列名 int not null Auto_increment自增 first 上调至第一行, 当然还有 after 列名 Add primary key (列名); 设定为主键

Right (列名, 2) 从右边开始截取 2位的字符

Page 45: Csharp

www.happy12.com 010-82387501

Substring _index(列名,“,”,2) 截取第二个逗号前的字符串

Substring (列,数字 A,数字 B) 截取列中 从 A位开始读取后面 B个字符

Upper(列) 将全部的字母换成大写、

Lower (列) 将全部的字母换成小写

Reverse(列) 反转字符串的顺序

Ltim()去除左空

Rtrim()去除右空

Length (列名) 获取字符长度

Update语句结合上面的内容,达到列值互换的效果

Update 表 set 列 = 列或者处理过得列

267

第一范式(数据有骨有节,还不能是肌肉)

(表套表 ) 二维表 (关系表,有主键,有唯一的标识) 无重复的行 (减少数据的重复记录) 列的数据是同一类型的,每列用唯一的列名 (列名单一,符合数值类型) 表的每格必须是单值的(无复合) 第一范式主要解决的是:信息与业务的逻辑问题,为了日后的努力而不断加油 第二范式 (不能存在多重依赖项,即是数据与数据之间不能分块) 即是所有表中的数据都仅仅依赖于表中的主键 (即是只存在一个单纯的依赖信息) (下图分析可以知道,课程学分依赖于课程号,而课程号却又依赖于学号),有时候也适合做双叉数据链入,把数据全部抽象化 第二范式主要是解决; 数据累觜的问题,解决更新插入删除等得异常

第三范式 (数据中不能存在传递依赖项,即是树根不能再回叉到此 record) 解决传递依赖的问题 第四范式 (树头的选择,即是要求必须是拿直系依赖的终端作为最顶级的主键) 例如:学生 、课程、教师、资料 超级主键 课程教师 学生课表 课程教师 课程资料 都要求满足三级范式 范式就是信息要求的独立性 修改多就要求分得更多

Page 46: Csharp

www.happy12.com 010-82387501

查询多久分得少 一般是两套 低范式的表存查询(后台的话),是搞范式高度集合决定的 下订单是前台数据库 当面对一对多的关系,以为 1为次要的信息依赖,多的类为主要的信息依赖 Case when then 语句 SELECT SUM(Money) AS 金额, CASE WHEN MoneyType = 1 and MoneyType is null THEN '花销' ELSE '得到' END AS 情况 FROM dbo.MoneyUsing GROUP BY MoneyType

Order by 列名 排序的问题 就是按照字符 A到 Z进行排序 针对特殊字符的排序

Page 47: Csharp

www.happy12.com 010-82387501

按多列排序的问题? Order by 列 1 ,列 2 在列 1 排好的基础上在再排列 2 即是要在原来组的上面 一般的顺序是 A到 Z 然后是 1到 999 desc的倒序 z到 A 然后就是 999到 1 而 ASC就是顺序的意思

Sum () 汇总,对应汇总出来的还是 sum (sales) 有时候也可以双重的 order by 的第一个 order by进行汇总

Page 48: Csharp

www.happy12.com 010-82387501

299

论坛地址: http://www.sisheng.net.cn/forum/forum.php 36、 对于 order by 中的 第一个 order by 已经是蕴含了 group by 了 再切合 而且结合的 sum()语句 就是这样

37、 利用 avg() group by

38、 39、 Inside SQL SQL技术内幕 数据库执行语句的执行步骤 写是有先有后的,但是在执行的是有关键字的执行顺序的

Page 49: Csharp

www.happy12.com 010-82387501

40、 设定主键 Primary Key () 或者我们称为唯一约束 41、 外键约束 references 表 (列) 要求前面的表中的数据也下面表的主键同名 生成笛卡尔积 查询的时候就要进行表连接 select * from customers,orders 要是没有声明情况的话都全部匹配,生成所有匹配 笛卡尔积(没有实际意义) 而且做好是什么前缀 前缀。列名 42、 select * from customers C别名 join orders O 别名 on C.customersID=O.customersID 内连接 inner 表 A Join 表 B on 条件

43、 outer 外连接, 就是提取出不满足的数据列 : 内连接的基础上再增加额外的行(参与链接的表但是在内连接没用的) select * from customers C别名 right outer join orders O 别名 on C.customersID=O.customersID 就是把不足的 orders O拉取出来 简化版:select * from customers C别名 right join 从右 orders O 别名 on C.customersID=O.customersID 简化版:select * from customers C别名 left join 从左 orders O 别名 on C.customersID=O.customersID 简化版本:select * from customers C别名 full join 左、右一起 orders O 别名 on C.customersID=O.customersID 就是根据主题 全部存在再绑定从属表的数据 总数就是在此扩展。 44、 是过滤条件 on 三值逻辑 ture false unknow 典型涉及到空的时候 在过滤中,unknow为 false 但是在检查约束中却是被看做是 true 45、 实际上的表都是 22连接的,先两个再与第三个相连· 46、 Count() 就是那些东西都是依赖于后面的 修饰条件语句的 47、 Having () 专门用于分组之后的筛选,所以有 group by 才回有 having 48、 Select是后面执行的,所以是可以起别名的,但是 在比他前面执行的东西不能引用它的别名 49、 Distinct 要是两条结果一模一样就是刘下一句 50、 Secet 返回的是一个 set 但是 VT最后返回的是 VC 游标 实际上是有序的 use MySQL select * from dbo.my_contacts; use myChenji; create table class ( classID int not null , classCode varchar(30) null, className varchar(30) null, primary key (classID) ); use myChenji; create table student ( studentID int not null ,

Page 50: Csharp

www.happy12.com 010-82387501 classCode varchar(30) null, className varchar(30) null, primary key (studentID) ); use myDB; create table result ( resultID int identity(1,1), resultCode varchar(30) null, result varchar(30) null, studentID int null, classID int check (ClassID int (0,1,2)), —check约束 primary key (resultID) ); 约束的问题 references 外键 这样就是要限制的 51、 外键约束 references 表 (列) 要求前面的表中的数据也下面表的主键同名 生成笛卡尔积 查询的时候就要进行表连接 select * from customers,orders 要是没有声明情况的话都全部匹配,生成所有匹配 笛卡尔积(没有实际意义)

--主键约束如下:比如 student表的 id为例

alter table student add

constraint PK_Student_Id primary key (id);

--外键约束如下:比如 student表 id位主键,score为子表 scoreId为外键

alter table score add

consraint FK_Score_ScoreId foreign key(scoreId) references student(id);

create table YY

(id int primary key, email varchar(50),

CONSTRAINT chk_email CHECK (charindex('@163.',email)>0 or charindex('@gmail.',email)>0 or charindex('@QQ.',email)>0 o

r charindex('@yahoo.',email)>0)

)

create table [user](id int identity(1,1),name nvarchar(20),email_id int)

alter table dbo.[user]

add constraint FK_tb_id foreign key(email_id) references tb(id); 唯一约束 unique (列名) 即是每次插入都会检查不能重复 检查约束 建立的时候 scoretype int check (scoretype in (0,1,2)) 主键约束 外键约束 非空约束 ass constraint constraint constraint

关于约束的问题 SQL对各种约束的新建 就拿一个 type来划分补考的成绩的状态的 但是我们仅仅是为了恒定的问题 不能输入 2 3的问题 但是 null是 check不管的,所以为了防止出现情况,我们最好还是加上一个非空约束 MSSQL自增 case 语句 SELECT SUM(Money) AS 金额, CASE WHEN MoneyType = 1 THEN '花销' ELSE '得到' END AS 情况 FROM dbo.MoneyUsing GROUP BY MoneyType

Page 51: Csharp

www.happy12.com 010-82387501

Case 列 When 值 then ‘第一次成绩’ Order by 默认是升序 A-z 1-99 组函数是对多组函数使用的,组函数会忽略空,直接跳过 Select top (100) ++ from Limit () mySQL 7种常见的查询 Master系统数据库 实际创建的数据也会有记录在Master数据库中 Use master;s [SuSheID] [int] IDENTITY(1,1) NOT NULL, Drop [ name ] 利用特殊字段做为列名 这个是事务表到 Create的时候 ( Constraint fk_XX foreign key (本表,外键名) references 表,主键) ) 然后就是内外连非问题 多变链接的问题 执行顺序的问题 Order by 成绩 having sum (chengji) 》260

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php 52、 今天的任务是子查询 转置 索引 视图的问题 alter table tb1 add salary int null(增加一列 salary)

alter table tb1 drop column age(删除列 age)

alter table tb1 alter column memo varchar(200) null(修改列 memo为字段的数据类型)

alter table add constraint name primary key(id)(增加约束 id列为主键)

alter table tabx add constraint df_tabx_sex default 'm ' for sex(增加约束,设 sex列默认为‘m’)

alter table add constraint name unique(id)(设 id列为唯一的约束)

alter table add constraint name check dd in (dd> 50)) 53、 转置 竖向的数据转换成横向的展示方式 54、 那么我们在 join on 与分组的组函数的时候怎么得到学生的名字呢?把前面的查询结果看成一张表,从逻辑上把它看成一张表,一个叫做子查询,一个叫做视图

55、 子查询,把前面查询的结果看成是一张表 语法 ——子查询 Select 需要查询的东西 (不同的表的) from ( select ) inner join tbl_students(要连接的表) ts on 条件,什么等于什么 -- 利用子查询得到学生的姓名 select ss.studentid, ts.[name], ss.totalmark from ( select s.studentid, sum( mark ) as TotalMark from ( tbl_students s inner join tbl_marks m on s.studentId = m.sid ) inner join tbl_courses c on m.cid = c.courseId group by s.studentId ) ss inner join tbl_students ts on ss.studentid = ts.studentid

Page 52: Csharp

www.happy12.com 010-82387501

56、 聚合语句不应该出现在 where中 根据执行的顺序 on where having 没有分组 不能用组函数。为了使用 我们就要好好安排子查询语句的顺序了。子查询中 由 where等条件连接词决定的。

57、 使用子查询,解决实际的复杂的问题 就是查询的结果看成是一个表, 但是缺点就是没用一次就写一次 58、 那么如何解决呢/ 视图,固化的子查询

Create view 名字 as 一堆查询语句 一般是 DBA来设定数据库的视图的 封装内部数据库的数据关系 范式修改数据容易了,视图让我们查询数据变得困难。

8、数据库 一层是物理的无关性(与文件存储的位置 状态无关) 逻辑的无关性 就是 利用各种工具 来搞 那么就是

59、 分组的意义,得到的是什么呢?就是根据相同的进行汇总 所以 group by 最后的指标最好还是最后执行表的指标 60、 转置的问题 就是把竖向的数据横向的显示出来 一个人可能有 3 行的成绩 但是我想把行的转化为列的 其实是分部实现的,第一步 group by 分组 利用 组内的组函数 的条件分组 上来实现 原理就是组函数分组 就是先组 利用有条件的组函数逐个抽取

select * from ( select [sid], sum ([mark]) as 总分, avg ([mark]) as 平均分, avg ( case when [cid]=1 then [mark] end) as [database], avg (case when [cid]=2 then [mark] end) as [C#], avg (case when [cid]= 3 then [mark] end) as [xml] from tbl_marks group by [sid] ) a where a.总分>250 order by a.总分 desc 还有我们可以用case语句来搞出来 利用系统的语句 利用透视列,就是要排除markID,剩下字段就作为分组了 SELECT * FROM ( SELECT [sid], [cid], [mark] FROM tbl_marks) p PIVOT ( sum (mark) FOR [cid] IN ( [1], [2], [3] ) ) AS pvt Sum(mark)就是组函数的约束 For 是针对的对象,in是对戏那个的集合 因为数据库的原因 它的数据是E计算的,但是要引申出 分离之后就可以复制粘贴了 表里面记录着一条条的数据记录,可以帮助我们更好地找到我们的记录。最好的解释就是索引的问题 为什么快呢?因为只有指向没有详细的信息 数据库才是我们字典的正文。 第一个窍门 逻辑索引 缺点 占用空间 编辑的时候需要花时间,可以创建N个逻辑索引 高级的数据结构 是一个B+树 切分成为N个范围 就是 N^层数 就是相对应的总数 那么删除数据之后 索引要更新 就是还要返回我们指令删除对应的位置 新增数据的时候 还要往索引里面添加 那么我们的数据库应该会自动关联的 大幅度提升我们队单体数据的查询 而且树是一棵平衡树,NN的关系嘛,所以要好好努力。 所以数据库的维护 维护索引 隐式索引 有索引就0用索引,可以专门为SQL语句专门写一个索引,查询得很快,但是维护数据库也是很忙碌的。就是要专门针对字段来 索引是用在查询条件里面的 怎么建立索引呢? Create index ins_sid on 表(sid); 就是利用我们的B+树 直接搞出来 好处的体现 显示估计的执行计划

Page 53: Csharp

www.happy12.com 010-82387501

表扫描就是直接查询 就是看SQL如何执行我们的SQL语句 方便我们写出更加高效迅速的SQL语句 函数索引 学生表 针对大小写的name 所以索引为了匹配度 我们决定使用函数索引 Create index index_name on tbl_student ( upper(student)) 根据函数表达式里面直接起作用 否则有的时候是无效的 聚集索引 classIndex 就是按照一定的顺序存储来达到我们需要的效果 那么创建主键约束的时候的时候就会自动建立了一个聚集索引 但是一个字段是一个聚集索引 但是这个会花费大量的时间去调整数据存储的顺序 主键约束的不冲突就迅速提升了聚集索引的使用 订立唯一约束的时候系统也是会自动建立一个索引 管理索引与键 全文索引就是网页 文档 那个时候就需要分词 日志的重要性是 完成没完成 http://www.cnblogs.com/skyangell/archive/2009/09/01/1558255.html

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php 61、 sql临时表 create table #temp 62、 isnull (两个日期) 拿出不为空的。 create table #tmp(rq varchar(10),shengfu nchar(1)) insert into #tmp values('2005-05-09','胜') insert into #tmp values('2005-05-09','胜') insert into #tmp values('2005-05-09','负') insert into #tmp values('2005-05-09','负') insert into #tmp values('2005-05-10','胜') insert into #tmp values('2005-05-10','负') insert into #tmp values('2005-05-10','负') insert into #tmp values('2005-05-11','负') --查询所有信息 select * from #tmp; --利用cast when then end select rq, count( case when shengfu = '胜' then 1 end ) as '胜', -- 其实就是数数 sum( case when shengfu = '负' then 1 end ) as '负' from #tmp group by rq --利用pivot语句 select rq, [胜], [负], [胜] + [负] as 总场数 from #tmp pivot ( count( shengfu ) for shengfu in ( [胜], [负] ) ) as pvt --利用全链接,利用了isnull函数筛选出非空的一项 select N.rq, m.rq, isnull( N.rq, m.rq ) , N.胜, M.负 from ( select rq, count(*) as 胜 from #tmp where shengfu='胜' group by rq ) N full outer join ( select rq, count(*) as 负 from #tmp where shengfu='负'group by rq ) M on N.rq=M.rq

Page 54: Csharp

www.happy12.com 010-82387501

-- 没有join, 得到一个笛卡尔集 -- 这里其实是内联接,所以有一个bug,就是号的没有提取,因为11号的仅仅有负没有胜场 select a.rq,a.a1 胜,b.b1 负 from ( select rq, count(rq) a1 from #tmp where shengfu='胜' group by rq) a, ( select rq, count(rq) b1 from #tmp where shengfu='负' group by rq) b where a.rq=b.rq 自己定义数据库函数 MathMax (int,int,int) 新建标量新行数 TSQL语句引入 其实就是函数与存储过程 然后就是触发器 CREATE FUNCTION MathMax ( --写好参数 @a int , @b int ) RETURNS int --返回的数据类型 AS BEGIN declare @max int if(@a > @b) begin set @max= @a; end else begin set @max=@b; end return @max END GO Select dbo.MathMax(dbo.MathMax(3,4),5) 日期判断的 SQL语句 常见的时间函数 GetDate() 而且时间入库是串的原因 类型转换函数 Cast convert; insert into #tmp values (cast ‘串’ as datetime); insert into #tmp values ( Convert (datetime,’串’) ); where DateDiff ( dd , 开始时间,结束时间) =0 返回的是一个整数 两个 ##成为全局临时表 针对的是多用户的 要是#是针对单用户的,直到所有的会话全部中断的时候才对删除。 数据库与日志文件等等 select id, Count(*) from tb group by id having count(*)>1 create table #tmp1 ( 语文 int, 数学 int, 英语 int ) insert into #tmp1 values(70,80,58); select * from #tmp1;

Page 55: Csharp

www.happy12.com 010-82387501 --请用一条sql语句查询出这三条记录并按以下条件显示出来(并写出您的思路): -- 大于或等于表示优秀,大于或等于表示及格,小于分表示不及格。 select (case when 语文>=80 then '优秀' when 语文>=60 then '及格' else '不及格' end)as 语文, (case when 数学>=80 then '优秀'when 数学>=60 then '及格'else '不及格' end ) as 数学, (case when 英语>=80 then '优秀' when 英语>=60 then '及格'else '不及格' end) as 英语 from #tmp1 --其实也是可以写一个数据库函数的 --table1 --月份mon 部门dep 业绩yj --------------------------------- --一月份 01 10 --一月份 02 10 --一月份 03 5 --二月份 02 8 --二月份 04 9 --三月份 03 8 create table #tmpYJ ( 月份 nchar(10), 部门dep nchar(10), 业绩 int ) insert into #tmpYJ values ('一月份','01',10); insert into #tmpYJ values ('一月份','02',10); insert into #tmpYJ values ('一月份','03',5); insert into #tmpYJ values ('二月份','02',8); insert into #tmpYJ values ('二月份','04',9); insert into #tmpYJ values ('三月份','03',8); select * from #tmpYJ; --table2 --部门dep 部门名称dname ---------------------------------- -- 01 国内业务一部 -- 02 国内业务二部 -- 03 国内业务三部 -- 04 国际业务部 create table #tmpBM ( 部门dep nchar(10), 部门名称dname nchar(20) ) insert into #tmpBM values ('01','国内业务第一部'); insert into #tmpBM values ('02','国内业务第二部'); insert into #tmpBM values ('03','国内业务第三部'); insert into #tmpBM values ('04','国际业务部'); select * from #tmpBM; --table3 (result) --部门dep 一月份 二月份 三月份 ---------------------------------------- -- 01 10 null null -- 02 10 8 null -- 03 null 5 8 -- 04 null null 9

Page 56: Csharp

www.happy12.com 010-82387501 -------------------------------------------- select c.部门dep,c.部门名称dname, sum (case when c.月份='一月份' then c.业绩 end ) as 一月份, SUM(case when 月份='二月份' then 业绩 end) as 二月份, SUM(case when 月份='三月份' then 业绩 end) as 三月份 from( select a.部门dep as 部门dep,a.部门名称dname as 部门名称dname ,b.月份 as 月份,b.业绩 as 业绩 from #tmpBM a inner join #tmpYJ b on a.部门dep=b.部门dep group by a.部门dep,a.部门名称dname,b.月份,b.业绩 ) c group by c.部门dep,c.部门名称dname order by c.部门dep 事务 数据库事务 什么是数据库事务 很多时候我们的操作都不是一步完成的,而是由多次的修改插入删除所完成的 在银行数据库 里面 张三存了1W 那么转账呢? 那么得至少写两条SQL语句 防止程序出现灾难与数据错误 所以在高度自动化的时代,我们就必须搞好。五角大楼的事务例子,利用计算机技术去处理, 一般是从4个方面去理解。ACID A 原子性 就是执行的时候要么整个完成,要么整个失败,就是两条语句构成一个整体,C#是不支持的,而且不论什么状态下都高度保持这样的原子性 B 一致性 指的是数据库是一条条的执行,但是在外部观察不会出现瞬时的不同步,也就是说我们在任何时候查询数据库,就是转得时候也是已经完成业务的(不论什么时候查询,都是保持一致的,就是业务都是执行完毕的,保证瞬时执行的完整性) I 隔离性 就是虽然是一条条地改,但是对于事务外的对象是完全隔离的,但是外部查询是依赖于一致性的,在事务之外是查询不到的。但是Oracle是可以做到的,还是可以直接查询的 D 持久性 一旦事务提交成功那么堆事务的修改是持久更新的,不会因为断电而悲剧。将被持久地存下来。需要DBA提供后备的支持的。支持多种方式的,分布式的话,就是同时在4个地方存储,银行不是那么低级地存得,要求全部都是实时的备份 怎么才能用上事务呢? SQL是有自动事务自动提交 只针对数据记录修改删除的操作。针对的是DEL UPDATE INSERET 就是系统内部自动产生事务,但是是一条语句一个事务,这样也是不同于银行的事务的,对简单的操作特别方便,但是遇到特殊的情况,就会出现问题。 自己要明确地使用事务 显式事务 事务有的时候会很快 因为它只存盘一次 在SQL里面就要使用 begin transaction commit/roolback 遇到的时候就停止 遇到他们事务就结束了,里面就是执行的原子性 。可以执行 只要么有提交一直可以随时rollback 也就是写了之后,先执行 create database myBankDB; use myBankDB; create table bank ( 账户 int identity(1,1), 存款 int ) begin transaction insert into bank values(10000); insert into bank values(10000); insert into bank values(10000); select * from myBankDB.dbo.bank; update myBankDB.dbo.bank set 存款=20000 where 账户>10 and 账户<55; delete from myBankDB.dbo.bank; commit; rollback;开始执行了begin transaction 再执行一半的语句这个时候 停止服务rollback,就会返回原来执行那一条的状态 直到运行至commit才完成事务,要不系统自动回滚 也就是说我们在存储过程里面,或者是C#程序里面直接用事务来封装一次我们的整个事务流程的话,是很幸运的。 剧目表 多张碟子 名称 数量 租金 tbl_Drama DramaID、DramaName、DramaContent 碟子 碟子的状况 状态 谁租 tbl_Disc DiscID、DiscID、DiscName、 DramaID、DescCharge、State IsBorrow、BorrowDate、RecessionDate、Status、IsBespeak、BespeakID 会员 姓名电话预存 tbl_Leaquer leaquerID leaquerCode leaquerName CardNumber Money OpenDate BorrowCount LeaquerPhone 租基表 tbl_Borrow BorrowID BorrowCode leaquerID DescID BorrowDate BorrowLength 预约 tbl_Bespeak BespeakID leaquerID DescID BeapeakDate

Page 57: Csharp

www.happy12.com 010-82387501

还表 tbl_recession RecessionID RecessionCode BorrowID BorrowID Charge 优先分配、 最佳硬碟 增加硬碟 新会员 会员来租 对应来还 扣钱 最佳碟子 预约分配 最佳客户 月报表

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php 63、 IsNull (column,value) 判断 column,要是为 null,则为 value的值 64、 星号存盘, 65、 默认值的作用域,仅仅是在插入数据的时候有用 66、 创建视图 create view name as 查询出来的集合 修改视图 alter view name as 查询的语句 67、 Select * from view_Movie 利用数据库关系图来建表的问题 68、 默认值与关联的问题 69、 外键的关系 拖拉外键指向主键 70、 默认(初始值) 71、 唯一约束是索引/键 10、check 注意 () 不用加 check,因为她是自动放入到 check的集合里面的 select ('Disk'+Ltrim(Rtrim(Convert(char,a.Disk_ID)))+'Movie'+Rtrim(Ltrim(Convert(char,b.Movie_ID)))) as 硬碟编号 , b.Movie_Name as 影片名称, a.RentCount as 租借次数, (case a.States when 0 then '没租' when 1 then '已租出' when 2 then '已预定' when 3 then '损毁' end ) as 状态 from (tbl_MovieDisk a inner join tbl_Movies b on a.Movie_ID=b.Movie_ID) left join tbl_MovieTypes e on b.Type_ID=e.Type_ID;

用事务 ACID 原子 一直 持久 隔离 Begin transaction Begin try Commit End try Begin catch Rollback End catch 但是需要的操作还是比较多的,但是 SQL语句也是比较悲催的,基本上我们是采用存储过程来搞 存储过程的通用性 类似我们的方法,但是是存在数据库的,而且是预编译的,所以不用检查语法直接执行,可以大大地提升我们的效率 Create procedure proc_Deposit ( @name type , @name2 type ) As Begin transaction

Page 58: Csharp

www.happy12.com 010-82387501

Begin try Commit End try Begin catch Rollback End catch alter procedure proc_UpdateName ( @NewName nvarchar(20), @OldName nvarchar(20) ) as begin try begin transaction update tbl_Movies set Movie_Name=@NewName where Movie_Name=@OldName commit; end try begin catch rollback end catch 执行存储过程的名字 Execute name parmmarys ; Execute proc_UpdateName '精武门','新版精武门' ; 不同的数据库的语言也是不同的,MSSQL的是 TSQL ,存储过程一般是解决复杂的业务逻辑操作的问题 存储过程 数据库都支持自主编程 PLSQL oracle 存储过程的深入使用 早上针对的是传入参数 那么今天下午我们就会使用返回值的存储过程 在 oracle就没有返回值,但是MSSQL有。 返回值不是普通的返回值,这个一般不返回计算的结果,一般仅仅是返回整数的类型,若果没有显示返回结果,默认为返回 0,一般是判断存储过程的执行状态 多参数长度的设定要多不要短 Return参数,一般执行成功会返回 0 create procedure proc_test ( @NewName nvarchar(20), @OldName nvarchar(20) --, @Name nvarchar(30), -- @number int output ) as begin transaction begin try if exists (select Movie_Name from tbl_Movies) return 0; commit; end try begin catch return 1; rollback; end catch create procedure proc_create_Member ( @name nvarchar(50), -- 在SQLServer 中一个特殊的问题,数据长度问题e @phone nvarchar(50) -- 如果参数的长度过短,可能造成数据的截断 ) as begin -- 使用return 来表示创建用户的状态 -- 0 成功

Page 59: Csharp

www.happy12.com 010-82387501

-- 1 重名 -- 2 名字为null -- 检查重名 if exists( select member_name from tbl_members where member_name = @name ) return 1; -- 检查是否为null if @name is null return 2; -- 进行插入 insert into tbl_members ( member_name, phone) values ( @name, @phone ); return 0; end declare @return int; execute @return=proc_create_Member 'name','phone'; print @return;--在消息中显示返回的执行状态 同时返回主键的问题 (存储过程利用返回值 output的问题 Execute仅仅是返回 return的 Int一般仅仅是利用此来判断存储过程执行的结果全局变量,下面的是两个一起集中使用 create procedure proc_test ( @NewName nvarchar(20), @OldName nvarchar(20), @Name nvarchar(30), @number int output ) as begin transaction begin try --scope_identity()--标识当前作用域中新创造的主键 --insert之后马上获取当前状态的唯一标识的问题 declare @key int; set @key =scope_identity();--赋值 select @key=scope_identity();--赋值 --但是临时变量@key仅仅在与自己的作用域中,要赋值给传出参数 set @number = @key; commit; end try begin catch rollback; end catch --执行 declare @Pan int; execute @Pan = proc_test 'a','B','C',@number output; print @Pan;--打印,return的 print @number;--返回的 简便法 直接返回一个数据集 双法 数据集+传出参数 Select @参数 =count() from table 就是没返回数据集的话,返回的是 int,成功为 0 excute @参数 = 存储过程 print @参数 有返回数据集的话,返回的是一个 dataset 自连接 table Acolumn→ Bcolumn B 那么再 record中 B就是 A的领导 人事模块中比较适合使用,也可以用作无限级树状

Page 60: Csharp

www.happy12.com 010-82387501

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php 72、 函数不涉及业务,仅仅是对数据的处理;对记录 涉及 事务 还是使用存储过程比较好。 73、 数据库搞一个数据运算,数据库的价值在于数据管理,TSQL 也可以写,但是通常认为数据处理的运算的效率没高级语言的快。所以统计运算放在高级语言,数据库中仅仅是负责存储数据与数据的操作。大量的数据统计,不要放在数据库。读取一遍的记录数据库书要付出很

多代价的。差距是极其惊人的,那么这个就是需要在高级语言的 linq语句了。 74、 主键的选取的问题,组合主键,如何选取主键,唯一依赖,不要拿业务数据的属性做主键,一般我们还是用 ID作计算,在于需求的变化太难控制了。之所以花时间都是因为需求的变化所导致的。减少需求改变的影响,我们要预计到常见的变化。主键的问题,宁愿花销一点资

源记录,也是为了数据库的更加稳定。 75、 强化如何设计的问题?跨数据库的事务?也仅仅是百分之一,现在的数据库宁愿稳定,当然也要优化。设计时候的松野是为了以后的拓

展。 76、 数据库这样不好,不要随便打开数据库写入数据。就规划而言,就不会受到限制。在哪里写验证,不要迷信一切的输入都好,我们应该

各层多各层的检查。你基本是很难遇到的。视图仅仅是一个查询 视图里面是不能写多于两个的查询的,而且也是不能写 if这些逻辑判断的。 77、 触发器,存储过程,函数,触发器。触发器,是一种不用调用的程序,是数据库自己调用的,就是事件委托。写一些触发器注册到数据

库,这种特殊的方式就是触发器。额外的执行定义的操作,除非必要,要不就不要使用。触发器的使用是要建立在速度的代价上的。 78、 完成从数据库的操作的数据处理技术,高级语言就是解决 界面与数据访问 79、 数据访问的历史:1、直接访问数据库,利用数据库的 API应用程序接口,用户的操作操作按照特定的顺序传输对应的 SQL命令,实际上就为了转化为数据库操作命令,这种是最高效的。这种东西开源的,可以很嗨的,不同数据库的 API都是不同的,就是换个 CPU也是很悲催。2、微软就出了一个开放数据连接 ODBC是,让程序员只学会一种方式就能访问所有的数据库。就是把所有的东西就虚拟化,JAVA与 C#一样都是虚拟化,ODBC 是抽象出来的,那么这个时候就需要一个驱动,实际上就是一个翻译。驱动就是翻译 Oracle的数据集指令,获得数据 用户 命令 ODBC API ODBC数据库驱动 数据库 数据库驱动 数据 (最通用的)ODBC带来的损失,那就是慢,但是通用。3、微软推出ado与 ODBC最大的区别就是对象化的直接访问,那个时候与 VB直接关联这个时候数据访问很嗨。后来 JAVA.NET出来了。4、为了迎合.net就出现了 ①:ado.net 最好的就是直接访问数据库的 API这种方式是最好最快的。但是有个缺点就是不好写。现在的数据库就是 4大天王除非出现革命性的突破。所以第一种方式意义不大。但是还是重写了。所以 SERVER就很好。但是 oracle也有。Oracle也有自己写的,这个都是专门写的。最快最好的。 ②:那么小型的数据库怎么办?ODBC出来了,.net写了一个壳,odbc 找驱动 驱动找数据库,ODBC的包装壳。但是这样的确是太慢了,但是对于其他的数据库还是可以实现的。 ③:OLEDB其实就是调用两人以前的 ado,重写了一个 com组件,主要是解决 access数据库的问题

80、 System.data.sqlclient.用于访问托管环境中的数据库程序 81、 System.data.OracleClient 82、 System.Data.ODBC 支持访问所有的数据库 83、 Systemm。Data。OLEDB 84、 面向对象来进行的处理还是很快的 85、 第一步就是要连接数据库 connection 借助类图来查看他们的关系 SqlConnection ConnectionString 连接句柄 方法有 open ,close ① String connectionString = “Server=192.168\\sqlexpress 找到我的数据库的服务器 ; database=Dbname; interated Sercurity = true 使用 windows 集成验证”;

② System.Data.sqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection (ConnectiongString);//创建连接 ③ Try { Connection.open(); Console.WriteLine(“连接成功”); }//很复杂的找到,权限,运作 所以很危险的,所以要 try一下 Catch (System.Data.SqlClinent.SqlExpection e) {Console.WriteLine(e.Message);} finally { connection.close();} 而且也是可以用 using的 失败与协议有关,必要的时候要换,是连接成功的第一步

static void Main(string[] args)

{

string ConnectionString = @"Server= 192.168.0.115 ; Database=myMoneyDB ;Persist Security Info = false;Integrated Security = SSPI " ;

System.Data.SqlClient. SqlConnection connection = new System.Data.SqlClient.SqlConnection(ConnectionString);

try

{

connection.Open();

Console.WriteLine("连接成功");

Console.Read();

}

catch (System.Data.SqlClient.SqlException e)

Page 61: Csharp

www.happy12.com 010-82387501

{

Console.WriteLine(e.ToString());

}

finally

{

connection.Close();

}

}

static void Main(string[] args)

{

string ConnectionString = @"Server= 192.168.0.115 ; Database=myMoneyDB ;Persist Security Info = false;Integrated Security = SSPI " ;

System.Data.SqlClient. SqlConnection connection = new System.Data.SqlClient.SqlConnection(ConnectionString);

using (connection)

{

Console.WriteLine("连接成功");

}

Console.Read();

}

86、 Windows登陆验证,那么安全体系的核心都要放在 windows上,我开机之后就是以为 windows的登陆的身份开机的,然后访问数据库的话,SQL就自动核实你在 windows的身份。实际上还是要检查的,可是方便,安全,保护你的账号与身份。在安全性,登陆名 所有可能登陆数据库的用户角色都必须在 SQL里面设定的。Win32useer,adimistrator用户登陆验证

87、 还有一种是 SQL验证方式 88、 SQL数据库服务器访问模式,安全性,上面是微软下面的是混合的模式 数据库服务器必须要设置为支持 SQL登陆验证的方式

89、 90、 用户映射的问题,权限列表 顺序依次为:登陆(windows、sa)、将登陆名映射为用户名、数据库、操作数据库操作权限 91、 检查是否打开了端口 TCP/IP 入站的规则 1433的端口。打开这个端口,一般是不用设置出站的。

服务与 managementstudio 的区别 managementstudio 是一种管理工具,是操作数据库的界面工具而已 那么哪个是我们真正的 SQLServer 服务 Sqlwxpress只要这个启动外部就可以联网了,这个是最重要的核心的服务。 执行 SQL命令

Page 62: Csharp

www.happy12.com 010-82387501

非查询 ExecuteNonQuery 返回影响的行数 string ConnectionString = @"Server= 192.168.0.115 ; Database=myMoneyDB ;Persist Security Info = false;Integrated Security = SSPI " ;

System.Data.SqlClient. SqlConnection connection = new System.Data.SqlClient.SqlConnection(ConnectionString);

try

{

connection.Open();

Console.WriteLine("连接成功");

string sql = "insert into MoneyUsing(MoneyNumber,Money,MoneyUsing,MoneyDate,MoneyType)values(1,300,' 取款','',1) ";

System.Data.SqlClient. SqlCommand command = new System.Data.SqlClient.SqlCommand(sql, connection);

//command.ExecuteNonQuery();

int count = command.ExecuteNonQuery(); //影响的记录

Console.WriteLine(count.ToString());

}

catch (System.Data.SqlClient.SqlException e)

{

Console.WriteLine(e.ToString());

}

finally

{

connection.Close();

}

看看查询的,就是多列的问题 利用SQLdatareader来帮助我们读取,数据库查询的时候也是不是一下子全部拿出来的,它要使用游标去解决大量数据的出库问题 Cusor 先得到游标 数据库再借助游标来读取我们的数据ExecuteReader得到的还是游标,要是真的需要数据的时候,我们这个时候就利

用游标一条一条地搞了 没次读一次就需要调用一次read()的方法,所以这个时候就会返回一个bool类型的,为true为已读取,为false为假

再使用完了之后,游标也是要关闭的

//string ConnectionString = @"Server= 192.168.0.115 ; Database=myMoneyDB ;uid=sa,pwd=1 ";

string ConnectionString = @"Server= 192.168.0.115 ; Database=myMoneyDB ;Persist Security Info = false;Integrated Security = SSPI " ;

System.Data.SqlClient. SqlConnection connection = new System.Data.SqlClient.SqlConnection(ConnectionString);

try

{

connection.Open();

Console.WriteLine("连接成功");

string sql = "select * from MoneyUsing where MoneyType is not null" ;

//string sql = "insert into MoneyUsing(MoneyNumber,Money,MoneyUsing,MoneyDate,MoneyType)values(1,300,' 取款','',1) ";

System.Data.SqlClient. SqlCommand command = new System.Data.SqlClient.SqlCommand(sql, connection);

System.Data.SqlClient. SqlDataReader reader = command.ExecuteReader();

while(reader.Read())//为真继续

{

//利用游标的下划性,第一次判断就好了,游标开始下划到第一行

//Console.WriteLine(reader.GetInt32(0));

Console.WriteLine(reader[0].ToString() + "\\" + reader[1].ToString() + reader[2].ToString() + "\\" + reader[3].ToString() + "\\"

+ reader[4].ToString());

}

reader.Close();//关闭游标

Console.WriteLine("已关闭游标");

//command.ExecuteNonQuery();

//int count = command.ExecuteNonQuery();//影响的记录

//Console.WriteLine(count.ToString());

}

catch (System.Data.SqlClient.SqlException e)

{

Console.WriteLine(e.ToString());

}

finally

{

connection.Close();

}

Console.Read();

上午讲了三个对象,连接对象 负责与数据库建立连接、命令对象 封装 连接对象、参数对象、语句、读取游标代表的对象datareader对象代理 读取数据

ExecuteReader

ExecuteNonQuery增删改

下午还要 参数 事务

Page 63: Csharp

www.happy12.com 010-82387501

System.Data.SqlClient.SqlParameter sqlp = new System.Data.SqlClient.SqlParameter("@name",System.Data.SqlDbType.NVarChar,50);

System.Data.SqlClient.SqlTransaction tran = connection.BeginTransaction(); //建立连接,启动事务

command.Transaction = tran;

tran.Commit();//提交

tran.Rollback();//回滚

输入参数到SQL命令

利用string.Formart () 拼装sql命令(SQL注入)构造反常规的输入,但是仅仅是针对字符串 ‘ or 1=1 —— ‘‘转义了’ or 真 永远为真了 所以不

能这样写 还可以构造出很强悍的串了

如何解决呢? 写带参数的sql语句 where name=@name;

在iracke中使用:引导变量

事务 一个事务插入两个学生

Connrvtion.返回一个事务对象

Cmd受到那个事务的管理

不能重复添加参数,但是往后要重新搞新的值

登陆所涉及的问题

各种各样的数据访问技术

Cs客户端+服务器

Bs浏览器+服务器 就是为了减少浏览器,通用的客户端浏览模式,部署方便,就是浏览器的功能操作受到限制,很难做到CS那么漂亮。

Btn dialogresult OK完成对话框的设置

DialogResult result = form.ShowDialog();

if (result == System.Windows.Forms. DialogResult.OK)

{

cmd.ExecuteScalar(); 直接第一行第一列,object 要是没有的话,返回空值null

object obj = command.ExecuteScalar()

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php 32、 模式对话框 model对话框 showdialog(); 用户必须处理,不能忽略。 33、 非模式对话框 modeless对话框 show(); 34、 5个对象的使用 connnection cmd datareader sqlPramer 35、 离线数据访问 (为了针对 datareader的一条性与不便性) 二维表 System.Data针对关系数据库下得所有的关系数据库的数据结构 36、 Datatable 专门表示二维关系数据库表的类 datable是动态变化的 是一个新的数据结构 System.Data.DataTable table= new System.Data.DataTable();

System.Data.DataColumn nameColumn =new System.Data.DataColumn("Name", typeof(string)); Typeof实际上也是一个语法糖

System.Data.DataColumn idColumn = new System.Data.DataColumn( "Sid", System.Type.GetType("System.Int32"));

table.Columns.Add(idColumn);

table.Columns.Add(nameColumn);

nameColumn.Unique = true;

table.PrimaryKey = new System.Data.DataColumn[] { idColumn };

System.Data.DataRow r1 = table.NewRow();//必须通过表对象来获取行对象的

for (int i = 0; i < 10; i++)

{

System.Data.DataRow r = table.NewRow();

r[idColumn] = i +2 ;

r[nameColumn] = string.Format("Name{0}", i);

table.Rows.Add(r);

}

foreach (System.Data.DataRow dr in table.Rows)

{

// 每一行有多个列

foreach (System.Data.DataColumn col in table.Columns)

{

Console.Write("{0}\t", dr[col]);

}

Console.WriteLine();

}

Console.Read();

修改问题与冲突问题

Page 64: Csharp

www.happy12.com 010-82387501

对datarow详解

92、 判断是否修改 unchange状态设置 一般是add 在构建完毕之后可以设置为unchange

留下一个痕迹,然我们找到原来的数据在哪里

至少存了三遍数据,一般的变量只会记录最后的状态 // 在构建完毕之后,可以将行的状态设置为 UnChanged

table.AcceptChanges();

Console.Write("{0}\t", dr.RowState);

修改了 ID呢?更新的时候 就是要 update返回到数据库的时候必须要保存好我们原来的 ID 原来的值还是记着,新的值也是记录的,但是查询的时候还是最上级显示,原值(表,只能记录一开始的原值)、新值 便于我们去更新回数据库3 新值:直接读 // 修改一行数据

r1[1] = "Smith";

// 当行中的数据被修改之后,行的状态将会被改变

Console.WriteLine(r1.RowState);

// 其实,在 DataRow 中同时保存了原来的值

Console.WriteLine("当前的值:{0}", r1[1]);

旧值:ri[1,] Console.WriteLine( "原来的值还被保存:{0}", r1[1, System.Data.DataRowVersion.Original] )

一个准备赋值的值,没讲 先用datareader 列 reader.fieldcount 拿到列数int columnCount = reader.FieldCount;

建列 抓取列名 reader.getname(i) 取得列名 r eader.getfieldtype(is)取得类型 转行 while(reader.read()s) for (int i = 0; i < columnCount; i++)

{

DataColumn col= new DataColumn(reader.GetName(i), reader.GetFieldType(i) ); // 取得列名。取得列的数据类型

table.Columns.Add(col);

}

控制台的配置文件 App.config 规定命名,可以从特定的文件, 不参与编译的。修改的几率很高的话,还是比较适合这样的

从配置文件中读取 引用 添加 System.Configuration 就是专门记录我们的配置参数的

<configuration>

<connectionStrings>

<add name="demo" connectionString="server=.\sqlexpress;database=demo;integrated security=true; "/>

</connectionStrings>

</configuration>

程序调用:

string connectionString= System.Configuration. ConfigurationManager.ConnectionStrings["demo"].ConnectionString;

using (SqlConnection connection = new SqlConnection(connectionString))

{

我们可以动态的创建行与列,甚至是状态 拉扯到视图 对于 datable 的排序的问题 希望用更加简单的方式使用读取的数据 dataview 用这个对象 可以非常方便地查看数据 一个访问数据的方便机制实际的数据来源于 datatable,其实 dataview就是为了排序而存在的 类似数据库视图,但是不包含 Syste.Data.Dataview dv = new dataview (datatable) Dataview view1 = table.default; View.Sort=”sid desc”;; Froeach (dataRowview r in view ) { R[“sid”],R[1]; } 一般是拿其他的对象来抓取 table的数据再显示出来。 Dataset 数据集合 System.Data.Dataset dt = new dataset ();

Page 65: Csharp

www.happy12.com 010-82387501

Ds.tables.add(datatable); 甚至我们可以用 ds.relations来设定表与表的关系 Dataadapter 数据适配器 connection sql语句 System.Dat.sqlClient.Sqldataadapter adapter = new sqldataadapter (sql,connection); System.data.dataset ds = new dataset (); Adapter.Fill(ds,name起名); Ds.tables[0].acceptchange(); Foreach (system.data.datarowview r in ds.tavles[0].defaultview) { } Datatable的高级应用 类似 sql的 where Datarow dr = ds.tables[0].select(“sid=17”)[0];//只要一行 Dr[1]=”change name”; Console.WritleLine(dr.rowstate); //modify更新 更新到数据库 Update(modify) 、delete(deleted)、insert (add) 要是要完成这些操作的话 微软写了一个自动生成 command的 commandbuilde 创建 adapet就必须提供字符串与表的关键字 就是 primary要搞好 Sqlcommandbuilder builder = new sqlcommandbuilder (adapter); 要写 adapter.UpdateCommand = builder。GetUpdateCommand(); Adapter.deleteCommand=builder.Getdeletecommand(); Adapter.InsterCommand = builder.GetInsertCommand(); Adapter.update( ds,name); 与 datagridview连接 Datasource Datamember=“student” 然后再自己搞 强类型的 dataset 为了防止列名的出错,那么我们就定义一个属性来限制索引器 令到 table有一个属性 class student : datable 那就是可以在这个类里面搞了自己做我喜欢的数据类型,强类型的 dataset但是自己的工作量很多。

Page 66: Csharp

www.happy12.com 010-82387501

还要做什么呢?只要 new一个对象 然后就是不用了索引器了 <?xml version="1.0" encoding="utf-8" ?>

<configuration>

<configSections>

</configSections>

<connectionStrings>

<add name="TypedDataSetSample.Properties.Settings.demoConnectionString "

connectionString="Data Source=.\sqlexpress;Initial Catalog=demo;Integrated Security=True "

providerName="System.Data.SqlClient" />

</connectionStrings>

</configuration>

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php 93、 数据库数据适配器与 reader的问题 reader速度是最快的 adapter是一个什么? 就是内部操作变复杂了,会变慢 94、 用在规模不大的效果不错,用在 winfrom也是可以的。但是用在网站上,因为比较占用内存,所以基本不用 adapter ,小项目的网站 还是可以使用的,但是大型的网站还是不建议使用的(adapter只是针对小型的

95、 退出的使用 reader的时候,意味着编程量的增加 96、 与字节流等的联系,但是文件流是低级的,数据传输的是更加高级的,传输就变成字符 97、 DAAB applicationBlok 应用程序块 非正式的应用程序块 带实验性质的程序 数据访问方式,直接写一个方法。模式与实践项目组,就是微软就大家都遇到的问题,微软提供了一个官方的参考。最早的就是数据访问的模块。

98、 读代码的工具

99、 重载,就是方法名,但是有不同的参数,把一堆完成一类相同操作的方法聚合到一起。 100、 可变参数, params sqlparams[] 语法糖 int x,int y public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

那么 可以允许任意个数的参数 形参是 params int[] nums while (reader.Read())

{

Student student = new Student();

student.Sid = reader.GetInt32(0);

student.Name = reader.GetString(1);

// 每一条数据库中的记录将会转换为程序中的一个学生对象

list.Add(student);

}

Page 67: Csharp

www.happy12.com 010-82387501

}

// 这样,得到一个学生的集合

foreach (Student s in list)

{

Console.WriteLine(s.Name);

}

101、 要是传参为 null的话,ado.net会被认为忘记传递参数。 Ctrl+”- ” 回退鼠标 ctrl+”+” 方便读代码 if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );

102、 省内存 速度块 reader 结合 student 与 list 值对象。 Froeach (student student in lisr) 其实就是 DAAB的运用 // 这个存储过程有三个显式定义的参数

SqlParameter pName = new SqlParameter("@name", SqlDbType.NVarChar, 50);

SqlParameter pPhone = new SqlParameter("@phone", SqlDbType.NVarChar, 50);

SqlParameter pId = new SqlParameter("@member_id", SqlDbType.Int);

// 其实,还有一个隐式参数 return

// 名字是什么?无所谓!, 有所谓的是类型,必须是整数

SqlParameter pReturn = new SqlParameter("@returnValue", SqlDbType.Int);

// 参数的值

// 默认都是传入参数,传入参数必须赋值

pName.Value = "123456";

pPhone.Value = "987654321";

// 传出参数不必赋值,但是,必须说明参数的方向

pId.Direction = ParameterDirection.Output;

// 同样,return 参数也必须说明, 必须是 ReturnValue

pReturn.Direction = ParameterDirection.ReturnValue;

数据访问对象 data access object DAO 是专门针对一个对象的 通常跟表是有直接的关系的 MemberDAO MovieDAO 如何=判断自己写对了 就是调用方法就好 这种类库会包含很多数据访问对象,这些就是数据访问层,解决数据库的数据到 一般是 class libraly 数据访问层 类库项目 DAL 要引用好我们的接口 再写一个数据访问层的接口 也是一个类库的项目 里面写 interface 在接口里面针对会员的操作写好方法,设定好方法与参数 对应对个就是使用 ArryList 还要添加引用 claa 定义对象类 模型 值模型 MemberClass 也就是我们的 model DAO—Interface—Model 结合单元测试 再加上一个测试 class libraty 下午再写一个 SVN 跑测试 添加一个新建项 测试问题 第一个是 程序 第二个是 app.config [TestFixture]

public class MemberTest

{

// 测试方法

Page 68: Csharp

www.happy12.com 010-82387501

[Test]

public void CreateMemberTest()

{

const string name = "TestName";

const string phone = "12345678";

// 取得数据访问对象的引用

DataAccessLayerInterface. IMemberDAO dao

= new DataAcessLayer.MemberDAO();

// 创建成功的话,会得到一个会员的编号

int id = dao.CreateMember(name, phone);

ValueModel.Member member = dao.GetMemberById(id);

// 断言

Assert.AreEqual(name, member.Name);

Assert.AreEqual(phone, member.Phone);

}

}

就是写一个变态的 结合测试的东西 然后就是就是日志工具,log4net日志 开源社区 的使用 因为很 console很悲催

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php 103、 对象关系映射 ORMapping 把对象变成对象 会很容易陷入技术的细节里面失去方向。 人月神话,提出了 1 个星期 实际上是 9 个星期,远比你想得复杂。延期是很常见的。就是对问题的复杂度缺少了分析 《软件研发》 新的技术不断涌现,开发的模式还是在不断地改变,所以这个就需要我们做一个很好的计划,那么我们就要先考虑这个类要写什么?就是先定义一个接口就是先考虑功能再搞实现。

104、 那么这个时候就变成团队开发的问题,直接定义接口直接搞 别人可以写一个模拟的类 就是同名的假类,就是不是靠实现类,而是靠接口的抽象类来实现的,这个就是面向抽象编程。接口是我们的规格说明书,写实现的时候,还要写测试。

105、 用完成的测试的绿条来衡量我们的效率,还要针对特殊的情况。各种约束与长度。程序修改的时候,会不会影响到其他地方。测试的代

码追求简单。 106、 解决错在哪的技术?1、debug 调试 可以断点,但是不能再发布以外在用 2、test 测试 在程序中关键的地方输出信息,那么最后可以查看日志文件中的信息 程序可以一直工作,而且不依赖与高级调试器,测试的效率要比调试的高。

107、 那么如何解决输出的问题 就是配置文件+优先级的问题。如何配置的问题。定制属于我们的输入输出。 108、 为什么有项目的存在, Project—程序集 就是开发工作可能得到独立的程序集,在使用的时候拷贝一下就好,非常方便地使用费。管理开发很灵活,有独立性 一个解决方案会有很多项目。

109、 接口 log = 类 ;面向抽象的协作的问题。接口就是搞大型项目的。 110、 DAO数据访问对象,就是继承接口,实现方法 数据仓库 reposeradio 111、 今天的任务是继续完成,下面再讲一些知识 10、泛型 数据集的 3大接口 Emarable遍历 数数 Icount 一般是要对读取的数据 object 做一个 as的转型 叫做强类型的集合,有条件的,只能放某种类型数据的集合。本来就是那么几个基类,但是却要写大量的东西,所以就浓缩为泛型。 泛型是基于模板的。 就是挖了一个洞的 ArryList 类型爆炸 会创造出大量的数据类型 都提供一个专门的泛型模板。 System.Collections.Generic //非通用集合 Ststem.Collections.Generic.List<int> list = newList<int > ;//int 就限定了里面的类型; List.Add(1); 系统内部编写,运行时快,不用处理装箱等问题,减少功能损耗。 11、版本管理 每个人都有一个类吗?团队开发的时候 1、源代码共享 2、版本的问题,不是一次写完的,以前都是覆盖性的,以前的东西都被覆盖了。可以把以前的搞出来。就是跟踪版本的问题。3、协同性 帮你发现重复修改 警告报错 是软件开发的基本工具 软件其实有很多的。但是作用都是一样的。 微软 VSS 、 TFS(2008)但是还要做一个 那么全部都要买一圈 开源的 CVS(Linux) SVN 升级版 免费要求不高 可以时候全世界的协同开发 SVN的功能算是比较全的 GIT svn的问题就是比较慢 可以离线使用 就是每一份的端都存一个 与.net的不全 很难配置 需要敲点命令行 一个是服务器 (装一次 VisualSVN 适合几十个人开发就好),N个是客户端

Page 69: Csharp

www.happy12.com 010-82387501

还能做存储与分支

客户端

他是 VS的一个插件 VS 工具 选线 版本管理工具 插件 选择插件

Page 70: Csharp

www.happy12.com 010-82387501

仓库与本地 放进去叫做 chenk in (迁入) commit ; 取出来就做 update (合并) 存入自己的仓库

数据库的字符串 还有要把数据库 脚本都拉到里面 在配置文件不好吗? 先空着 在加一个自己的配置文件 XML 里面都是必须要 configuration userconfig <Connectionstrings> useer 的是自己的 subversive

ignore就可以自己自用的了 再在 App里面就可以写 configsource =”user.config” 自己使用的是 ignore 别人看见的是黄色的。 <configuration> </configuration>

Page 71: Csharp

www.happy12.com 010-82387501

抓取 URL +号

Page 72: Csharp

www.happy12.com 010-82387501

右击项目 会弹出很多选项 包含很多的东西 Show changes () Resert to this version 单独的项目 Revert 要全面的理解 取下来一份 双开 文件 打开 open from

Page 73: Csharp

www.happy12.com 010-82387501

不要动.svn 但是要排除控制得话,还是可以的。 同步 (先 updates再修改再解决冲突) 同行 项目方案 update to lastes version 不要先提交 先 upadte

Page 74: Csharp

www.happy12.com 010-82387501

那么留哪一行呢? 留自己的 先删除 在右击 resolve 解决冲突 resolve comflit 面对隐式的冲突呢? 添加类 (先 update再编辑 再重新加载 再解决冲突 再 check in)

保存之后变成 红方块,但是服务器还没改

其实改得是项目文件 croprojs,其实仅仅是修改文本的文件,为了返回 还是要把文本文件中多余的删除掉

会变灰色 但是要解决解决冲突的操作 编辑项目的文件 Solution解决方案 就是新建一个类库的时候 另外一个人也需要 先 resert 再 update 冲突的排除 可以跟谷歌的联网存 Lock的问题 unlock

Page 75: Csharp

www.happy12.com 010-82387501

Nunit单元测试的扩展 测试驱动的例子 针对银行的账号进行测试 即是针对所有的操作与属性进行 写注释 ///可以直接抽取变成帮助文档 标准化的注释 ///<sumarry> ///转账 ///</summary> ///<paiam> 使用测试的快速方法 插件结构的允许扩展的 如何添加? 设置外部工具

Page 76: Csharp

www.happy12.com 010-82387501

/// <summary>

/// 取款

/// </summary>

/// <param name="amount">取款金额</param>

这样是可以利用外部的工具对数据进行抽取的

/// <summary>

/// 转账

/// </summary>

/// <param name="destination">目标账号</param>

/// <param name="amount">转账金额</param>

[Eppecction] Try catch在抛出异常的时候 检查原子性 就是调用查询的事务的问题的时候使用 还有的就是方法的顺序的问题 [ignore] 代码还没写 出现黄条 问号 没有完成 如何变懒 但是又不能应用到构造函数 set up 命令 初始化 在测试方法执行之前执行一次 log4net只是初始化一次就好 可以写一个日志器 很像是构造函数啊 还有一个方法叫做 tear down 再每一个测试执行了之后 进行扫尾的工作 很像析构 [test] [repeat(1000)] 接口 与抽象类 Interface 限定继承接口或者是对象的动作,有方法却没有实现, 可以包含方法 属性 事件 索引器 接口所有成员隐式具有 public 可以继承多个接口 但是只能继承一个基类 方便对人协同开发, 什么是泛型接口 要是用泛型的话 即是传进去 就对应好了类型了 不用再 as一次 Class:interface

Interface t = new class (); 接口与基类的选择性透过的方法,主要是为了规范性与扩展。 Virtual就是虚,一切以后面为主 // 在每一个测试方法执行之前,执行一次,基本上是实例初始化的工作,但是这样也是可以优化程序一开始的速度的,减少没必要的内存开销

[SetUp]

public void Setup()

{

log4net.ILog logger

= log4net. LogManager.GetLogger(typeof(AccountTest));

logger.Info( "Setup......");

this.source = new Account();

this.source.Deposit(200.00F);

this.destination = new Account();

this.destination.Deposit(150.00F);

}

// 在每一个测试执行之后,进行扫尾工作

[TearDown]

public void TearDown()

{

log4net.ILog logger

= log4net.LogManager.GetLogger(typeof(AccountTest));

logger.Info("TearDown......");

}

[Test]

// 准备些一个测试,但是,还没有想好

[Ignore("Decide how to implement transaction management" )]

Page 77: Csharp

www.happy12.com 010-82387501

public void TransferWithInsufficientFundsAtomicity()

{

Account source = new Account();

source.Deposit(200.00F);

Account destination = new Account();

destination.Deposit(150.00F);

try

{

// 因为在余额不足的情况下,会抛出异常

source.TransferFunds(destination, 300.00F);

}

catch (InsufficientFundsException expected)

{

}

Assert.AreEqual(200.00F, source.Balance);

Assert.AreEqual(150.00F, destination.Balance);

}

接口就是从上往下的 虚方法是从下往上的 还能够作为阻隔

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php 1、WEB 网络 TCPIP 目标是 不至于瘫痪 军方开放民用 那个时候有 email ftp传文件 欧核中心 诌欣 为了让人们享受互联网的便利 发明了 http 超级文本传输协议。Tp是协议 那么文章要怎么样传输 写出我们的文章呢? Ht 写的工具多,即是写歌网站可以在很多文本编辑器上写脚本 HTML拿标记来找内容的 用记事本来写可以很清晰地看到,简单简单 , 记得另存为所有 在添加 .html 浏览器就是一个专门用来读网页的软件 Web服务器 也有一些软件提供访问提供服务 IIS7.0 阿帕奇 必须把网页放在 web服务器 允许多个客户端发送命令访问网页 然后那个美国人成立了第一家互联网公司 网景 开发浏览器 利润很大 互联网的神话 高科技公司的竞争太猛了 比尔开始干活了 都要转向互联网 IE出来了 捆绑操作系统 火狐就是网景浏览器的源代码 <html> <head>--网页的说明信息 <title>标题</title> </head> <body>--实际的文本内容 <h1></h1> 1到 9 <p></p>段落 <h2>魔方</h2> <p><b>文章:</b><a herf=’网址’ target='_blank'>模仿与魔方</a></p> -- <a>是提示 ,一般使用在链接上,herf是连接,target='_blank'窗口打开的模式 </body> </html> IIS程序 作为一个服务运行在我们的系统上

Page 78: Csharp

www.happy12.com 010-82387501

wwwservice IIS管理器 怎么样提供服务? 37、 浏览器(客户端)-------------------------------------------------————————————————web服务器 (网页) 38、 找到 web服务器 IP地址 192.168.0.X就是私有地址,排除在互联网 0到 255,但是在公网的时候是单独确定的 端口号 0到 65535 一个网络程序可以用一个到几个端口 默认是 80 方便用户的访问 ftp21 、snitp25 、popus110 去登记注册端口 相当于注册 但是记端口很累啊, 后来出了专门负责管理地址的人 然后域名 Domain就来了 允许你给你的地址起个名字 出现了一个公司 域名服务器 http:// IP地址:端口 就是借助 IP地址与域名来访问网址的 然后就是 启动 IIS 但是 web服务器不想用户访问其他的文件,那么依靠文件系统来管理 那么这个时候针对网站提供了一个虚拟的文件系统 网站的根目录 那么实际上是什么的文件目录

IIS编辑网站 物理路径 physicsPath 虚拟路径 映射 IIS默认文档 网页

Page 79: Csharp

www.happy12.com 010-82387501

添加虚拟路径 添加虚拟用户的映射 http://192.168.0.115/myWeb虚拟名称/index.html

http://apps.hi.baidu.com/share/detail/22696091 IIS设置参考 启动父路径

Page 80: Csharp

www.happy12.com 010-82387501

配置物理物理路径

Page 81: Csharp

www.happy12.com 010-82387501

让同一局域网里面的人也能访问自己的电脑上的网站。

1、依次选择:开始---所有程序---管理工具---高级安全 Windows 防火墙。

(有的电脑在所有程序里面可能没有”管理工具”,这时可以开始----在空白处鼠标右击---属性---自定义---找到

系统管理工具,选择“在所有程序菜单上显示”,这样在所有程序里面就有管理工具了

2、在高级安全 Windows 防火墙的左边栏,选择“入站规则”。

3、在右边栏选择"新建规则“。

Page 82: Csharp

www.happy12.com 010-82387501

4、在弹出的窗口依次选择:选中端口---下一步---选中 TCP以及特定本地端口,填入要开放的端口号(这里

填入 80,当让也可以选择开放所有端口)---下一步---选中允许连接---下一步---选中所有选项---下一步---填入名称

(这里填入 IIS)---完成。完成这些之后,跟你处在同一个局域网里面的人就能访问到你电脑上的网站了,到此,

在Win7上的 ISS就和平时在 XP里面一样了。

HTTP 错误 403.14 - Forbidden

Web 服务器被配置为不列出此目录的内容。

其实解决方法错误提示页面就有

· 如果不希望启用目录浏览,请确保配置了默认文档并且该文件存在。

· 使用 IIS 管理器启用目录浏览。

112、 打开 IIS 管理器。

113、 在“功能”视图中,双击“目录浏览”。

114、 在“目录浏览”页上,在“操作”窗格中单击“启用”。

· 确认站点或应用程序配置文件中的 configuration/system.webServer/directoryBrowse@enabled 特性被设置为 True。

点击启用即可。

IIS7.5的真的挺不错的,能够将解决问题的方法都提示出来,这比 xp下的 iis5.1和 windows server 2003的 iis6都要好得

多咯

实际上为了安全大家不必要开启目录浏览,只要设置好默认文档就可以了

在右边的操作列 点击打开功能

http://articles.e-works.net.cn/661/article32655.htm 玩转 IIS 配置搞笑的 web服务器 xhtml 那么是什么呢?浏览器的容错率很大, 后来 XML出现了,出现了新的规范,提出超级严格的要求。DTD的 规定 <!DOCTYPE html> 标记小写 小写的属性必须用“” 样式表 stylesheet 页面的逻辑结构与页面的现实的效果 因为样式标记与结构标记混编,所以W3C组织(核心后台是麻神理工学院) 万维网论坛 出了标准 样式表 stylesheet 分类出来 /**/注释 <b>XXX</b> 1、隔离标记 <span style=”font-weight:bold;font-size:20px;”></sapn>内容片断 抽取出来 专门的隔离 2、 <head> <style type=”text/css”> .name { font-weight:bold; ;font-size:20px;

} </style>

</head> <span class=”name”></sapn>

Page 83: Csharp

www.happy12.com 010-82387501

要是其他页面也需要用呢? Css样式表 <head> <link rel=”Stylesheet” herf=”path” type=”text/css”> 这个里也是写类的 <link rel=”Stylesheet” herf=”” type=””> rsth </head> 样式表例子 脚本 专门就是实现动态的文本文字 那个就是脚本 现在就是 javascript与 JSscrtpt 可以做很多很酷的操作 网页 Html CSS Javascript 那么我们现在的是动态页面 是动态绑定数据的 那么我们 Active serve page ASP 活动服务器页面 后来出现的 Java server page 慢 Eelicpse超级慢 Asp.net 利用.net技术 效率最高 其实在 VS的强大工具的支持 但是最重要的是钱的 但是本身还是因为 PHP 很像 ASP 就是突破 ASP的限制 却是跑在 linux服务器上 免费的 apache Lamp mySQL <script typr=”text/javascript”> Window.setInterval ( Function() { Document.getElementBuId(“clock”).innerHTML = new Date().to } ) </script> 如何写动态网页呢?其实就是用程序来生成字符,关连流的技术 字节流字符流 那么实际上生成网页的代码是什么呢? 实际上是服务器把文件 变成流 再从文件出去文字 网页实际上就是一串字符 网页也是对象的集合 流的复习, 那么实际上是如何输出 HTML的呢? 第一步 生成一对标记 第二步 string format替换时间 其实动态网站 就是在服务器拼串 实际上很多公司都是这样开发的 把一个标记看成一个基本单位,把网页分成多个 在实际开发,美工基本是写好网页的布局的,不变的内容称为 literal内容 把网页分成一块一块地进行开发 挖出基本单位作为开发 从面相对象的角度 去理解网页开发 可以看成三部分 每一个部分看成 3个对象 一个网页对象 里面有 3个小对象 ()把复杂的问题拆成小得问题 直到方便我们解决问题为止 从一个基类派生出一些有共同特点的类 Control 不变的类 literal:Control 可变的类 HeadLine 共同点 能输入到字符流里面 override Render 再利用小对象组装成网页对象 可以做成复杂的高级页面 那么对于小的对象我们还能够再拆分小一点 就是让我们把网页的问题变成对象的问题 Page类 ( 集合泛型集合 Constrol 确保了准确性 list<constrol> Controls add() Render(){foreach 遍历 controls} )然后输出到浏览器 空 web项目 一般处理城西 ashx TextWriter writer = context.Response.Output; Page.Render(writer); 引申到图片类 namespace ObjectHtmlSample

{

// 定义一下共同的抽象

public class Control

{

// 定义生成字符的基本方法

public virtual void Render(System.IO.TextWriter writer)

{

}

}

// 更加高级的页面对象

public class Page

: Control

{

// 对于页面来说,并不需要关心非常细节的标记

// 到页面级别,只需要关心组成页面的 Control 对象

private System.Collections.Generic. List<Control> controls;

public Page()

{

this.controls = new List<Control>();

}

Page 84: Csharp

www.happy12.com 010-82387501

// 将控件加入到页面中

public void AddControl(Control control)

{

this.controls.Add(control);

}

// 最终的目的还是生成 Html

public override void Render(System.IO.TextWriter writer)

{

foreach (Control control in this.controls)

{

control.Render(writer);

}

}

}

// 两个派生类

// 表示固定不变的字符内容

public class Literal

: Control

{

private string text;

// 属性

public string Text

{

set { this.text = value; }

get { return this.text; }

}

//

public override void Render(System.IO.TextWriter writer)

{

writer.Write(this.text);

}

}

// 一个表示 HeadLine

public class HeadLine

: Control

{

// 标记中间的内容

private string text;

public string Text

{

set { this.text = value; }

get { return this.text; }

}

public override void Render(System.IO.TextWriter writer)

{

writer.Write("<h1>");//写入到内存的字符流中

writer.Write(this.text);

writer.Write("</h1>");

}

}

public class Image : Control

{

private string text;

public string Text

{

Page 85: Csharp

www.happy12.com 010-82387501

get { return text; }

set { text = value; }

}

public override void Render(System.IO.TextWriter writer)

{

writer.Write("<img src=");

writer.Write(this.text);

writer.Write("/>");

}

}

}

namespace PageSample

{

/// <summary>

/// Summary description for Handler1

/// </summary>

public class Handler1 : IHttpHandler

{

public void ProcessRequest(HttpContext context)

{

Literal l1 = new Literal();

l1.Text = "<html><body>";

HeadLine h = new HeadLine();

h.Text = System. DateTime.Now.ToShortTimeString();

Literal l2 = new Literal();

l2.Text = "</body></html>";

Image img = new Image();

img.Text = "\"C:\\Users\\Administrator\\Desktop\\架构师大会.jpg\"";

Page page = new Page();

page.AddControl(l1);

page.AddControl(h);

page.AddControl(l2);

page.AddControl(img);

// 在网站应用程序中,可以得到输出到浏览器的字符流

System.IO.TextWriter writer = context.Response.Output;

page.Render(writer); //把control写入到writer里面

}

public bool IsReusable

{

get

{

return false;

}

}

}

}

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php 115、 微软视图用面向对象,令到一个页面 page变成一个对象 现在就生成 html标记的问题了 不要过分注重控件,要关注我们的底层的 HTML标记语言 2、小心标记的嵌套 标记是有层次的

Page 86: Csharp

www.happy12.com 010-82387501

<img herf = “ X” /> 116、 from 填写的单位就是表单 与 div 这样可以分块 117、 新建网页

可以用来检查页面的规范性

118、 from实际上是看不见的,是用来提醒用户的 119、 flddler2

可以截获浏览器回发服务器的信息 Localhost 本机 对应一个特殊的 IP 127.0.0.1 为了好好使用,所以讲落下 localhost改为自己的电脑名称 一定是 IE8 IE9

Page 87: Csharp

www.happy12.com 010-82387501

查看原始内容 RAW

Post 服务器主机 读取解析标准 Accept接收 application/xhtml+xml */* MIME文本内容 就是类/细类 Referer 这次的请求的上次请求 Accept language en-us接受 的语言 语言/国家 zh-cn User-Agent:其实就是浏览器 mazilla网景 读冒充自己的网景的浏览器 (compatile : MSIE NT 6.1;Trident/5.0核心) 其实很多就是 IE的内核没本质的区别 Accept_Encoding 接受的编码问题 浏览器我自己认识这两种压缩方式,服务器你可以返回这些 这样就可以比较快了。 HOST 你要访问的主机 Connection : keep-Alive 在 1.1的时候形成的,在发请求的时候在完成第一个任务的时候不断开连接,方便继续的后继的内容要做 Cookie 我们在服务器编程的时候我们也可以得到 要回发就必须有 name post与®?get的Ì?方¤?式º?

一个请求:请求头 请求体 (请求头 什么方式发 name:content 空行(这样就不会影响我们的地址) 请求体 参数 ) 内容多的话,建议用 post的方式 Get是跟在地址后面 Post就用空行隔开 有请求头与请求体 有时间就总结一下了

Page 88: Csharp

www.happy12.com 010-82387501

39、 最低级:隔离标记 <span style=”font-weight:bold;font-size:20px;”></sapn>内容片断 抽取出来 专门的隔离 40、 在网页的头部写 css,必须设定 class或者是系统的 body 这些大得嵌套标签 <style type=”text/css”> .name { font-weight:bold; ;font-size:20px;

} </style>

<span class=”name”></sapn> <h1 class=”name”></h1> 41、 外部 CSS样式表 .css /* DEFAULTS

----------------------------------------------------------*/

body 大的嵌套标签

{

background: #b6b7bc;

font-size: .80em;

font-family: "Helvetica Neue", "Lucida Grande", "Segoe UI", Arial, Helvetica, Verdana, sans-serif;

margin: 0px;

padding: 0px;

color: #696969;

}

a:link, a:visited

{

color: #034af3;

}

.main class=”main”

{

padding: 0px 12px;

margin: 12px 8px 8px 8px;

min-height: 420px;

}

div.menu ???要查一查

{

padding: 4px 0px 4px 8px;

}

因为本身是做后台、玩数据绑定的,界面UI的还是要花点心思的呢

Fildder2 需要用到电脑名 最好是 IE9 ipv4.fiddler 替代主机名字或 localhost

__VIEWSTATE=%2FwEPDwUKLTIwNjAyODU4M2RkK06xm6X9KR9Chc0Lp9eaHram%2B0DtL7DM5dsm9i%2BpQEU%3D&username=%E8%AF

%B7%E6%82%A8%E8%BE%93%E5%85%A5&check=on&userpsw=123456&radiongroup1=on

Text username %3D&username=111

Pswtext pwd A5&check=on&userpsw=11111111&radiongroup1=on

Check 没有选的时候 A5&userpsw=123456&radiongroup1=on

Radion 选了一个,但是只是返回组的 on&userpsw=123456&radiongroup1=on&radiongroup2=on

到底我们选的是哪一个呢?我们可以配置 value

A5&check=on&userpsw=123456&radiongroup1=2&radiongroup2=4

Title是 on提示

<label for="radio1">one</label><input type="radio" id="radio1" title="title1"

就是对应绑定了空间的 ID 选了 label也是选了 radio1

小周姐姐面试心得

电子商务 第一眼的定位 哪方面的问题

所有的问题 就看书 所有的东西都问到 厚厚的题 做过什么项目 心得体会 未来有什么计划 问题解决不了 的时候如何解决 简历要写详细一点 基本上是面

试 10家 全英答题 职位要定位好 调职位的问题 对了 我是为了 CTO 刚去 好多不会做 不需要心虚 我的优势是什么 先挑点不是太好的练练手

MVC2 MVC3 Razor 还有一般的 aspx引擎生成页面

新建空的 MVC项目

Page 89: Csharp

www.happy12.com 010-82387501

Model View control 即是把复杂的程序分开来写 因为不便于修改与新增功能

View 视图 看的地方 显示一个结果 不需要管用户的输入到底干嘛 只负责接受用户的输出与按键

Control 处理器 只管接受用户的操作 鼠标啊 按键啊 根据你的操作 决定修改的内容 (用户所有的操作)→ Model

Model 模型 即是在内存中的数据结构,与显示没任何关系 修改完毕 独立抽象的数据结构

View显示

内存处理显示 3大结构完全分开 这个就是设计模式 而且可以套用 N次

1、第一步新建 Controler

复选框 自动控制器的增删除改查得方法

2、短的直接拼

//

// GET: /Home/

//在MVC中每一个处理就是一个Action

//下面就是一个典型的方法

//处理完成后返回用户处理的结果,通常是Html页面

public string Index()

{

string Html = "<html><body><h1>Hello</h1></body></html>" ;

return Html;

}

然后在页面就是 hellow了

http://localhost:1162/home/index 即是可以直接拼 其实 home是 controller 而 index是 homeController中的 Action

访问 IP:端口/Controlname /ActionName

Page 90: Csharp

www.happy12.com 010-82387501

3、利用视图

这个时候我们的controler也做点改变

public ActionResult Index()

{

//return this.View("Index");//1、默认找与自己同名的View

return this.View("Other");//2、找另外别名的view

//3、设置默认页面 Global.asax public static void RegisterRoutes(RouteCollection routes) new { controller = "Home", action = "Index", id

= UrlParameter.Optional } // 参数默认值

}

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">

<html xmlns="http://www.w3.org/1999/xhtml " >

<head runat="server">

<title>Other</title>

</head>

<body>

<div>

<h1>你好吗?</h1>

</div>

</body>

</html>

像静态网页但是却是不是 是 aspx MVC3还 Rozar的页面生成文件,更加简便

Page 91: Csharp

www.happy12.com 010-82387501

4、引入Model

即是一般时候修改某个值

那么我们就需要建立一个对象生成 进行修改 <head runat=”server”><title></title></head> 一般是生成 L 然后服务器生成对应部分的代码

直接创建一个model其实就是一个类,类名一般式 只管从model的得到数据 一般的命名规则是:

namespace MovieShopWebMVC.Models

{

public class TimeModel

{

private DateTime datetime;

public DateTime Datetime

{

get { return datetime; }

set { datetime = value; }

}

}

}

然后就是通过 controler把model传到 view

public ActionResult Time()

{

//model是数据传递的对象 那个数据对象就是model

DateTime datetime = DateTime.Now;

Models.TimeModel model = new Models.TimeModel() { Datetime = datetime }; //语法糖

//将model传递给视图

return this.View("Time2",model);//看是不是串,是字符串则是视图 不是则是模型 (view,model)

}

(1),没有确认是强类型的话,要 as

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

强类型的话;

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MovieShopWebMVC.Models.MemberModel>" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">

<html xmlns="http://www.w3.org/1999/xhtml " >

<head runat="server">

<title>Time</title>

</head>

<body>

<div>

<%--不知道你传什么,所以this.Model是object--%>

<%=(this.Model as MovieShopWebMVC.Models.TimeModel).Datetime.%>>

</div>

</body>

</html>

(2)

先按 F6生成,就可以创建强类型

Page 92: Csharp

www.happy12.com 010-82387501

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MovieShopWebMVC.Models.TimeModel>" %> 它就知道你的model的类型了 不用as了

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<%=this.Model.Datetime %>强类型下

4、view反问查询 Controller的 action,然后再根据具体情况执行返回的操作与视图

<body>

<div>

<h1>你好</h1>

<a href="/Member 对应的控制器/Index对应的action">转到会员管理</a>

</div>

</body>

//index是默认的action名称

public ActionResult Index()

{

return this.View("Index");

}

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">

<html xmlns="http://www.w3.org/1999/xhtml " >

<head runat="server">

<title>Index</title>

</head>

<body>

<div>

<%--画个注册连接--%>

<h1>会员管理</h1>

<a href="/Member/CreateMember">增加新会员</a><%--<%--增加新会员的action, Member控制器 action名CreateMember%>--%>

</div>

</body>

</html>

public ActionResult CreateMember()

{

Page 93: Csharp

www.happy12.com 010-82387501

return this.View("CreateMember");

}

5、、从 view抓取数据

<head runat="server">

<title>CreateMember</title>

</head>

<body>

<div>

<h1>添加新会员</h1>

<form method="post" action="/member/PostCreateMember"> <%--回发到控制器,member控制器 找里面的action PostCreateMember -- %>

<div>

<label for="username"><%--也是控件的ID --%>

用户名:</label>

<input type="text" id="username" name="username1" />

</div>

<div>

<label for="telephone">

电话:</label>

<input type="text" id="telephone" name="telephone1" />

</div>

<div>

<input type="submit" value="注册" />

</div>

</form>

</div>

</body>

</html>

//接受视图的数据,这个是CreateMember表格回发的action

public ActionResult PostCreateMember()

{

//return this.View();

//1、最基本的方式 所有的参数在服务器上都被表示成为一个请求对象

// 摘要:

// HttpRequestBase用作一些类的基类,这些类使 ASP.NET 可以读取客户端在 Web 请求过程中发送的 HTTP 值。

System.Web.HttpRequestBase request = this.Request;

//表单的参数表示为这个对象的一组属性

string username = request.Form["username"]; //控件的ID

string telephone = request.Form[ "telephone"];

//保存到数据库,调用一个方法而已

Models.MemberModel member = new Models.MemberModel();

member.Username = username;

member.Telephone = telephone;

return this.View("finishView",member);

}

<form method="post" action= "/member/PostCreateMember" ><%--回发到控制器,member控制器 找里面的action PostCreateMember --%>回发数据

<input type="text" id="username" name="usernameText" />

上面是 view的准备

下面是控制器的问题了

1、最基本的方式 所有的参数在服务器上都被表示成为一个请求对象

System.Web.HttpRequestBase request = this.Request;

2、表单的参数表示为这个对象的一组属性,我们可以利用我们的索引器来对应抓取我们的数据,但是从请求抓取的都是字符

string username = request.Form["username"];

string telephone = request.Form[ "telephone"];

view要足够的笨 MVC的核心思想 就是分成 3部分 简单意味着好写。ASP维护起来想死。

Page 94: Csharp

www.happy12.com 010-82387501

仅仅是从传入的model搞到里面

请求的目标全部都是访问 controller的

要是结合业务逻辑呢?那么复杂度就足以让你疯狂。

新的写法 即是关于回发控制器的都可以利用 Actionlink与 Html.BeginFrom(“A”,”C”,FromMethd)

1、不同的控制器表示连接 (实际是发送到controller中Action)

<a href="/member">会员管理</a>

<%= Html.ActionLink("LinkName","Action", "Controllers") %> HA LAC

<%=Html.ActionLink(“LinkName”,”Action”,”Controllers”)%>

2、相同的控制器

<a href="/member/createmember">增加新会员</a>

<!-- 同一个 Controller 中的 Action 可以更加容易一些 -->

<%= Html.ActionLink("LinkName", "ActionName") %> LA

<%=Html.ActionLink(“LimkName”,”Action”,”Controller”)%>

11、 view表示 Model中的值

<%=(this.Model as MovieShopWebMVC.Models. TimeModel).Datetime.%>在弱类型下

<%= this.Model.Time %>在强类型下

<%= Html.DisplayFor( m=>m.Time) %>

12、 form的回发

<form method="post" action="/member/postcreatemember">

<form method=”post”, action=”/Member/postcreatemember”>

<\form>

<% using (Html.BeginForm("PostCreateMember", "Member", FormMethod.Post)) HB ACfP

{ %>

<% } %>

<% using (Html.BeginForm("ActionName", "ControllersName", FormMethod.Post))

{%>

<% using(Html.BeginForm(“Action”,”Controller”,FormMethod.Post)) { %>

<%}%>

第二种写法 , <%=HTML.ActionLink> 输入框 form连接

动态对象,指向任何的属性 new {}

<% = HTML.DisplayFor(m=>Time) %> 在强类里面

FTP同步工具

Tools ftp

论坛地址: http://www.sisheng.net.cn/forum/forum.php aspx其实就是一个模板 JQ网页脚本验证

(System.Drawing.Brushes.White)不一定直接new通过别人给我们创建对象,这个就是工厂

一般是静态的

Page 95: Csharp

www.happy12.com 010-82387501

重定向的 就是访问了A A给浏览器 让浏览器访问B Action,再访问B 解决身份所属的问题 确实到底是谁在操作,谁负责的问题

<%=Html.LabelFor(RequestMember => RequestMember.username)%>

[System.ComponentModel.DisplayName("电话号码")]//lable显示文字

[System.ComponentModel.DataAnnotations. RegularExpression("\\d{6}",ErrorMessage="请您输入6位电话号码")] //正则控制格式

[System.ComponentModel.DataAnnotations. Required(ErrorMessage="电话号码格式错误!")] //需要输入

public string telephone { set;get;}

软件工程师出身 3年之后 成为什么样的人 项目经理?技术总监?人士经理? 收入是多少? 还是在此追逐我们的时光 微软技术讲师 业务? 管理? 稍微

一个讲师还是很不错的 1年在1W 我的目标很蛋定 看来不能听完就完事 机会很多主要是看着自己能否抓住机遇。

高级测试 白盒测试 软件就是 是看程序的哪个部分慢 最喜欢找bug 喜欢崩溃的东西

低级测试 就是核实值

高级测试 就是性能测试

解决问题是很嗨的 很开心的

从银行众多人拿钱 要服务大量的用户 如何区分我们的客户呢?

票据!!!!而且都是不同。那么我们的cookie来了 识别我们的用户

但是识别也是会有错的。有的是简单的票据 有些要求是复杂严密的

又涉及了我们的加密的技术了。

低 明文显示

高 卡号 查询你的信息 真实的信息是放在银行的 敏感的信息统一保存

回到我们的web开发 服务器回发的

第一次访问

以前访问过没有? 希望这样可以自动完成。这个技术的核心是cookie

如何解决个性化的技术

原理:请求 —>回应中附加特殊的信息(非网页信息,其实就是字符串key value)浏览器自动存储

下次访问 —>把请求与附加的内容也发到服务器

防盗链 根据附加的信息 让用户有区分

1、 cookie session是依赖于 cookie的

Page 96: Csharp

www.happy12.com 010-82387501

Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session跟踪而储存在用户本地终端上的数据(通常经过加密)。定义于 RFC2109(已废

弃),最新取代的规范是 RFC2965。Cookie最早是网景公司的前雇员 Lou Montulli在 1993年 3月的发明。

使用 cookie实现单点登录

[1]

Cookie是由服务器端生成,发送给 User-Agent(一般是浏览器),浏览器会将 Cookie的 key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该

Cookie给服务器(前提是浏览器设置为启用 cookie)。Cookie名称和值可以由服务器端开发自己定义,对于 JSP而言也可以直接写入 jsessionid,这样服务器可以知

道该用户是否合法用户以及是否需要重新登录等。

c#中的 cookie编程

[2]

服务器可以利用 Cookies包含信息的任意性来筛选并经常性维护这些信息,以判断在 HTTP传输中的状态。Cookies最典型的应用是判定注册用户是否已经登录网站,

用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续,这些都是 Cookies的功用。另一个重要应用场合是“购物车”之类处理。用户可能会

在一段时间内在同一家网站的不同页面中选择不同的商品,这些信息都会写入 Cookies,以便在最后付款时提取信息。

使用和禁用 Cookie

用户可以改变浏览器的设置,以使用或者禁用 Cookies。

微软 Internet Explorer

工具 > Internet选项 > 隐私页

调节滑块或者点击“高级”,进行设置.

Mozilla Firefox

工具 > 选项 > 隐私

(注: 在 Linux版本中,是如下操作:编辑 > 首选项 > 隐私 , 而 Mac则是:Firefox > 属性 > 隐私)

查看源网页

设置 Cookies选项

设定阻止/允许的各个域内 Cookie 查看 Cookies管理窗口,检查现存 Cookie信息,选择删除或者阻止它们

2、 前台 – 浏览器展现 先利用客户端的输入,可以大大地减少无效的联网连接,经过基本的数据的处理

3、 后台 – 服务器处理 是接受请求 有可能是 hacker自己编写的 content 华硕刷票系统 fiddler可以模拟网页的请求 get

4、 这两个验证都是需要做的,

生命周期

Session的使用 1级字典 2级字典

IE9 F12 验证 网络 捕获

为什么要那么长就是不要唯一是一个很随机的一个,一位别人拿这个号就可以模拟你的身份了。专门有一个类负责生成那个号,叫做 sessionID

要是服务器知道你已经有了,那么他还是不会再你开一个,在你关闭浏览器之前都不会消失。

Page 97: Csharp

www.happy12.com 010-82387501 那么我们如何处理在浏览器的过期时间呢?统一规定,存储在浏览器之中,随浏览器的关闭而死亡。

那么什么才是新的会话呢? 一次新开浏览器就是一次的 session

那么 session在服务器怎么呢?

Session 直接翻译成中文比较困难,一般都译成时域。在计算机专业术语中,Session 是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注

销退出系统之间所经过的时间以及如果需要的话,可能还有一定的操作空间。

具体到Web中的 Session指的就是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。因此从上述的定

义中我们可以看到,Session实际上是一个特定的时间概念。

需要注意的是,一个 Session的概念需要包括特定的客户端,特定的服务器端以及不中断的操作时间。A用户和 C服务器建立连接时所处的 Session同 B用户和 C

服务器建立连接时所处的 Session是两个不同的 Session。

论坛地址: http://www.sisheng.net.cn/forum/forum.php 1、view要笨(涉及 contraller 绑定 验证) model要重(取参绑定,错误信息,验证) controller要尽量简单 (验证model不应该再出现绑定的问题)

Request controller.Action—> model view绑定—> view 回发 post model comtroller —> controller model view

自己定义的正则表达 添加项目引用会更新 DLL

[Validation.Email(erro =””)] 贴标签

数据类型的标签

Class validateDe: :Ssytrem.dataCompoent

{ 正则表达式

//构造函数 parten

}

http://msdn.microsoft.com/zh-cn/library/ms187342.aspx @@ 与 soap

脚本注入 标记语言脚本等等 直接输出就会脚本注入 一定不要直接把用户的内容直接输出 看成是一个个的字符符号

< 怎么显示呢? &lt; 那么就是纯文本 不允许执行

防止脚本的注入

<hr/>

<%=html.displayfor()%>

Httpruntime 页面标签

标签 false

但是还是会编码的

改值

但是<% this.Model.Email %>注入

<% : this.Model.Email %>

<% this.server.HtmlEncode (Model.email)%>//实际网络核心编码

还有就是防止 SQL注入

验证码

现成的验证码

引用 DLL captcha

安全的问题,登陆的问题

怎么知道请求我们的用户是谁?是谁与权限 第一步验证 以前的是 validation 现在的是 Athenacation

还有授权的问题

关于安全的理论概念

Kerberos http://www.cnblogs.com/haogj/archive/2010/10/04/1841715.html

账号密码 在 wimdows里面

一个用户对应 n个账号的话,就是代价很高 要记住一堆绽放哈

代理是什么?服务的客户端代理

开放的网络环境下 安全是一个问题

就是服务器知道你是谁 你访问的时候也把身份返回去 方法过笨

Page 98: Csharp

www.happy12.com 010-82387501 那么怎么才可以高效呢? 认证有口令 用户也有口令 认证服务把口令存到中央数据库中 这个就是认证服务器(验证用户名口令,记录了此用户的权限) (后面还

有邮件服务器 短信服务器) user ( 用户口令 ,提出服务器访问要求 )

Charon 除非你确实得到了认证 而且还要同时告诉你要使用什么服务 用户名+口令+服务指向 然后 charon 就会回发邮件服务器的密码给你 然后就是直接访问

但是 charon是不会直接给你的 防止你绕过我 而且还有可能被你伪造作为用户

但是 charon会给你一个 ticket 包含了你的身份,而且名字是用邮件服务器的密码加密

然后 Email服务器用自己的密码把票解密 拿去用户名 密码

能验证 而且还要安全可靠

写一个监听器 以太网是以 IP

重演呢? 密码的重演

钓鱼呢?就差一个符号 服务器都是假的呢? 交互验证 安全系统的验证 kerberos V4

三头狗

企业开发 单点登录呢?还是需要这样的思想的。一次登录使用所有的系统。单点登录的软件。

知道网站的用户的身份

登录 用户名—>票据

请求中附带票据 那么我们可以使用 cookie的技术

每次请求处理都附加

权限

建立 view的时候选择 Edit

Internet选线 内容 自动完成

注销 同名过期的 cookie

控制 登录与注销

再学两个新的类

用得领域不同含义也不同

专门为用户对象设置一个安全用户对象 如何表示用户对象。

System.Sericuty.Principle System.Security.Principal 命名空间定义表示代码在其中运行的安全上下文的用户对象

有很多种的对象 有很多种的用户对象。怎么样令对象一样呢? 接口啊!!!

Iidenity

要写一个实现了接口的类

创一个不是空串的就是已经验证了

Page 99: Csharp

www.happy12.com 010-82387501

用户标识对象 控制 登录与注销的显示

判断用户的角色与权限的接口,继承了 Iidentity

4中用户标识

值对象

MVC 模型对象

程序内部 iidentity iPrincipal 很高级的用户对象 也就是一个对象表示的问题 但是验证的代码还是要自己写的,也就是兜了一圈 建议是放在最后验证之后

逻辑层

论坛地址: http://www.sisheng.net.cn/forum/forum.php

博客园的例子 回帖登陆再回到原来的页面的问题 需要传进去我们之前的地址。URL(XXXX?参数) 回到我们原来的那个页面

调试测试与日志 debug text Log

调试 debug 设置断点 switch 快捷方式 F9 breakpoint 移动鼠标 按键盘 I 右击快速监听

F10 按步执行 复杂的情呢?

条件断点 成立的时候才触发 当 i=1000才听下来 右击断点 条件 i==1000 红圆圈会附带上一个加号 is true

表达式的值发生变化的时候再停下来 isChanged 第一次执行 然后 执行到判断的条件 1/100

命中技术 HitCount 次 倍

断点过滤器 可以针对多线程的程序

可以直接输出信息 不适合用 console会影响的速度的

Output窗口,可以输出调试的信息 线程的 ID 名字 内容 就时刻直接看了

还有各种窗口 watch窗口 watch可以是多个监视窗口,防止重叠。

Page 100: Csharp

www.happy12.com 010-82387501

还与欧 lcals当前的局部变量,可以让我们开导变量在方法与方法中的变化

看调用堆栈 就是查看你们的调用对象。适合多层额监测

测试

单元测试

Assert 测试驱动开发

的思路开发 的原则 除非你有一个目的 测试的功能 想把你的测试写好,测试第一 step one 想写一个测试的接口 没测试就是没需求 没需求就是没必要

防止出现重复的代码 程序员自己的测试 Nunit 还有专门的测试 2.5.10

必须是 public的 而且需要有一个缺省的构造函数

TestFixture修饰在类里面

TestAttribute标记测试类中的方法 public void 无参

先编译再启动 Nnuit然后直接 run就好 可以反射出来我们的测试类与值· 还有 Nunit还有很多 不同的东西

方法短小 功能单一

断言 assert Arequal AreSame

Set up 为每一个测试的方法准备初始化 public void 无参 在每一个测试方法执行之前被执行

Tear down 正好是相反的 相当于我们的 dispose用来释放我们的资源 就是方便我们对非托管类资源的释放 被垃圾回收掉了

SetupoFixture 但是我们是针对这个测试类执行一次的

TestFirstSetup

TestFirstTeardown

测试集

Config类库加是无效的 而且还是需要编译的

创建一个特殊的特殊文件 需要特殊的位置 特殊的名字 所以必须是放在测试项目下,而且是 config后缀的

一般仅仅是使用在初始化加载我们的 App.Config 位置文件名扩展名

日志 log

是一个记录的机制

这些跟我们正常的显示是不同的,希望可以输出到同样的地方 可以是 email 还是就是控制输出的级别 那么这个时候简单的级别的错误 就不需要输出了 而且

使用越简单越好

120、 日志器 就是几个静态的方法 debug 只有在定义了 debug常量的时候才有用,在 debug下编译才有用 Trace可以发布可以调试

TRACE一般信息 警告信息 失败的信息 Trace.TraceInfomation 只是在 output下输出的 不会影响我们的标注输出

转换到控制台的输出 Listeners.add

121、 监听器,实际输出的工具 可以记录到很多不同的地方

122、 控制开关 级别 详细的 简单的机制 日志控制开关

TraceSwitch指定一下 输出级别

(微软的)还要自己去判断

常见的日志系统 本身 VS自带的 log4Net 使用方便而且强大 但是微软的有点乱

首先是添加引用 我们的程序集合 Log4Net

Logger 一共是五个方法 取得日志器 因为实现了 Ilog接口可以用

Appender 保存到哪里 我们也是有不同的对象的 有控制台的 还有很多很多

Layout

Fitters

最好全部的设置存放在 App.Config中 先是声明再是使用

Configsetions 配置节要写在最前面

<section name=”log4Net”>

Page 101: Csharp

www.happy12.com 010-82387501 输出级别 设置的记录器

追加模式 类似文件流那样

布局 日志的格式

内容及其格式

过滤器

还有一些不可见的字符 记得编译

要养成记录日志的习惯 好处就是方便我们找问题。

就是

论坛地址: http://www.sisheng.net.cn/forum/forum.php

webconfig的作用 两个配置文件的使用

在.net里面有要求 第一个

位置必须放在网站的目录里面 在根目录下得 webconfig下

而子目录下呢?就是限制用户看得页面 进行限制 因为网页会很多

在webcongfig 在 anthentucation中 模式是表单验证 forms default url LoginURL 在这里配置 那么 cookie的名字必须一样 这样会使我们的网页更加灵

<!-- 在验证方式的配置参数中进行配置 -->

<authentication mode="Forms">

<forms defaultUrl="~/Home/Index" loginUrl="~/Account/Login" timeout="2880"

name="Ticket"

>

<!-- 用户账号 -->

<credentials passwordFormat="Clear">

<user name="alice" password="123"/>

</credentials>

</forms>

</authentication>

设置过期的时间

System.web.Security.FormAuthentication.SingOut();创建一个过期的 cookie 但是还要做一个 redirect to slogin page LoginSample

public void Logout()

{

// 注销就是将用户保存的票据删除

// 只能间接删除浏览器端的 Cookie

// 用来创建一个过期的 Cookie ,以便删除票据

System.Web.Security. FormsAuthentication.SignOut();

System.Web.Security. FormsAuthentication.RedirectToLoginPage();

#region

//// 创建一个与浏览器端同名,但是已经过期的 Cookie

//HttpCookie cookie = new HttpCookie("Ticket");

//cookie.Expires = new DateTime(1999, 1, 1);

//// 发送回浏览器

//this.Response.Cookies.Add(cookie);

Page 102: Csharp

www.happy12.com 010-82387501

//// 重新访问登录页面

//return this.RedirectToAction("Login");

#endregion

}

自动回到 rediretoLoginPage 然后再自动返回 returnURL

抽取我们的验证 写到哪里呢? Controller 再提升 就是 HttpApplication globle.asax

7、MapRoute 路由表

8、HttpApplication 究竟 一开始是 application然后就是再创建 controller对象 事件 当然里面还能写观察者模式

为什么要那么复杂呢/ 所以把处理的环节 里面很多各种各样的类

但是效率过低 每次都算就是太悲催了。那么怎么可以省下我们的对象呢

那么就需要 cache 缓存 把上次的结果存起来 MapRequestHandler HttpModel模块 时间 典型模块大全(响应处理程序,其实就是为了扩展)、Module 高

深的model 一般写在一个单独的程序集里

是处理 application的

所以要拿到 application的对象

先继承WebIhttpModule 有 dispose()释放模块的使用资源 指非托管资源 void Init (HttpApplication application) 完成事件注册

我们自己是不会调用的 当网站的底层创建 httpapplication对象的时候将会调用这个方法的时候对事件进行注册

花费的时间呢?beginrequest endrequest的时候

跳出类与方法的框架 httpContent 就像是潜水艇 保证人的生存 正常工作的环境

回应的流 HttpApplication —handlier — Content —( response request ) context 贯穿我们请求的整个过程 context 可以抓取所有的数据 帮我传

递数据 可以超越方法与类

基于 httpContext的状态管理完成

可以在内部存一个字典 Web.HttpContext context= web.HttpContent.Current;

还有办法 httpContext context = (sender as System.Web.HttpApplication).Content;

存 context.Items[“Begin”]=begin;

Time = Covert.ToDatetime (Context.items[“Begin”]); 建议用毫秒看书

发到浏览器看 其实还是流

Textwriter response outputstring

Writer.Write(“ ”);

Endrequest最后输出

配置文件配置自定义 modules <!--自定义配置module-->

<httpModules>

<add name="myModel" type="namespace.class,DLLname"/>

</httpModules>

namespace DouBanModule

{

public class TimeModule:System.Web.IHttpModule

{

//首先先配置好我们的module

//</compilation>

//<!-- 配置自定义的 Module -->

//<httpModules>

// <add name="name" type="NameSpace.ClassName,ClassLibraryName"/>

// <add name="name" type="MyModule.TimeModule,MyModule"/>

//</httpModules>

//<authentication mode="Forms">

/// <summary>

/// 释放非托管资源

/// </summary>

public void Dispose()

{

//没有使用托管类的资源

}

/// <summary>

/// WebConfig自动帮我们执行

Page 103: Csharp

www.happy12.com 010-82387501

/// </summary>

/// <param name="context"></param>

public void Init( HttpApplication application)

{

//请求事件注册

application.BeginRequest+= new EventHandler(application_BeginRequest);

//结束时间注册

application.EndRequest+= new EventHandler(application_EndRequest);

}

/// <summary>

/// 开始事件,

/// </summary>

/// 获取context对象后写入时间到Items(字典)

/// <param name="sender"></param>

/// <param name="e"></param>

private void application_BeginRequest( object sender,EventArgs e)

{

DateTime begin = DateTime.Now;

System.Web.HttpContext context = System.Web.HttpContext.Current;

//方法2 System.Web.HttpContext context= (sender as System.Web.HttpApplication).Context;

context.Items[ "Begin"] = begin;

}

/// <summary>

/// 结束事件

/// </summary>

/// 从sender获取context,然后对比时间,再写入到字符流

/// <param name="sender"></param>

/// <param name="e"></param>

private void application_EndRequest( object sender , EventArgs e)

{

DateTime end = DateTime.Now;

//System.Web.HttpContext context = System.Web.HttpContext.Current;

System.Web.HttpContext context = (sender as System.Web.HttpApplication).Context;

DateTime begin = (DateTime)context.Items["Begin"];

TimeSpan span = end - begin;

System.IO.TextWriter writer= context.Response.Output;

//继续写入

writer.Write("<h1>本次请求花费时间:{0} 毫秒</h1>" , span.TotalMilliseconds);

}

}

}

但是为什么是放在最后的呢、

那么我们能不能不在外面的呢?

如何在 view中划出呢?

Module太麻烦了

直接使用 HttpContent.TimeSpan 绑到 HttpContent.TimeSpan

Module是方便 但是麻烦 仅仅是适合从用

写在 globle中方法的名称准寻特定的规则 则会直接注册到相应的程序上 application _ EventName

Page 104: Csharp

www.happy12.com 010-82387501

Controller要轻 把对应的用户验证 放在我们的 globle中

Globle 其实也警械了 FormAuthrncatin Module

那么module配置的时候就已经是配置了

Config 有一个叫 webConfig 针对我们里面都使用了

对我们这台电脑所有的都已经配置好了很多了。

里面有 FormAuthcationModule 所以基于票据的 就不需要再写了 支持 4中验证方式 不是同时都起作用

验证方式 forms 就是我们的输入验证 重点的 但是在微软里面都写过了

用得原理

Windows 专门针对 windows操作系统的 核心是操作系统 TFS版本管理器 把这套服务卖给公司 跑在局域网 服务器的时候呢/

如何才愿意使用呢?原理是在企业内部是局域网,统一管理的网络,管理单位称为域 域控制器 Server可以管理电脑 可以登录公司的电脑用域账号,随意登录。

那么我们内部的 windows 票据 发到服务器上来 从客户端到服务器 这条路就通了 仅仅登录系统就知道你的角色了。企业内的软件开发 ,那么就用 windows

实现无缝连接

Password 多个账号的问题 开发一个 password护照 微软验证 便于云集成的程序 开放 API

None 什么都不请求 一般适合静态网页 仅仅是公布信息的

到模式中改为 none

支持 4中方式

其实还有我们想要的东西

模板页

以前都是视图来做的,但是开发的时候有很多内容都是相似的 但是要是继续画就浪费时间了

一个叫做部分页

一个叫做母版页

选择母版页??

那么全部都是我们一点一点的学出来

做一个 banner

Id #

Class .

42、 新建视图却是剩下 div aspx式的部分页面(专门是负责数据绑定的快) 这里强制转化为 sring[]

// 下面的 Action 实际上不生成整个页面

// ChildActionOnly 指仅仅在其他视图中被使用的 Action

// 不能直接被调用

[ChildActionOnly] 只能是子action才可以访问,不能直接访问

public ActionResult MovieList()

{

string[] names = new string[] {"海洋", "鸟的迁徙","世界很美丽"};

return View( names );

}

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<string[]>" %>

Page 105: Csharp

www.happy12.com 010-82387501

<!-- 无符号的列表 -->

<ul>还可以嵌入 foreach

<% foreach (string name in this.Model)

{ %>

<li><%= name %> </li>

<% } %>

</ul>

2、新建视图选择分部视图

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>

<div style="border:1px solid blue">

<img src="../../Content/images/banner.png" />

</div>

3、在主页面调用两种部分视图

<% html.RenderPartial(“name”);%> 执行我们的部分视图 自己不处理数据 不走 action

<%= Html.Action("MovieList") %> action下得伪部分视图

<%Html.RenderPartial("banner"); %> 真正的asax部分视图

子action// 下面的 Action 实际上不生成整个页面

// ChildActionOnly 指仅仅在其他视图中被使用的 Action

// 不能直接被调用

[ChildActionOnly]

public ActionResult MovieList()

{

string[] names = new string[]

{

"海洋",

"鸟的迁徙",

"世界很美丽"

};

return View( names );

}

选择了模板页的页面

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/MasterPage.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">

About

</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>About</h2>

</asp:Content>

那么生成母版页 专门针对我们的 MasterPage 里面有内容容器 镜框 你的内容放在什么地方? 分为 title main

Share就是所有的控制器都是使用此模板页 …/上一级的意思

算出地址 <%=URL.content(~“文件夹/名字”)%>

<%--<img src="../../Content/images/banner.png" />-- %>

<%=Url.Content("Content/images/banner.png" ); %>

论坛地址: http://www.sisheng.net.cn/forum/forum.php 就是要注意 women的交流的能力

安全的问题 一部分是验证 第二部是授权

昨天是可以验证的了

白名单 黑名单 还是 Httpapplication 白名单 黑名单、资源、角色(用户组) role administration 可以对人与资源进行分类

管理 最后还对资源进行分组(权限)

Identity IsInrole 查询我的角色 (组) 还可以操作 角色管理 角色与用户的增删改查

RoleProvider

创建角色的 createrole

删除角色 增加删除 检查是否存在

一种是用户的

一种是用户与角色之间的关系的

Page 106: Csharp

www.happy12.com 010-82387501

创建在哪里呢?

数据库 uniqueidentifier 16个字节 4的字节就是 4G了

多对多的关系 中间表

用户的管理 membershipprovider 但是框架很庞大 自己用接口规定我们的用户管理

实现了系统很多的抽象的类 applicationService

使用抽象基类

领域模型与数据访问层有一个接口 用户的接口

工厂模式

方法 返回是实例 就是帮我们都实例化好了

可以看到角色创建删除角色

已经处理了角色 ,用户与角色的关系

表单的没有角色只有用户名

在 globle中在得到 票之后 取得用户名 获取角色

然后就跳到只有管理员可以看得页面

怎么样管? 取到权限

1、当前的用户 是谁 可以在 action中判断 直接判断 pricipal = context user user.IinRole(“”””)

FromAthuitin 但是灯枯也是有权限的 就是利用 role IsInRole来写代码

带角色的安全

直接在 action贴标签

[Authorize(roles=”Admin,Guest”)] 直接限制 可以贴授权的标签 表示拥有角色才能访问

也可以写 users

[Authorize] 表示经过验证的用户才能访问 直接提供了支持但是死的 要是更改角色呢? 我们还需要一个界面去解决问题

开发中的设计模式

讲讲删除 view中的链接是 get 生成地址 生成参数

路由映射 cai controller action id 我们就可以好好利用 id

用 new []

用路由参数 RouteValueDictionary()

Session的原理

客户端 session的 ID

Session就是一个双字典 然后再对应找 一般是以 cookie的形式记录在客户端的

.net怎么去使用呢?

所有的东西(sessin)都跑在 web服务器的网站程序的内存中 但是服务器断电、崩溃等原因会造成 session丢失的问题

程序很脆弱 因为你不知道用户的输入是什么,要保证程序的顺畅运行

那么微软的 IIS内置一个诊断的功能 自动检查网站的工作状况,出现异常就是帮你自动重启 但是还是会丢失 session

还有很多增强的版本,、

43、 session服务器 其实就是一个软件 他的名字是 管理工具— 改成自动

<!--用®?session存ä?储ä¡ésession-->

<!--<sessionState mode="StateServer"/> -->

44、 存储在 SQLServer 可以防止内存大小的问题 那么写一个参数就好了

45、 自定义 抽象的基类 自己写实现配置就好

46、 关闭使用 session 效率低占用内存

还有 session会话 用户级别的会话存储时间的问题 而且客户浏览器关闭后 session还是继续 存储的问题

那么就会使用滑动过期的机制来存储 一般默认是存储 20分钟的 从最后一次开始计算

我们也是可以在<!--<sessionState mode="StateServer"/> -->中设置时间

使用的场景:登陆、投票(session就是太悲剧了)一个手机号投

Application 是全局的状态管理 都可以存也可以读 应用全局

省空间,缺点是大家都可以存,但是新的会把旧的覆盖掉 那么我们用来存什么呢? 一般是所有的用户都需要用到的数据 访问论坛的数据

用户的数据是 session的

但是大家都可以看得呢?

在线的人数 在线人员的列表 而且放在内存中 所以这个一般是全局变量

但是它有很多局限,那就是放在内存,会影响性能,而且没有过期的时间,除非你的服务器关,还是自己清理

明天我们将会学习 cache技术

网站对象 qing求 application server对象 6大对象 现在还围绕着 继续学习的

论坛地址: http://www.sisheng.net.cn/forum/forum.php

Page 107: Csharp

www.happy12.com 010-82387501

数字证书 X.509 kerberos服务器是服务器 客户端是客户端呢? 在公网上解决的问题 一切都是不可信的 而且代价也是很高的

公钥体系 认证中心 可信的机构 发证明 你的姓名 你的地址 公钥 私钥 大指数分解 U盾的原理 申请一个数字证书

先问公钥,任何人都可以拿到 拿公钥把信息进行加密 再发送信息 公钥的内容要用私钥 解密 遵循先者先保障

先用私钥 加密信息 得到数字签名 类似数字指纹 MD5 私钥签名 公钥加密

Windows1会本来就验证了数字证书 国家的申请

缓存 cache 目的是想让程序变得敏捷快速 程序对决 围棋下棋的程序

云识别技术 但是没有价值 主要是算法太懒

还有一种快的方法就是连算都不算,这个就可以达到很快的效果了。

CPU缓存 AMD与赛扬 主频很快 事实上还是存储器 可以满足 CPU运算器的作用 、

寄存器就是为了提高速度 一方面提高寄存器的数量 第二级就是缓存 从内存中抓取数据 目的是为了更快

CPU不断进行预测 然后再更新到内存中 减少 CPU对内存直接操作

CPU缓存是很重要的 计算机的体系 会开辟一个缓存区 (流的问题,同步的问题,使用文件流的问题必须关闭) 保存的内容先放在缓存区

所以缓存是很重要的 提升处理的效率与速度

缓存在网上视频的问题,用空间来换时间,播放的是缓存中的数据。

缓存在网站程序的使用 一般是针对没变的内容。

缓存简单地来看可以看成是一个字典 我们记住对应的 key 拿我们的 key就可以从内存中找到我们请求访问网页的内存了。

Cache应该是动态的 不是放进去了就永远在那个地方 要根据一些参数进行控制

1、有计数器 频率高的就上去了,低的就是清除 进行动态的调整

2、滑动时间 相对时间 计时器

3、设置设置时间点 绝对时间

3、优先级 在同样的情况下 放很多数据 大家都一样,有个新的呢? 还可以指定一个本身的优先级 重要的一般的次要的 使我们的内存最大化的使用

缓存管理器

public ActionResult Index()

{

//判断是否有对象了

//System.Web.Caching.Cache cache = this.HttpContext.Cache;

//方法二,利用HttpRuntime的cache静态对象

System.Web.Caching. Cache cache2 = System.Web.HttpRuntime.Cache;

string news = cache2["Cnews"] as string;//可能有,也可能没有

if (news == null)//没有只能去读取了

{

string path = this.Server.MapPath("~/App_data/Cache.txt");

news = System.IO. File.ReadAllText(path);

news += "缓存";

this.ViewData["news"] = news;

//读取之后要缓存读取的数据,以便后继的使用

System.Web.Caching. CacheDependency dependence = new System.Web.Caching.CacheDependency(path);

cache2.Add( "Cnews",news,dependence,System.Web.Caching. Cache.NoAbsoluteExpiration,

new TimeSpan(0,20,0),System.Web.Caching. CacheItemPriority.Normal,null);

//NorRemoveRable 不允许删除;Normal后写一个委托,可以扩展我们的东西

}

this.ViewData["news"] = news;

return View("News");

}

但是我们大多数的数据是数据库的,但是缓存依赖不好处理。

要是数据修改了呢? 重新刷一遍 设定刷新周期为 10分钟

最好还是数据库一修改 9就自动更新 当修改的时候发送信息

就是针对 delete insert update DML DDL(create、alter、drop)DCL(角色与权限的)

所以我们我单独监控我们的 DML

有一个技术叫做触发器

触发器 可以自己定义 一类是系统级触发器 (数据库系统级别的,谁使用了我们的数据库(用户登陆触发器))一类是表触发器()

可以在表上写一个触发器 CREATE TRIGGER tbl_TableName_DML ON MoneyUsing --执行之前权限查询 执行之后适合做监控 --tbl_DML的语句 AFTER INSERT , DELETE , UPDATE

Page 108: Csharp

www.happy12.com 010-82387501 AS BEGIN print '触发器被执行了。' END GO

insert into MoneyUsing (MoneyNumber,[Money],MoneyType )values (1,1,1)

那么我们怎么在外面知道呢?

巴修改表的记录记录到数据库的记录表中 表名

大多数的 dba也是要获取 changeNo

那么我们如何实现呢?

微软呢?已经写好了,在 4.0中,已经有了 找一个 asp.net_regsql.exe 在命令行执行

必须在命令行 -ed创建 –S 服务器 –E –d name –ed

Finished 会多出一张表 监控表

-lt 显示被监控的表名

-t tablename – et 启动监控

有了一个触发器 但是里面掉哟家那个存储过程

C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regsql.exe

Page 109: Csharp

www.happy12.com 010-82387501

在后台使用

建立缓存依赖对象

MVC的基本概念

优化网站 针对性地优化 不可能 是要找到问题在哪 我需要网站的访问报表 需要的时间 知道优化的 数据访问 数据库 绝大对数是在数据库的访问上 百分

之九十是在数据库 第一步可以是缓存 最直接的 oracle 一般是BS架构的 ERP网站 我的缓存特别好 Java C#没有什么很大的区别 都应该转移到编写的效

率与速度上

要是来源于自我查询 员工角色表+角色表 可以创建 可以创立多个缓存依赖对象。

使用组合缓存依赖对象 就是使用缓存依赖对象的集合,就是把缓存一个一个的放进去 然后添加进去

CacheDependency scd2 = new System.web.Caching. CacheDependency();

AggreteCacheDependency acd = new System.web.Caching. AggreteCacheDependency();

Acd.Add(scd1);

Acd.Add(scd2);

上面的都是针对数据缓存的,但是我们现在研究一下视图缓存对象

[outputcache(Duration=时间,多长时间删掉 69, VaryByParam=”none ?ID=”””其实就是不要因为地址参数而该表)]

还是存在服务器的内存里面的 如何设置呢? 改为 no 先当于可以缓存多个版本

还可以应用到子 action 页面局部缓存 web缓存是数据缓存的一个应用

Page 110: Csharp

www.happy12.com 010-82387501

论坛地址: http://www.sisheng.net.cn/forum/forum.php 8、 程序进程线程 CPUCLR 9、 工厂模式 10、 遇到乱码的问题 如何解决

4、权限问题 附加数据库失败 任务管理器看用户 属性 安全 users 看权限 计算机管理 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools\Computer Management.lnk 本地用户与组 用户与组查看 一般是对整个文件夹进行授权 还有就是数据库用户 与表用户的关系 在删除的时候也是要值得注意的 11、 项目的介绍 Web MVC 数据访问 数据库表 查询语句 等等 支持多数据库的 IDAL 数据访问层的接口 面向抽象编程 然后就是工厂 使用了反射!! 要讲究效率 要有专用的命名空间 model 修改命名空间 属性 默认命名空间 priate set ; private get 最好就提供一个默认的构造函数 以支持序列化的操作 DAO

Factory Icategory SQLServerCategory SQLHelper

Model

CategoryInfo 反射与序列化 内存是有限的 可以把内存的数据序列化 停在其他的地方 这样内存就不怕停电了。序列化的手段实现持久化的目的 不都是字节吗? 你自身知道类型 但是其他东西不了解 怎么样存 怎么样写? 能不能不对每一个类写呢?一看就知道的话,那么写一个类就好了,专门写一个对应类 告诉做序列化的对象,他们就知道了。!!! 贴上一个标签。 数据结构 必须附带类型信息 现在存数据要浪费空间,但是以后其他人就可以直接知道它的类型 说明一样的话 我把每种值书 uo放一个说明的地址,那么这样就剩下空间了。用来放类型说明 还能做什么运算 由什么可以调 在.net只要用到对象则直接有对象的类型的声明的对象 System.Type 是系统中核心的类 其他的都是他的实例 但是可以带来极大的当面

Page 111: Csharp

www.happy12.com 010-82387501

那些说明叫做元数据 metadata就是说明数据的数据,是在程序执行的时候可以知道,方便我们动态的编程 可以写出高度灵活的程序 那么利用了我们元数据的知识这些都可以解决了。 int i = 100;

System.Type intType = i.GetType();

Console.WriteLine(intType.FullName); //类型

Console.WriteLine(intType.AssemblyQualifiedName); //程序集的名

public class Person

{

public string Name { set; get; }

public int Age { set; get; }

}

Person alice = new Person();

System.Type personType = alice.GetType(); //获取实际的类型

Console.WriteLine(personType.FullName); //得到类型名

Console.WriteLine(personType.AssemblyQualifiedName); //获取person类的程序集的信息

反射 Person alice = new Person();

System.Type personType = alice.GetType(); //获取实际的类型

System.Reflection.PropertyInfo[] properties = personType.GetProperties(); //获取此类中的公共属性

foreach (System.Reflection.PropertyInfo p in properties)

{

Console.WriteLine(p.Name);//属性名

Console.WriteLine(p.PropertyType.FullName); //属性类型名

}

改变值 // 还可以动态访问对象

alice.Name = "Alice";//这个是赋值给Name字段

// 首先取得属性描述对象

System.Reflection.PropertyInfo ageProperty = personType.GetProperty( "Age");//获取age属性字段的对象

Console.WriteLine(ageProperty.DeclaringType); //获取age所在的类名

Console.WriteLine(ageProperty.Name); //获取属性名

Console.WriteLine(ageProperty.PropertyType); //获取类型

ageProperty.SetValue(alice,18, null);//修改值

// 检查动态赋值的结果

Console.WriteLine(alice.Age);

创建 // 可以动态创建对象

string className = "TypeSample.Person";

System.Type personType2 = System.Type.GetType(className); //根据类名进行反射得到类型

// 使用反射技术,创建对象实例

Person person1 = System.Activator.CreateInstance(personType2) as Person;//通过反射构造出实例,但是要注意要有系统的默认构造函数

// Person person2 = System.Activator.CreateInstance(null, className) as Person;

// 使用反射动态赋值

ageProperty.SetValue(person1, 20, null);

Console.WriteLine(person1.Age);

反射工厂(IOC对象工厂) <1>工厂 <?xml version="1.0" encoding="utf-8" ?>

<configuration>

<appSettings>

<add key="className" value="TypeSample.Person"/>

<add key="prop1" value="Name"/>

<add key="prop1Value" value="悟空"/>

<add key="prop2" value="Age"/>

<add key="prop2Value" value="10000"/>

</appSettings>

</configuration>

Page 112: Csharp

www.happy12.com 010-82387501

public class ObjectFactory

{

public object GetObject()

{

string className = System.Configuration. ConfigurationManager.AppSettings["className"];//获取类名

System.Type type = System.Type.GetType(className);//得到类型

object obj = System.Activator.CreateInstance(type);//创建类型

//1得到name属性

string person1Name = System.Configuration. ConfigurationManager.AppSettings["prop1"];

//1得到name的value

string person1Value = System.Configuration. ConfigurationManager.AppSettings["person1Value"];

//2得到age属性

string prop2Name = System.Configuration. ConfigurationManager.AppSettings["prop2"];

//2得到age属性的value

string prop2Value = System.Configuration. ConfigurationManager.AppSettings["prop2Value"];

//转为属性

System.Reflection. PropertyInfo nameProperty = type.GetProperty(person1Name); //实现1name属性

System.Reflection. PropertyInfo ageProperty = type.GetProperty(prop2Name); //实现2name属性

//赋值悟空

nameProperty.SetValue(obj, person1Value, null);

// 如果属性的类型不是字符串,那么进行转换,类型判断

if (ageProperty.PropertyType == typeof(int))//赋值岁数

{

int age = Convert.ToInt32(prop2Value);

ageProperty.SetValue(obj, age, null);

}

return obj;

}

}

ObjectFactory factory = new ObjectFactory();

Person p3 = factory.GetObject() as Person;

Console.WriteLine(p3.Name);

Console.WriteLine(p3.Age);

后来我就萌生了把索引转换为属性的想法 开闭原则 就是开放接口 你继承了 我就实例化的时候就可以调用了。我定义了鼠标的接口,其他鼠标只要继承了这个接口,我们就可以处理了。 而反射是不完全编译的,都太编程 appsetting应用程序配置参数 在类型对象中还包括里面的对象 GetProperties 每一个属性的 System.Reflection.PropertyInfo[] proviters=paonftype. GetProperties (); 到最后再 foreach执行 有 name type 类型说明对象的地址 还可以动态的访问对象 Alice.Name =”Alice”; System.Reflection Property ageProperty = persomType.GetProverty(“ago”); DecalaringType Name ProvertyType setValue (alice,18,null) 检查动态复制的效果

论坛地址: http://www.sisheng.net.cn/forum/forum.php 47、 工厂 吧对象的实例的方法封装了 低耦合 受到冲击的尽量小 48、 单例模式 Instance实例 在调用的时候呢? 饿汉模式 先创建好 49、 IOC依赖倒置 spring.net 就是根据我们的接口 一个接口就是一个对象的实例 就是调用的时候是要把接口也放到容器中进行考虑的

DI 依赖注入 对象里面还有成员 初始化的时候直接赋值 可以利用反射 取得一个订单对象就全部赋值好 50、 对象池 限定可以使用的对象的个数 可以是还回来的

Page 113: Csharp

www.happy12.com 010-82387501

51、 用 list得话就要选 list Inherits="System.Web.Mvc.ViewPage<IEnumerable<myPetShop.Model.Category>>" %>

获取分类的产品 页面传值 结合 URL重写 + 页面 model 地址里面 globol里面决定的

需要调用路由的方法 这个就是我们的 URL重写 映射 //自定义路由

routes.MapRoute("Product","Product/{CategoryID}/{PageIndex}" , new { Controller = "Product", action = "GetProducts", pageIndex = 0 });

页面 <td>

<%= Html.ActionLink(item.CategoryName, "GetProducts", "Product", new { CategoryID = item.CategoryID, PageIndex = 0 }, null)%>

</td>

public ActionResult GetProducts(myPetShop.Model. ProductModel model)

{

return View();

}

然后就是画图 就是查询出鸟的信息 还有分页 怎么样取呢? 先定义接口 服务器分页 全部读取再提取 数据库分页 直接传参到数据库 浏览器 脚本分页 AJAX来了 总数 页长 就可以进行分页的 还有一个就是当前的页码 下午解决数据库分页的问题 与服务器分页的问题 连参数也可以抽象出工厂吗?答案是可以 自定义的路由很强悍啊 其实就是做一个回发 数字+一页-1 除以 页数 数据库分页 现在是分页不行还有 模板页 还有 5、 top 前几条 饼的翻转 4个一页 还要补上我们的序号呢 Row_Num() 我想结合分页函数 就是利用系统的视图 呵呵 我觉得我太邪恶了 可以来回地倒 6、 下标 利用 SQLServer标识列 Identity 种子与增量 可以创建一个临时表 还能够 drop 两个井号为全局临时表

Page 114: Csharp

www.happy12.com 010-82387501

7、 存储过程 得知 id index当前页 每一页的大小 就是建表的基本操作 自己添加标识列 Insert into #pruduct (字段) (Selelct 得到查询的记录,按要求提取而且字段要统一) Declare @开始下标 @结束下标 Set @开始 当前页数*size set@结束=@开始+@size 再查询出来 返回一个总得行数 表变量其实比较简单 结构没区别 这个是创建临时表 表变量 就是变量 但是类型是表 Declare @table table { 样子 } 但是是变量变成内存 CREATE PROCEDURE prGetPageProductList @CategoryID nvarchar(10), @PageIndex int , @ProductIndex int, @PageSize int, @ProductCount int out AS BEGIN select @ProductCount=Count(*) from Product where CategoryId=@CategoryID declare @tmp table ( ProductIndex int identity(0,1), ProductID varchar(10), CategoryID varchar(10), ProductName varchar(80), ProductionDescn varchar(255), ImageURL varchar(80) ) insert into @tmp (ProductID,CategoryID,ProductName,ProductionDescn,ImageURL) select ProductId, CategoryId, [Name], Descn, [Image] from product where categoryid = @categoryid; declare @start int; declare @end int; set @start = @PageIndex * @PageSize set @end = @start + @PageSize select ProductID, CategoryID, ProductName, ProductionDescn, ProductionDescn from @tmp where ProductIndex >= @start and ProductIndex < @end END GO Direction.out put 参数数组 为 list的参数赋值 out赋值 还要读文章 SQLServer的分页的 程序 存储过程 都是可以搞得 争取两周做完 晚上说一说 JS的开发

论坛地址: http://www.sisheng.net.cn/forum/forum.php 1、连接

<a href="/Home/Index"> <img border="0" src="../../Content/images/Commond/Logo.gif" alt=".NET Pet Shop 4.0" width="287" height="78" /></a>

2、是购物车的问题了,就是 session中 我的收藏我的喜爱 都是购物车的问题 解决问题的思路的问题 那么我们再在程序中去实现一下。

Session的选中的问题 加入购物车 查看一下 看看购物车的内容 就是一个超级威武的事情

Page 115: Csharp

www.happy12.com 010-82387501

增加删除 的功能 一般可以是 cookie与 session来进行 还是要从数据库查询的 购买收藏

清空购物车

谁能用购物车 只要连接到服务器 而且在断网之后 就 SQL处理(会员) 还有靠 cookie(一般客户,用来保持持久连接性)来进行 session还原 登陆了之后 就是

cookie 转 session 但是登陆之后再注销就丢失了购物车 但是过了一段时间之后 又重新加载 我再次登陆呢?也就是说我们登陆了后 session SQL 检查 cookie 那

么我们买了之后呢? 收藏呢? 隐藏域呢?Cookie的隐私问题呢?

操作

购物车的时间 浏览器已关闭就没有了 但是服务器呢?这个就是一个问题 所以还是需要解决的

京东还有寄存的功能 临时的数据库 session表 保存 session的表

隐藏域呢?cookie呢?

即是说 很慢 发一次带一次 cookie 那就是无用的传输 巨大的 cookie fillder 就是很悲催 浏览器的限制是 4k 就是因为每次都会回发 4K 有很多的限制 没在

coookie存了。解决不了。解决匿名的情况了。

登陆呢?还是存在数据库 全部都是使用 sql 数据库。你的目的还是那个 session 依赖于数据库。那么我们全部使用 SQL 得了?搞笑啊。专属购物车,从临时表的信息

进行转化。

我又注销了,再次提取?就是两步更新。注销,

标识问题(编号)

注销呢?清空 cookie?还是原来的?

图片没有经过路由 要是没有的话 才找我们的 controller action

String.Format (“/item/{0}”), 就是可以利用路由拼连接串

怎么实现购物车呢?

购物车是一个对象?那么货物对象呢?呵呵,一切都好办了吧。

最后抓换为字段索引与 session记录

实际上是放 有个标识 内存、数据库、sesssion服务器、自定义办法

123、 直接使用 session 专门解决办法 直接省事 缺点呢?

装得是很多的购买项目 ID 数量 价格 名称 时间 各种操作的逻辑

那么删除的操作 我觉得是重点

先写一个购买的项目类 该定义的还是要定义的 收藏呢? Type用来区分购物车还是收藏

而且还要准备有一个查看的类

而列表 list是紧密的数据结构

字典是哈希的 适合频繁的查找 但是比较占空间 还要划分哈希码的存储空间

Dictionary<string,class>

If dictionary constainkey()

Add(string,model)

删除呢?Remove

先检查有没有 Remove(key)

修改数量

先检查 判断区间 然后到 0的话自动删除

购物车 存与取的方法

存,拿到当前的购物车对象,session key先检查 session是否已经有购物车 this.session[“cart”] as cart

说明还没有购物车,要创建

论坛地址: http://www.sisheng.net.cn/forum/forum.php 1、 Routedata <a href="<%= string.Format("/Item/{0}", item.ProductID) %> ">

<a href="<%= string.Format("/Cart/AddItem/{0}", item.ItemID) %> ">

注意 name

Page 116: Csharp

www.happy12.com 010-82387501

2、 针对大量的 action的自定义路由 routes.MapRoute("Cart", "Cart/{Action}/{ItemID}" , new { Controller = "Cart" });

隐藏域的使用 返回修改的内容 票据 cookie获取 ID名 匿名呢? 就是要保存我们的号 而且每一步还要 cookie 先检查我们的 cookie 要是没有票据 就没办法了 Cookie session cache SQL组合拳 但是 GUID 全局唯一标识符号 uniquedentity 保证唯一生成 就是利用了那个 GUID,有购物车的都有一条

使用子查询 讲的比较复杂 但是还行 就是票据的问题了 现在讲匿名的问题了就是有没有带这个特殊的值的 cookie的问题 通过检查用户的强求中的特殊的 cookie 在 home index SystemGuid guid = System.Guid.NewGuid(); 且还要重新回发 还是还要在最前面判断登陆的问题 global 系统写好的 module 管理我们的匿名的标识符 AnonymousID 自己做一个特定的 module 提供了方法 clearAnonymous Anonymousidentityfication 还要解决读取显示的问题 还要解决登陆 匿名的类型的问题 还要解决我登陆了还需要这个的问题 再转移到 httpModule 还要保存的问题 个性化数据 让我们开发更加简单 直接在 web层直接拿到用户的数据 profile。Cart 全部自动完成 profilemodulr 事件管道 11到 12的管道事件 注册到 9th事件上 T我们把数据优先读取 为了通用 有点绕 知道你读什么数据 你要保存什么数据的吧 所以有点绕 一次次独立的请求 断开方式的访问的问题 还有很多状态管理的问题 cache session 等等 cookie sql等等 明天做一个结账的问题 订单数据库

论坛地址: http://www.sisheng.net.cn/forum/forum.php

今天要做用户登陆 角色权限等等 权限需要的话要自己做

策略模式 设计模式 开发经典的书

一个问题有很多种解决方法,不想固定的方法,我们程序员可以使用所有的功能 提升灵活性

我们需要抽象 购物车要做什么操作 基类还是接口呢? 存 查 两个方法

我们真正关心得是功能

有一个工具类(以前叫工厂,帮助我们调用实现的办法,然后返回了我们需要的结果,不需要对象)

还有一个配置的文件 直接搞到对象的实例

Provider策略模式

抽像

N个实现(越全越好)

工具类

配置文件

要全部地照回来

Page 117: Csharp

www.happy12.com 010-82387501

先针对购物车的保存问题 再处理用户登录与角色的问题

工厂返回的是对象

策略返回的是结果

其实策略模式就是反射工厂的加强版而已

Membership成员管理 抽象基类是memberProvider N种实现 sqlMemberProvider

SQL中的脚本生成的表视图 存储过程

servervices数据库要支持

加密口令的使用(算法加密的口令,现在用哈希的口令,单向的运算,数字的签名,可靠性高,但是我们怎么检查呢,不同的内容不一样,相同的内容一样,安全

系数高的都没有 MD5以前是官方的标准,加盐算法 立即创建随机数 相互结合 这样破解的难度就加强了,存储随机数,然后再合起来再配置哈希,而且拼接的长度是

可调的)还有2次登陆

创建这些表的工具 名字是:InstallMemberShip 一系列

Asp_regsql 但是不用写命令行,而是直接写

在配置文件中配置

处理数据库

配置项目问题件 设置参数

登陆了之后 需要处理购物车的问题

新旧购物车合并

删除标识

删除旧的购物车对象

删除就得标识符

下订单与地址页面

结账要登陆

没有的需要注册

还有账号的信息

编辑查询修改

分页部分页

模型改造

界面全部要好了

开发中的问题

1、部分视图的使用

<1>分页 如何抽取的问题 就是要提取一个model 还有新建一个部分视图 而且还要全部地画好的啊

就是要分离出什么呢,就是要画出来?页数

传到主页的Model也会自动传到部分页的,所以我们必须知道要抽象出model

模型

而且部分页也是可以设置强类型的,就是单纯地帮下面的页数页码全部抽象出一个bar

小窍门 attribute 指定html的属性

就是class的问题 但是有Class @class 这些

核心对象

Context request repose

Runtime UnloadAppDomain Cache

论坛地址: http://www.sisheng.net.cn/forum/forum.php 124、 策略模式与序列化 125、 可空类型 126、 京东类型,怎么搞呢?数据库的峰值问题。如何处理 存数据库 信息队列(空间换时间,先来先走,数据结构,有效的资源换取最大的效果)

全部使用策略模式

Page 118: Csharp

www.happy12.com 010-82387501

订单汇总等等 信息队列 基于微软的消息队列(序列化) 队列本身是一个软件,数据库也是一个软件,存储在内存中,但是内存中也不足够保存呢? 而且停电呢? 怎么办呢? 要保证队列的可靠性,所以我们需要使用单独的队列软件。消息队列,很高级的软件,大型的服务器 MicrosoftMagicQ,存在磁盘,安全可靠 还有事务的操作性 处理大量的数据 相比的好处就是相当地块 迅速存储大量的数据 为日后争取到时间 那么我们怎么放呢? 那么就必须对放入的数据进行序列化 把内存中的信息序列化 变成信息队列 进行网络传输 利用反射 可以写通用的程序 写了好几种序列化的程序 2进制的序列化程序 namespace SerializationSample

{

class Program

{

static void Main(string[] args)

{

Person jobs = new Person();

jobs.Name = "Jobs";

jobs.Age = 50;

jobs.Sex = "meal";

// 使用反射,取得对象的类型

System.Type type = typeof(Person);

// 利用反射取得所有的公共字段

System.Reflection. FieldInfo[] fields = type.GetFields();

foreach (System.Reflection.FieldInfo field in fields)

{

Console.WriteLine(field.Name);

Console.WriteLine(field.FieldType);

Console.WriteLine("——————————————————————");

//从哪个对象获取值

Console.WriteLine(field.GetValue(jobs));

Console.WriteLine();

}

//[System.Serializable]可序列化标签

// 下面看一下系统提供的二进制序列化程序

System.Runtime.Serialization.Formatters.Binary. BinaryFormatter formatter= new

System.Runtime.Serialization.Formatters.Binary. BinaryFormatter();

// 提供一个字节流

System.IO.MemoryStream ms = new System.IO.MemoryStream();

//将对象序列化

formatter.Serialize(ms, jobs);

byte[] buffer = ms.ToArray();

Console.WriteLine(BitConverter.ToString(buffer));

Console.Read();

}

}

}

XML 2进制 Json的 2进制速度快 省内存 其他方式慢,占内存

但是是可以限制不序列化的 [System.Serializable] [System.NonSerialized]

Is Serializable接口

Xml序列化 soap协议

要加DLL system.runtime . Serialization.Formatters

基于 soap协议的 xml的序列化

Page 119: Csharp

www.happy12.com 010-82387501

Json方式下 {“age”:50} 序列化器很多种,因为应对很多不同的浏览器、服务器、程序等等 分布式开发的基础 必须要装消息队列软件 MSSQ 程序 打开与关闭 windows信息队列

公共队列是 server的 System messaging 创建消息队列 检查 删除 创建 使用 Send发对象 对象被序列化,然后发进去。会查看到一个小信封 还可以在队列中读取消息 但是是被序列话之后的消息 所以必须要做一个反序列化 所以需要指定一个正确的序列化器 这个时候就需要注意一下了 怎么使用序列化器呢? 如何查看我们的信息呢? namespace MessageSample

{

class Program

{

static void Main(string[] args)

{

//也可以使用代码来创建和删除消息队列

if (System.Messaging.MessageQueue.Exists(".\\Private$\\order"))

{

System.Messaging. MessageQueue.Delete(".\\Private$\\order");

Console.WriteLine("已经删除 Order 消息队列");

Console.ReadLine();

}

// 创建

System.Messaging. MessageQueue.Create(".\\Private$\\order");

Console.ReadLine();

// 使用消息队列

System.Messaging. MessageQueue queue

= new System.Messaging.MessageQueue(".\\Private$\\order");

// 发送消息

queue.Send("Hello, world.");

// 以后,可以在队列中读取消息

System.Messaging. Message msg = queue.Receive();

// 消息中保存的是已经序列化之后的信息

// 需要指定正确的序列化器

System.Messaging. XmlMessageFormatter formatter

= new System.Messaging.XmlMessageFormatter(

new System.Type[] {

typeof( string)

Page 120: Csharp

www.happy12.com 010-82387501

}

);

msg.Formatter = formatter;

// 获取信息

string hello = msg.Body as string;

Console.WriteLine(hello);

Console.Read();

}

}

}

查看实际信息 默认是 XML的 那么应用在我们的 petshop中就应该是 在工具中定义好我们用消息队列存储账目的信息的方法,这个时候 是传入的是 OrderModel 那么就要序列化 然后存为消息队列即可 但是insert与 get呢? 是先删除 再新增 而 get呢 是 获取抓取 再转 // 以后,可以在队列中读取消息

System.Messaging. Message msg = queue.Receive();

// 消息中保存的是已经序列化之后的信息

// 需要指定正确的序列化器

System.Messaging. XmlMessageFormatter formatter

= new System.Messaging.XmlMessageFormatter(

new System.Type[] {

typeof( string)

}

);

msg.Formatter = formatter;

// 获取信息

string hello = msg.Body as string;

Console.WriteLine(hello);

Console.Read();

Page 121: Csharp

www.happy12.com 010-82387501

}

}

由同步方式有异步(消息队列)的方式 呵呵 那么怎么处理呢?OrderProcess控制台的程序 还可以利用多线程来进行处理,这个就是里面最复杂的部分

论坛地址: http://www.sisheng.net.cn/forum/forum.php 127、 CSS 倾向于美工 AJAX的出现使得我们程序员也要做了 128、 那么 CSS要用什么来解决问题呢?另存为 网页全部 Doctype, Xhtml全部小写的标记,而且属性必须引号 有了第一行就标准 没有的话工作在怪异模式下。当旧的网页来处理 基本样式 背景色:颜色 白色是#FFFFF 背景图 直接在背景上画一张图 而且还有 repeat分布的样式 Border 边框 1px sold green 显示的时候的盒模型 Margin边界 Border 中心 padding内容与边框的间隔 类前样式表 <style type=””> calss . ID # 大元素就是 body </stylr> <link src type rel> Url相对路径 图片要小用 repeat就好 Table thead 标题 tr td(colspan rowspan 退后原则) th tbody(可以放行,table中必须要有tbody,然后才有行tr) tfoot(脚注,只能出现一次) 由于是大元素 所以只能是全部传输 等待时间比较长 现在基本是div来搞了

现在 table基本是用来显示数据 table设置 broder是自身的 Tdth重叠 就要在 table设置 border collapse:中间那个 优先级别 单独的优先 style 宽度的百分比就是依赖于百分比的 现在看看 div的 auto就是对等 图片的定位 流定位 先画先出 并行地排 流式布局 Style position 相对定位相对父级 position:relative; left:-200px 会与后面的 div自动拉开一个距离 就是原来的保留 但是显示左移 绝对呢/absolutele 还是 right就是,但是是依赖父级容器的,就是说父 position:relative,那是是依赖与父的 我觉得 DIV还是比较适应的 浮动 float;left 下面的 div也是 float:right Div是块元素 自动有一个 br 那么不换行呢? 下面的那个 Span是(行) 块 元素

Page 122: Csharp

www.happy12.com 010-82387501

Div clear 清除浮动 线

论坛地址: http://www.sisheng.net.cn/forum/forum.php Csc编译 CLR 模块 动态链接库 dll exe 会有一个 main 方法 程序的入口 程序集 ILDSM 打开编译完的中间语言的程序,中间语言是完全抽象的虚拟机 完全的中间语言确保了移植性 但是必须要运行在.NET的平台上 上下文的环境 还要有操作系统的环境 操作系统再为你的程序分配资源 、 .NET的程序 比操作系统要高级 .NET的虚拟机要预先启动需要的.NET的程序 但是不是直接加载的 因为 CPU不一样 即时编译器 JST 立即根据 CPU立即翻译 2次编译 CSC是第一次 中间语言 加载的时候 才做 2次编译 根据 CPU 所以有延迟 所以只编译你现在需要执行的那一块 再需要再次编译 使启动的速度加快 缺点就是第一次比较慢,优点是 突破了 CPU的界限 那么就要牺牲了高级语言的特性 根据不同的 CPU编译为不同的执行语言 ILDSM 混淆器 程序的逻辑不变 但是我把程序打乱 保护我们的程序 类型数据类型 就是用 type与真正的数据内存 类型引用标识+值模块 32 64 就不好移植了 那么.NET就做了一个超级的虚拟机 所以类型体系 公共类型体系 CTS object下的 value不一定都是引用类型 那么值类型还是在引用类型下的 Value中有基本类型的类型 都是 sealed不能派生 完全虚拟出来的一套规定 然后在公共语言 CLR再决定我们类型值的使用 但是它是根据 那个类型的标识管理内存的使用 引用的 局部变量 就是栈 没有的就是堆 C#语言 还提供了很多关键字 用语言写程序 但是最后还是 CLR执行 CTS类型 关键字的 等效的 system.object 与 object是有区别的 我们写的 bject一定表示引用类型 所以就出现了 装箱 拆箱 转换的时候就创造了一个箱子 装起来 箱子的类型我们也是不懂的 给 object 中立即装箱 实际运行的时候还是一个引用 i。tostring()其实也已经蕴含了装箱拆箱了。

Page 123: Csharp

www.happy12.com 010-82387501

隐式的装箱 字符+整数 就是隐式的 会检查装箱的类型 都是 CLR来处理的 然后就是 rel与 out的使用的高级使用 还是很嗨的 连接池的问题 好的连接放在池中了 别人不用了 但是别人用了,但是你再取出来用,就不一定还是好的连接了。服务器中断了连接,但是连接池还以为自己还是好的连接, 我们可以复位连接池,这种要在连接池解决,那么重启 IIS,现在由系统解决问题,连接池的问题 还是 IIS 复位一下就好了。 连接池自动响应

论坛地址: http://www.sisheng.net.cn/forum/forum.php

脚本,很简单的程序,而且还没有编译器

今天的主题是Javascript 1995 1.0 ECMA-262 1997

使用script 标签 MIME的文本描述

可以写在head

还可以写在网页代码中

还可以写在脚本文件中 但是还是要在head中写的 <script type=”” src=””></script>

原始值 保存在栈中的基本类型

Undefined 未定义 变量还没赋值的时候 (彻底的不知道)

定义变量的关键字 var

Var I 它的值就是underfine

Alert(i);

判断是否是underfine

Alert(Typeof(i));取得类型但是仅仅是表示类型名的串

If(typeof(i)==”unserfine”)

{

Alert(“未初始化的变量”);

} 直接写

Alert(i); //会显示未定义的异常

那么怎么知道是否已经定义呢?

可以让我们调试脚本文件

Alt

Page 124: Csharp

www.happy12.com 010-82387501

空也是要表示出来的 表示不知道数据库的null C#却是引用类型上的

Js下的null就是引用了空的引用 也是表示不知道 (知道了它是对象)

Var I ;

Var j = null; 输出的结果

Alert(typeof(i)); underfine

Alter(typeof(j)); object

涉及类型转换:Alert(i==jj); true 会涉及到类型的转换 所以这个时候是需要思考思考的

值比较,不允许类型的转换:Alert(i===j);直接比较 不允许类型转换

Boolean null ,underfine ,0都是false

Number是数字

String 字符串 可以用单引号 或 双引号 C#单引号是字符

Javascript是弱类型的语言

Var其实就是一个标记

那么typeof 是看变量值的类型

根据值的类型而决定类型

可以重复定义

Var I =1;

Car I =”1”;

$可以当变量名 _也是可以的 $i _i 这些

引用值:堆中的引用对象(内部有点像字典,字典的key就是成员名字,字典的value就是成员的这个)

基于对象的编程 var obj ={};表示数据的方式 函数式编程语言

没有class

但是定义了之后 我还需要知道里面的成员 属性的啊 但是这里却没有啊

var o = {};

alert(typeof (o));

需要有一个办法 所以在JS环境下 是一个动态的对象 C#是死的

所以是动态添加的

Page 125: Csharp

www.happy12.com 010-82387501

var o = {};

o.name = "我是对象";//立即增加叫name的成员

alert(typeof (o));

判断成员是否存在

1、使用for in遍历对象的成员的名

For (var memberName in O )

{

Result+=memberName+”\n”

}

Alert(result);

2、使用in对象判断是否存在特定的成员

Alert(“name” in O); 返回的是boolean

那么怎么动态删除呢?

Dellete o.name;//直接删除

//1、

alert("name" in o);

for (var member in o)

{

result += member + "\n";

}

alert(result);

//2、添加成员

var result;

o.name = "我是对象的啊"; //立即增加一个叫name的成员

o.age = 21;

alert("name" in o);

for (var member in o) {

result += member+"\n"

}

alert(result);

//3、动态地删除对象

var result;

delete o.name;

alert("name" in o);

for (var member in o) {

result += member + "\n";

}

alert(result);

仿数据 Jquery的核心 Jquery的核心,JQery是类似FCL,一个类库 但是实际上还是js文件

脚本库很多 那么我们怎么使用Jquery呢?这个是需要我们去扎扎实实地学好的。自己写一个Jqery

对js的看法要猛点 真的 最核心的思想 javascript速查手册

就是自己模仿数据,拿对象来仿造数组

var arry = {};

arry["0"] = "zero";

arry["1"] = "one"

arry[2] = "two";

arry.length = 3;

alert("2" in arry);

alert(arry[2]);

对比以前索引器自己搞数组那玩意 JS还是挺好的。

我觉得是拿取了window的length的属性

var arry = {};

arry["0"] = "zero";

arry["1"] = "one"

arry[2] = "two";

arry.length = 3;

arry.length2 = “3”;

alert("2" in arry);

alert(arry[undefined]);

Page 126: Csharp

www.happy12.com 010-82387501

alert(arry[length]);

alert(arry[length2]);这个不执行

引入我的天 window 浏览器下执行的

arry.length1 = 3;改了名后就不执行了

var arry = {};

arry["0"] = "zero";

arry["1"] = "one"

arry[2] = "two";

arry["length1"] = 3;

//arry[length1] = 3;

arry.length1 = 3;

arry.length2;

alert(arry["length1"]);

alert("2" in arry);

获取焦点的问题

执行

找到

得到焦点

先判断ID与name就是控件的存在问题

后执行的时候 要放在后面 次序的问题 要放在后面的啊

<script type="text/javascript">

//找到控件

//ID法 没找到就会返回一个null的空引用

var elem = window.document.getElementById( "search");

if (!elem) {

alert("未能找到元素");

}

else {

elem.();

}

</script>

Html.Hidden(“item参数名.index说明下标”,i.tostring());

还要隐藏起来

而且还对Item【】进行改造

这么拿到呢? 变成list<还是model>

那么就会自动填充 那么我们就可以回去大 列表的下标

下面的就是 下标对象的itemID

那么我们就要明白Javascript的三个大得对象了。

论坛地址: http://www.sisheng.net.cn/forum/forum.php 1、 序列化的问题 反射是序列化的基础 网络传输的序列化一样是要这样子的。二进制、XML 序列化、JSON 序列化,呵呵。系统 Iservirable自定义序列化

2、 MVC分页的大牛 3、 JS函数的概念 函数式语言 对象是表示的方式 函数名 利用函数的名称 来调用函数 由于是弱类型所以前面不能声明 返回值 但是是可以返回值的 不存在就返回 undefine 参数也是没有类型的 变量的类型就是所带的值的类型 function 但是习惯首字母是小写的 <script type="text/javascript">

//找到控件

//ID法 没找到就会返回一个null的空引用

var elem = window.document.getElementById( "search");

if (!elem) {

alert("未能找到元素");

}

else {s

elem.focus();

}

Page 127: Csharp

www.happy12.com 010-82387501

</script>

2+underfine = NaN不是一个数字

4、 形参就是真正的形参,有个形参就会很方便。没 Arguments

<script type="text/javascript">

function add(a, b) {

if(typeof(a)!=Number && typeof(b)!=Number)

{

return a+b

}

else

{

throw "输入的必须是数值类型"

}

}

var result = add(a, 1);

alert(result);

</script>

<script type="text/javascript">

function add1() {

var length = arguments.length;

var a = arguments[0];

var b = arguments[1];

if (typeof (a) != Number && typeof (b) != Number) {

return a + b

}

else {

throw "输入的必须是数值类型"

}

}

</script>

5、 有形参一样可以传递参数 6、 匿名函数 只允许调用一次(没有名字给你调用) <script type="text/javascript">

//匿名函数,()求值取得易用,后面()调用函数

(function () {

alert("Hellow,world.");

})();

</script>

7、 没有 main方法 以为 Script脚本块为单位 从前往后执行 <script type="text/javascript">

function say() {

alert("Hellow,world.");

}

say();

</script>

<script type="text/javascript">

say();

function say() {

alert("Hellow,world.");

}

</script>

都是可以执行的,。因为它会先扫描所有的脚本方法的定义再执行 那么定义两次呢?那么第二次的定义会把第一次覆盖了。 <script type="text/javascript">

sayone();

function sayone() {

alert("我被覆盖了");

}

function sayone() {

alert("Hellw.World");

Page 128: Csharp

www.happy12.com 010-82387501

}

</script>

预定义必须放后面 <script type="text/javascript">

var result = function sayone() {

alert("我被覆盖了");

}

var result = function sayone() {

alert("Hellw.World");

}

sayone();

</script>

那么我们想执行两次呢?就是块的奥义 <script type="text/javascript">

function sayone() {

alert("我没有被覆盖");

sayone();

</script>

<script type="text/javascript">

function sayone() {

alert("Hellow");

sayone();

</script>

你的函数被覆盖了吗? 你现在执行的是哪个函数呢? Alert(sayone);这样就可以直接查看我们写的函数 函数也是对象 <script type="text/javascript">

function sayHello() {

alert("Hello");

}

sayHello();

// 函数是特殊的对象

sayHello.showMessage = function () {

alert("Hi");

};

sayHello.showMessage();

</script>

真正的核心是什么呢? 原型(函数的应用) 对象 B包 这种创造对象的函数一般称为类 , 似类的函数 那么我们就可以写很多底层的类函数, <script type="text/javascript">

//帮助我们创建对象,对于专门用来创建对象的函数首字母要大写

function ArryLike() {

//不需要的

//var arry = {};

//return arry;

//配合new,新的对象就是this,就是一个特殊的参数,其实调用时本身就是函数当前的对象实例

for (var i = 0; i < arguments.length; i++) {

this[i] = arguments[i];

}

//动态创建属性length

this.length = arguments.length;

//C#就是当前对象实例

Page 129: Csharp

www.happy12.com 010-82387501

}

//配合new关键字来使用

var arry = new ArryLike();

//1、new会创建一个新的空对象

//2、将这个对象传递给函数

//3、 返回这个新的对象

</script>

对象的例子 <script type="text/javascript">

function Person(name, age) {

//动态新增的成员

this.name = name;

this.age = age;

}

var alice = new Person("Yan", 22);

alert(alice.name);

</script>

对象的方法呢? 类函数中的方法 采用匿名方法 但是实际上皮特与爱丽丝每一个对应自己的一个 <script type="text/javascript">

function Person(name, age) {

//动态新增的成员

this.name = name;

this.age = age;

this.show = function () {

alert("Name:"+this.name+",Age:"+this.age);

}

}

var alice = new Person("Yan", 22);

alert(alice.name);

alice.show();

</script>

<script type="text/javascript">

function Person(name, age) {

//动态新增的成员

this.name = name;

this.age = age;

this.show = function () {

alert("Name:"+this.name+",Age:"+this.age);

}

}

var Alice = new Person("Alice", 22);

var Perter = new Person("Perter", 22);

alert(Alice.name);

alert(Perter.name);

Alice.show();

Perter.show();

alert(Alice.show == Perter.show);

alert(Alice.show === Perter.show);

</script>

原型的技术终于来了 就是方法共享的机制 其实就是一个名字 对于每一个函数来说 都存在一个称为原型的对象属性,都是这个函数的原型对象 var prototypeObject = Person.prototype;定义函数的时候系统自动帮我们创建出两个对象一个是函数对象 一个叫做原型,会先检查函数对象,再检查原型

对象

只有 New才可以使用这个 <script type="text/javascript">

function Person(name, age) {

//动态新增的成员

this.name = name;

this.age = age;

// this.show = function () {

// alert("Name:"+this.name+",Age:"+this.age);

Page 130: Csharp

www.happy12.com 010-82387501

// }

}

//原型,系统帮我们创造的,目的就是为了共享使用这个函数创建的对象共享

var prototypeObject = Person.prototype;

prototypeObject.show = function () {

alert("Name:" + this.name + ",Age:" + this.age);

}

var Alice = new Person("Alice", 22);

var Perter = new Person("Perter", 22);

alert(Alice.name);

alert(Perter.name);

Alice.show();

Perter.show();

alert(Alice.show == Perter.show);

alert(Alice.show === Perter.show);

</script>

Jquery的来临 实际开发的时候我们还是比较依赖于脚本库的 我们会使用产品级的脚本库 已经到 1.5了 min表示压缩版的版本 因为体积小 所以一般是用这种 Vsdoc适合在开发的时候使用 使用同时加载 $(fnction(){ $(“#id”).html(“Hellow,world.”); $(“li”).html(“Bom!.”);//仿选择器 })这个是 Jq的 ready函数 利用仿数组与原型 就是$是一个得到对象的方法 html是一个类函数中的属性 拿到查找到的元素 去除#号 判断#号 然后就是 遍历 搞值 就是 找元素名称 byTagName innerHtml(“”);这样就好了 <script type="text/javascript">

function jQuery(selecter) {

// selecter 可能是一个 id 的串,也可能是一个元素的名称

if (selecter.charAt(0) == "#") {

// 可以通过 this 得到新创建的对象

// 下面使用仿数组技术,将实际的对象封装起来

// 我们需要通过选择器找到相应的页面元素

var id = selecter.substring(1); //从第几位开始截取字符串,包含第几位

alert(id);

// 通过 id 可以直接找到相应的元素

var element = window.document.getElementById(id);

if (element) { // 判断是否找到了元素

// 仿数组

this[0] = element;

this.length = 1;

}

}

else {

// 元素名称

// 系统提供了通过元素名称来查找元素的方法

var nodeList = window.document.getElementsByTagName(selecter);

// 保存到仿数组

for (var i = 0; i < nodeList.length;i++) {

this[i] = nodeList[i];

}

this.length = nodeList.length;

Page 131: Csharp

www.happy12.com 010-82387501

}

}

// 通过原型共享提供方法

jQuery.prototype.html = function (html) {

alert(this.length);

// 遍历仿数组,其实就是实现了仿数组的传递,但是是利用了this[i]的

for (var i = 0; i < this.length; i++) {

var element = this[i];

element.innerHTML = html;

}

}

// 提供一个名为 $ 的函数,以方便使用

function $(selecter) {

return new jQuery(selecter);

}

$("#msg").html("Hello, world.");

$("li").html("Bom!");

</script>

潜在的父子关系 先在函数对象找 再到原型对象中找 12、 函数原型 13、 也就是说 MVC的Model与 view controller的对应性 14、 ID找 # 元素名 无 class . (点) 15、 创建定时器的编号 是一个长整型 16、 函数的直接 间接 new this是特殊的参数 17、 JS调试 I E9或者是 FF的 Fbug 就可以直接地监视我们的 JS运行的情况 18、

对象 var object ={} 伪数组 []; 还有 var object = new funtionName();可以调用原型 原型 就是 prototype 但是成员必须是调用函数对象 原型就是函数的扩展器 原型也是可以被覆盖的 还可以为已经 new出来的函数对象赋值,动态的嘛 {}其实也是通过 object new出来的 一线脚本语言 B包 形参 构造函数 arguments 与 this 特殊的参数 我们是通过特殊隐式的方式传进去的

Page 132: Csharp

www.happy12.com 010-82387501

怎么拿 this 1、构造函数的对象 2、通过对象的 new This的最近对象性 3、Call 那么这个是可以跨继承函数类的 Var functionName = person.prototype.showme;//拿到对象原型的函数的引用 Fn();//也是有的,但是这个里面的 this是谁?是 Alert(window.name); Alert(window.age); Fn.call(alice,”Hellow”); Call是一个系统方法专门为方法传递 this参数的,第一个参数将被当做 this 从第二个参数开始从方法中被表示,也可以通过普通的形参取得 但是 argument不包括 this的 4、apply区别在于第二个参数必须为数组 用来为 arguments传递 Fn.Apply(alice,[“Hellow”]); 系统提供的类 1、String “I’m String” 可以字符串的类是没有 trim的办法 那么我们就用原型去共享一个 trim方法不就好了 String.pototype.trim- function () { Alert(“trim方法”); //删除字符串的首尾空白 //正则表达式的使用 不连续的 // 中间的内容就是正则表达式 // \s空格 制表符 //+至少有一个,而且有 N个 Var r =/^\s+ /; Var r2 =/ \s+$/; Var r3 = / ^(\s|u00A0)+|\s+$/g;//g前后加全局匹配 排除空白与空行 Return This.replace(r,” ”).replace(r2,” ”); Return (text||” ”)防止 underfine 而微软的是判断 argument.Length !== 其实就是 === } Length 字符串的长度 charAt(int number) 获取字符 索引号 int的 获取单个字符 substring( int number ) 取子串 从索引号 int起的 获取字符以后的所有 slice 2、Date时间类 Var now = new date(); Alert(now.getFullYear()); Alert((now.getMonth ()+1));//Java索引 所以必须加 1 Alert(now.getDate());//31日 计时器 创建一个定时器,每隔一个固定的时间间隔就执行一段代码 Var timerID = Windows.setInterval( Function () {

Var now = new date(); Var show = windows.document.getElementID(“clock”); If(show!=null) { Show.innerHTML = now.getMonth(); } },1000); //ms //关闭定时器,要保留定时器的 ID //Windows.clearInterval(timerID); 利用 button onclick=”windows.clearInternal(timerID);” <script type="text/javascript">

var timerID = window.setInterval(

function () {

var time = new Date();

var showObject = window.document.getElementById( "clock");

if (showObject != null) {

Page 133: Csharp

www.happy12.com 010-82387501

showObject.innerHTML = time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate() + " " + time.getHours() + ":" +

time.getMinutes() + ":" + time.getSeconds();

}

}, 1000

)

</script>

<input type="submit" onclick="window.clearInterval(timerID);" value="停止" />

3、系统函数 Arry数组 常用的函数 Concat Join Push Pop Reverse Shift Slice Sort Splice Unshift <script type="text/javascript">

//得到数组对象

var arry = []; //相当于new arry

//不用考虑长度

arry[0] = "0"//类似字典

alert(arry.length);

arry[100] = "100"//类似字典

alert(arry.length);//101

alert(arry.join(",")); //拼接

var str = "1,1,1,2,";//5个逗号就是5了,那么就要正则去掉,号

var arry = str.split(",");

alert(arry.length);

</script>

AJAX入门 把 sumit变成 普通的 button 根本就不会提交 那么就写 就是拼串的问题 <form id="form1">

<%-- <input type="text" value="获取焦点" id="search" name="search"/>-- %>

<%--<input type="submit" onclick="window.clearInterval(timerID);" value=" 停止" />--%>

<input name="username" type="text" /><br />

<input name="email" type="text" /><br />

<input type="button" onclick="submit2()" value="提交" />

</form>

</div>

<script type="text/javascript">

function submit2() {

alert("自定义的提交");

//username= & email=

//拼接的数组

var paras=[];

//自己拼接

//取得form1

var form = window.document.getElementById( "form1");

//取form1的input的元素

var node = form.getElementsByTagName( "input");

//查找筛选出对应的元素

for (var i = 0; i < node.length; i++) {

var element = node[i];

if ( element.name) {

var value = element.value;

var key = element["name"] + "=" + value;

alert(key);

paras[paras.length] = key;

}

Page 134: Csharp

www.happy12.com 010-82387501

}

alert(paras.join( "&"));

}

</script>

数组的另外两个应用 堆栈 、队列使用 堆栈 是常用的数据结构 可以直接使用数组来完成 就是用了 push压 与 pop浮 <script type="text/javascript">//方法1

var arry = [];

//堆栈,先进后出 放←

arry.push("Zero");

arry.push("One");

alert(arry.join("-"));

while (arry.length > 0) {

alert(arry.pop());

}

</script>

<script type="text/javascript">//方法2

var stack = [];

//往前面放 放→

stack.unshift("0");

stack.unshift("1");

stack.unshift("2");

alert(stack.join("-"));

while (stack.length > 0) {

alert(stack.shift());

}

</script>

<script type="text/javascript">

//队列一端进,一端出

var queue = [];

queue.push("Zero");

queue.push("One");

queue.push("Two");

//令一端取出

while (queue.length > 0) {

alert(queue.shift());

}

</script>

<script type="text/javascript">

//队列一端进,一端出

var queue = [];

queue.unshift("Zero");

queue.unshift("One");

queue.unshift("Two");

//令一端取出

while (queue.length > 0) {

alert(queue.pop());

}

</script>

排序 <script type="text/javascript">

var list = [1, 2, 3, 5, 6, 2, 4,6];

//那么为了按数字来,那么就要告诉它一个函数 自定义 能够比较两个数据大小的函数

//通用原则: 返回大于0 表示前面大 ; 返回小于0 ,表示后面大;返回0表示相等

list.sort(function (a, b) {

return a - b;

}); //升序(按字符串排)

list.reverse(); //逆转位置

Page 135: Csharp

www.happy12.com 010-82387501

alert(list.join("-"));

//那么字符串呢? 98 900 78 76

</script>

那么怎么做 set呢?拿对象的属性名。 This的 5种用法

论坛地址: http://www.sisheng.net.cn/forum/forum.php 129、 fn是 JQ的原型对象

130、 JQ原型 对象 仿数组

131、 很难写一个脚本程序在不同的浏览器上跑 不像.NET的补齐 所以太悲催了。这样 JQ标准库诞生了。

132、 用一种方式写出浏览器都能跑的程序 使用很容易,设计很复杂 相当于 JS上的 Framework架构

133、 Window对象相当于我们的上帝 无所不在无所不能

C#实际上是没有全局变量之说的,因为却是还是有范围的。

但是 JS是有的 叫做全局对象 global object 它就是 window 其实就是浏览器

定义的东西要是不装的话,就会变成全局变量

Function(){}

Window.hellow();

Var msg

Alert(Window.meg);

计时器

保存 ID 数据、方法加事件

闭包全局的

This的问题 不再是自身的方法了,现在变成了 window了

什么是闭包 closure 函数优先的前提下解决我们的参数从属性的问题

定义变量

定义函数 (改变变量)

window执行函数

alert 变量的新值

整体的 window 就会隐式地传递到函数中 其实就是 JS的内部的函数 调用机制 函数执行的环境整个就会变成一个传递的对象

那么返回一个函数引用呢

Var fn = out();

Fn();..还是可以操作的,会记住我们的上下文的环境,即使我 return还是会记住的

即是执行的时候不但有 全局环境对象,还有局部的环境对象 每个对象的 inner指向的是对象自己的 inner对象

连续执行两次 fn(); 是不变的 即是指向相同的局部环境内存对象

针对这个函数的状态对象

闭包实际上就是函数执行私有状态的保护 也就是利用 var This = this; 截取保存当时的对象 <script type="text/javascript">

function outer() {

var i = new Date().getSeconds();

function inner() {

alert(i);

}

return inner;

}

var fn = outer();

fn();

alert("Wait!!");

fn();

程序原版 <script type="text/javascript">

//TimeClass

function Timer(interval, callback) {

Page 136: Csharp

www.happy12.com 010-82387501

this.timerID = -1; //no timer entity

//make sure the timespan

this.interval = interval | 1000;

//current number

this.current = 0;

//save the call method

this.callback = callback;

}

//TimerClass prototy

Timer.prototype = {

//public method start

"start": function () {

//check the timerID

if (this.timerID !== -1) {

throw "已经在使用定时器,必须先删除原来的定时器"; // throw a misstake

}

//else run the window's setInterval method

this.timerID = window.setInterval(

this.fn,

this.interval

);

},

"stop": function () { },

"reset": function () { },

"pause": function () { },

"resume": function () { },

"fn": function () {

this.current = this.current + 1;

this.callback();

}

};

var timer1 = new Timer(3000, function () {

alert("Hellow");

})

timer1.start();

</script>

闭包改造 <script type="text/javascript">

//TimeClass

function Timer(interval, callback) {

this.timerID = -1; //no timer entity

//make sure the timespan

this.interval = interval | 1000;

//current number

this.current = 0;

//save the call method

this.callback = callback;

}

//TimerClass prototy

Timer.prototype = {

//public method start

"start": function () {

//check the timerID

if (this.timerID !== -1) {

throw "已经在使用定时器,必须先删除原来的定时器"; // throw a misstake

}

//closure for the setInterval,record the old entity

var This = this;

//else run the window's setInterval method

Page 137: Csharp

www.happy12.com 010-82387501

this.timerID = window.setInterval(

function(){

This.fn();},

this.interval

);

},

"stop": function () { },

"reset": function () { },

"pause": function () { },

"resume": function () { },

"fn": function () {

this.current = this.current + 1;

this.callback();

}

};

var timer1 = new Timer(3000, function () {

alert("Hellow");

})

timer1.start();

</script>

The last version <script type="text/javascript">

//TimeClass

function Timer(interval, callback) {

this.timerID = -1; //no timer entity

//make sure the timespan

this.interval = interval || 1000; //or

//current number

this.current = 0;

//save the call method

this.callback = callback;

}

//TimerClass prototy

Timer.prototype = {

//public method start

"start": function () {

//check the timerID

if (this.timerID !== -1) {

throw "已经使用定时器,必须先删除原来的定时器";

timer1 = -1;

}

//closure for the setInterval

//make sure after the first time run , the this is not the window entity

//This is the start method entity

var This = this;

//else run the window's setInterval method

this.timerID = window.setInterval(

function () {

This.fn(); //the code for run

},

this.interval//get the current number

);

},

"stop": function () {

if (this.timerID !== -1) {

alert("停止");

window.clearInterval( this.timerID);

this.timeID = -1;

}

Page 138: Csharp

www.happy12.com 010-82387501

},

"reset": function () { },

"pause": function () { },

"resume": function () { },

"fn": function () {

this.current = this.current + 1;

this.callback(this.current);

}

};

var block = window.document.getElementById( "float");

var timer1 = new Timer(100, function (count) {//create entity,contain the fields

block.style.left = count + "px";

if (count > 800) {

timer1.stop();

}

}).start();// run the class prototype method

</script>

其实就用利用外部全局变量传递 this进来 JS是一个动态的语言 所以要用动态的思想去解决问题

一般就是用 JS对 Form的元素进行改造

DOM树 文档对象模型 针对 HTML XML基于树形结构的 API 编程接口 表示成为一个内存中的节点树

进而修改里面的内容

DOM树的根节点

就是找到元素的根节点 就这样 事件的名称全部是小写的 事件的对象是谁?

IE event = event || windows.Event

还要找到父节点 兄弟点 remove create DOM编程的基本原理

MSDN的 DOM图

Nodes

Next

Previous

Childnodes

Appendchild

insertChild 等等

还有一种就是 innerHTML的方式

但是要预先写好元素 但是要到后期 才给予文本 而且还可以直接写标记 写的是很嗨的东西

把文字再解析成节点

豆瓣验证

太多久不好办了 你说对不对?

每个程序直接使用 而且使用的时候越简单越好 这种就是脚本库

介绍一下怎么写呢?我们能不能自己

如何使用 JQ

加载 JS文件

$(function(){

$(“#form1”).Validate();”

})

元素可以是 可以借用 class class=”required”

可以做很多高级的操作

还可以在

$(function(){

$(“#form1”).Validate(

//自定义操作,传递一个对象

{

Rules:{ username: “required”,}

}

);”

})

交互的是 remote

Page 139: Csharp

www.happy12.com 010-82387501 那么以后我们就是

防止提交

Syccess 设置标签的类

很完善的验证库

JQ的 Validation

明天讲扩展与 AJAX

点的时候 弹出功能

离开的时候 弹出必须

1、 AJAX 允许在不干扰 web应用程序的显示和行为的情况下载 hour爱进行数据检索 使用 XMLHttpRequest函数获取数据 它是一个 API AJAX 是很多mashuo

的驱动力,可以将来自很多地方的内容集成为单一的 web应用程序。

2、 客户端执行的程序太悲催了 以前只能是对DOM树的操作, 那么我们想再不刷新页面的时候就可以看到网页的数据的更新 但是是有限制的 Java的沙箱模型 限

制浏览器的 Java操作 不支持文件系统操作 但是支持网络操作。由于 Java实在太慢了 ,所以悲剧了。

3、 后来出了 flash 插件 ActionFlash flash的编程语言 视频播放是拿 flash做的

4、 然后就有 Exchange Server 进行无缝沟通 集合性的邮件管理系统 现在增加了两个关键性的组件来支持与服务器的通讯和 XML的处理

包括:outLook客户端(本地程序,自己向服务器询问邮件情况) 标准配置 专门做一个 web的邮件界面

5、但是现在的浏览器呢?不能了,现在必须是不刷新就知道更新 那么微软怎么应对呢?IE 浏览器 的两个组件 XMLHttpRequest 允许脚本与服务器进行

XMLDOM 由于但是 XML被认为是我们日后数据通讯的未来,超文本数据 但是 XML还是比较繁琐的 使用比较少

6、JSON Javascript 服务器通讯组件 XMLHttpRequest 负责服务器进行通讯的组件 XHR 其他的服务器都集成了 但是名称会有所不同

7、创建 XHR判断

Var xhr;

If(window.XMLHttpRequest)//IE

{

Xhr = new XMLHttpRequest();

}

Else if (window.ActiveXObject)//FF

{

Xhr = new ActiveXObject(“Msxml2.XMLHTTP”);

}

Else

{

Throw new Erro (“AJAX is not supported. ”);

}

<script type="text/javascript">

var xhr;

if (window.XMLHttpRequest) {

xhr = new XMLHttpRequest();

alert(xhr + "的XMLHttpRequest");

}

else if (window.ActiveXObject) {

xhr = new ActiveXObject("Microsoft.XMLHTTP");

alert(xhr + "的Microsoft.XMLHTTP");

}

else {

throw new Error ("no supported AJAX");

}

</script>

0、取得请求对象

Xhr = new XMLHttpRequest(); 或者 xhr = new ActiveXObject();

1、设置请求

Open method url async true异步 flase同步(等待回发完才操作)

2、发送请求

Send(content);

3、请求状态的变化的事件

Onreadystateexchange 触发事件 什么时候变化呢?从 0到 4 发出请求 收到回应 全部收到 …….到 4的时候全部完成 4、

返回文本内容属性

reponseText 文本流的方式回发文本

4、返回 XMLDOM

responseXML

<script type="text/javascript">

var xhr;

if (window.XMLHttpRequest) {

xhr = new XMLHttpRequest();

alert(xhr + "的XMLHttpRequest");

}

Page 140: Csharp

www.happy12.com 010-82387501

else if (window.ActiveXObject) {

xhr = new ActiveXObject("Microsoft.XMLHTTP");

alert(xhr + "的Microsoft.XMLHTTP");

}

else {

throw new Error("There id no AJAX's supported " );

}

alert(xhr.readyState); //0 准备阶段,刚刚拿取到XMLHttpRequest对象

//设置

xhr.open("GET", "Home/Hello"); //method、url、type

//发出请求

alert(xhr.readyState); //1

xhr.send(null); //GET Null ;SEND Parmetrers

alert(xhr.readyState); //1

//发生改变的时候

xhr.onreadystatechange = function () {

alert(xhr.readyState); //2

if (xhr.readyState == 4) {

alert("请求处理完成。");

if (xhr.status == 200) {

//http状态为200为服务器成功处理

var result = xhr.resposeText; //需要规定好格式

var element = window.document.getElementById( "h1");

element.innerHTML = result;

//实际上网页的源文件还是没有变的,就是说本质的东西是没有改变的

}

}

}

</script>

JQ的解决方案

<script type="text/javascript">

//初始化

$(function () {

$("#h1").load("/Home/Hello");

})

</script>

JQ远程验证

两个的引用 基本库 与 验证库 (有顺序的)

Remote:”user.php ServerName”

Echo回发

JSON 是 Javascript 用于浏览器与服务器之间交换信息的轻量级数据格式(与 XML比较) 比 XML方便 但是没 XML那么严格的架构与齐备的工具

实际上是一个串 但是可以理解 Eval转换为对象

依赖与 JS工程师

用 JSON把串给浏览器 浏览器获取对象

<head runat="server">

<title>Index</title>

<script type="text/javascript">

//服务器拿到的JSON串

var json = '{ "name":"Alice","address":{ "city": "BeiJing","street": " 长安街"}};';

alert(json);

//在JS中可以很方便讲JSON转换成对象;

var data = eval("("+json+")");

alert(data);

</script>

</head>

<body>

<div>

</div>

//借助视图JsonPage访问Json数据

public ActionResult JsonPage()

{

return this.View("JsonPage");

Page 141: Csharp

www.happy12.com 010-82387501

}

//返回JSON格式的数据

public ActionResult JSON()

{

//服务器上数据使用对象表示

var json = new

{

name = "Alice",

address = new

{

city = "BeiJing",

street = "长安街"

}

};//C#创建对象,匿名类,不需要对象实例,编译器为我写一个类

return this.Json(json, JsonRequestBehavior.AllowGet);

//不允许用Get方式

}

<body>

<h1 id="city">

</h1>

<script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>

<script type="text/javascript">

$(function () {

$.getJSON("/Home/JSON",//服务器URL

{},//发送服务器的键值对,参数呢?怎么写?

$(“#city”).change( function(){

Var cal = $(this).val();

//{code:val},function(data){

For (var name in data){

Vat text = data.value;

}

})

function (data) {//CallBack时调用的函数

$("#city").html(data.name);//配置对应html中元素的内容

});

})

alert("JSON执行了。");

</script>

</body>

JSONP 即是 同源(防止) 跨域

什么是跨域的问题

由于受到浏览器的限制,该方法不允许跨域通信。如果尝试从不同的域请求数据,会出现安全错误,即是不允许跨网站抓取数据。如果能控制数据驻留的远程服务器并且

每个请求都前往同一域,就可以避免这些安全错误。但是,如果仅停留在自己的服务器上,Web 应用程序还有什么用处呢?如果需要从多个第三方服务器收集数据时,

又该怎么办?

结合 JSON与 JS的 SRC可以实现抓取数据实现 callback的效果(应用的例子:百度地图 API的开放)

什么是同源的问题

同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。(即是不允许加载自身域的脚本而且不允许操作其他域的文档属性,即是自身不加载脚本,不能

操作他人的数据,但是可以获取)也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。

这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。

解决办法 1

克服该限制的一个相对简单的方法是让 Web 页面向它源自的 Web 服务器请求数据,并且让 Web 服务器像代理一样将请求转发给真正的第三方服务器。

即是所有的服务放在自身请求的那个域

解决办法 2

克服该限制更理想方法是在 Web 页面中插入动态脚本元素,该页面源指向其他域中的服务 URL 并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行

的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供 Web 页面的域上加载的。

利用 JS的 SRC请求获取数据 data,而且把 callback也送去注册挂连,那么就可以既获取数据,也能对数据进行操作。

具体操作

同源策略不阻止将动态脚本元素插入文档中。也就是说,可以动态插入来自不同域的 JavaScript,并且这些域都携带 JSON 数据。这其实是真正的 JSONP(JSON with

Padding):打包在函数调用中的 JSON 数据。

为了完成该操作,Web 页面必须在插入时具有已经定义好的回调函数

脚本是在浏览器执行的 所以还要解决跨域问题 就是我们的网页是从哪里来的

只允许访问本网站 本域的资源 跨域的问题

就是解决拿取其他网页的

抓网页 太悲剧了

Page 142: Csharp

www.happy12.com 010-82387501 但是效率很低 但是要在浏览器就好好解决

解除同源限制 允许我们执行那个网站的脚本程序 把请求脚本库的访问写在浏览器 让它访问其他公司 CDM 内容分发服务器 跨网站跨域的数据共享

需要配合 简称叫做 JSONP

同源策略不制止将动态脚本元素加入

两个网站的例子

用 src就好 当时那个返回的是脚本 是正确的脚本

脚本可以突破同源的问题

就是返回的 Action的设置 利用 JSON与 SRC 实现破解同源限制

怎么拿到数据呢??

就是服务提供商 返回的是一个 data (对象)

浏览器直接这样使用对象

Var name = data.name;

能不能处理我们的 callback

服务器端生成一个 JS调用 然后传到浏览器

在浏览器还要写一个 callback的问题

那么这个时候就是 src 集合

解决问题的问题 ? callback=showName

但是服务器还是要搞得 funcitonName = this.request[“callback”]

JSONP大多数都是 JSONP的服务 那么我们的服务器就会变得轻松

JQ解决方案

“URL?callback=?”,function(data){写操作的函数}

这些就是公开的服务

缺点构建组合页面的强悍技术 脚本就可以组合页面

但是也不是万能的,没有任何错误的处理 成功就成功 失败就静默

xhr string

json string (但是可以是对象)

jsonp string (可以跨网站跨抓,就是传说中的 API )

这个是服务器 返回的是拼接好的 JSON语句

public string Json()

{

string json = " {'name':'Beijing'} ";

return json;

}

//加强版

public string Index( )

{

//回发函数

string functionName = this.Request["callback"];

//Json数据对象字符串

string json = " {'name':'Beijing'} ";

// 对于服务器而言,仅仅是一个串,可以返回脚本程序

string js =

string.Format(

"{0}( {1} );",

functionName,

json

);

return js;

}

这个是浏览器

<script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>

<script type="text/javascript">

function callback() {

alert("callback被执行,可以进行页面数据的绑定");

}

</script>

<%--<script type="text/javascript">

$(function () {

$.getJSON("/Home/JSON", //服务器URL

{}, //发送服务器的键值对

function (data) {//CallBack时调用的函数

$("#city").html(data.name); //配置对应html中元素的内容,解读eval了

});

})

Page 143: Csharp

www.happy12.com 010-82387501

alert("JSON执行了。");

</script>--%>

<script type="text/javascript">

alert("JSOP");

$(function () {

$.post("http://loca lhost:49299/Service/Index?callback=?", null, call back, "string");

})

alert("执行完毕。");

</script>

长连接 含义:断开之后 数据库变化呢 不断开连接 实现没延迟的更新 那么继续触发新的连接

服务器端

下午再讲下拉列表框的问题

下拉列表框

<select size=”控制一次显示多少个” mutifual=”是否允许多选” onchange=”functionName”>

<option value=“010“>北京市</option>

</select> 看看它的事件 写一个函数处理处理

functionName

里面还是要 event的

Var source=event.srcElement;列表框 Dhtml手册 完全手册 还有各种方法 对象 style对象

selectIndex 位于的位置

var option = source.options[source.selectIndex]

option.value 那么我们怎么做级联列表框呢?

那么就需要为 select设置 ID的了

<option selected=”selected”>请选择</option>

全部 JQ的话 就是要 先注册事件

Change(function(){

<body>

<h1 id="city">

</h1>

<script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>

<script type="text/javascript">

$(function () {

$.getJSON("/Home/JSON",//服务器URL

{},//发送服务器的键值对,参数呢?怎么写?

$(“#city”).change( function(){

Var cal = $(this).val();

//{code:val},function(data){

For (var name in data){

Vat text = data.value;

}

})

function (data) {//CallBack时调用的函数

$("#city").html(data.name);//配置对应html中元素的内容

});

})

alert("JSON执行了。");

</script>

</body>

})

添加的方法

Var element = $(“#ID”)[0];

Element.options.length=0;

For (var name in data){

Vat text = data.value;

Var text=data[value];

Car option = new option (text,value);

还有一种清空的方法就是找到就是 Empty();

那么怎么一块更新呢?

Option一块创建好

Page 144: Csharp

www.happy12.com 010-82387501

Var arry =[]; //拼接成串

For (var name in data){

Vat text = data.value;

然后 innerHTML就好了

<script type="text/javascript">

$(function () {

// 注册 select 的 change 事件处理

$("#city").change(function () {

var val = $(this).val(); // 获取 select 当前的值

$.getJSON( "/Home/GetAreaList", { "code": val }, function (data) {

// var element = $("#areaList")[0];

// element.options.length = 0;

// 遍历对象的属性

// for (var value in data) {

// var text = data[value];

// var option = new Option(text, value);

// element.options[element.options.length] = option;

// }

$( "#areaList").empty();//清空控件元素

var array = [];

for (var value in data) {

var text = data[value];

array.push( "<option value='" + value + "'>" + text + "</option>");

}

$( "#areaList").html(array.join());//直接使用拼接的标记元素

});

});

}

);

</script>

服务器端

public ActionResult GetAreaList(string code)

{

Dictionary<string, string> dict = new Dictionary<string, string>();

switch (code)

{

case "010":

dict.Add("001", "海淀区");

dict.Add("002", "东城区");

dict.Add("003", "西城区");

dict.Add("004", "朝阳区");

break;

case "021":

dict.Add("001", "浦东区");

break;

case "012":

dict.Add("001", "滨海区");

break;

case "013":

dict.Add("001", "重庆区");

break;

}

return this.Json(dict, JsonRequestBehavior.AllowGet);

}

论坛地址: http://www.sisheng.net.cn/forum/forum.php

19、 技术标签:(C# sealed 使用实例)

20、 技术细节:(sealed修饰符的具体使用环境)

sealed:当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承。在下面的示例中,类 B 从类 A 继承,但是任何类都不能从类 B 继承。。

Page 145: Csharp

www.happy12.com 010-82387501

目的:阻止修饰的类被继承。还可以在重写基类中的虚方法或虚属性的方法或属性上使用 sealed 修饰符。这将使您能够允许类从您的类继承,并防止它们重写特定的

虚方法或虚属性。在下面的示例中,C 从 B 继承,但 C 无法重写在 A 中声明并在 B 中密封的虚函数 F。

21、 技术实例:(C# sealed修饰符)

1、一般情况(修饰类)

class A {}

sealed class B : A {}

2、特殊情况(修饰函数)

class A

{

protected virtual void F() { Console.WriteLine("A.F");}

protected virtual void F2() { Console.WriteLine("A.F2");}

}

class B : A

{

sealed protected override void F() { Console.WriteLine("B.F");}

protected override void F2() {Console.WriteLine("A.F3");}

}

class C : B

{

// Attempting to override F causes compiler error CS0239.

// protected override void F() { Console.WriteLine("C.F"); }

// Overriding F2 is allowed.

protected override void F2() { Console.WriteLine("C.F2"); }

}

论坛地址: http://www.sisheng.net.cn/forum/forum.php

134、 技术标签:(单例模式 Singleton 使用实例)

135、 技术细节:(单例模式 的具体使用环境)

简介:只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。Singleton模式要求一个类有且仅有一个

实例,并且提供了一个全局的访问点。这就提出了一个问题:如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?客户程序在调用某一个类时,它是不会

考虑这个类是否只能有一个实例等问题的,所以,这应该是类设计者的责任,而不是类使用者的责任。即是单例模式,类的设计是关键。从另一个角度来说,Singleton

模式其实也是一种职责型模式。因为我们创建了一个对象,这个对象扮演了独一无二的角色,在这个单独的对象实例中,它集中了它所属类的所有权力,同时它也肩负了

行使这种权力的职责!一般我们可以将事务处理类设置成为单例,然后把每个小的任务设置到一个任务序列里。即是关键的事务类我们必须设置是单例的静态类。显然单

例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

业务分析:在下面的对象图中,有一个"单例对象",而"客户甲"、"客户乙" 和"客户丙"是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而

且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。

应用:在计算机系统中,需要管理的资源包括软件外部资源,譬如每台计算机可以有若干个打印机,但只能有一个 Printer Spooler, 以避免两个打印作业同时输出到

打印机中。每台计算机可以有若干传真卡,但是只应该有一个软件负责管理传真卡,以避免出现两份传真作业同时传到传真卡中的情况。每台计算机可以有若干通信端口,

系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。需要管理的资源包括软件内部资源,譬如,大多数的软件都有一个(甚至多个)属性

(properties)文件存放系统配置。这样的系统应当由一个对象来管理一个属性文件。需要管理的软件内部资源也包括譬如负责记录网站来访人数的部件,记录软件系统

内部事件、出错信息的部件,或是对系统的表现进行检查的部件等。这些部件都必须集中管理,不可政出多头。这些资源管理器构件必须只有一个实例,这是其一;它们

必须自行初始化,这是其二;允许整个系统访问自己这是其三。因此,它们都满足单例模式的条件,是单例模式的应用。

实现要点:

Singleton模式是限制而不是改进类的创建。

类中的实例构造器可以设置为 Protected以允许子类派生。

一般不要支持 Icloneable接口,因为这可能导致多个对象实例,与 Singleton模式的初衷违背。

一般不要支持序列化,这也有可能导致多个对象实例,这也与 Singleton模式的初衷违背。

Singleton只考虑了对象创建的管理,没有考虑到销毁的管理,就支持垃圾回收的平台和对象的开销来讲,我们一般没必要对其销毁进行特殊的管理。

Page 146: Csharp

www.happy12.com 010-82387501

理解和扩展 Singleton模式的核心是“如何控制用户使用 new对一个类的构造器的任意调用”我觉得有点像 Spring.Net。

可以很简单的修改一个 Singleton,使它有少数几个实例,这样做是允许的而且是有意义的。

优点 :

实例控制:Singleton 会阻止其他对象实例化其自己的 Singleton 对象的副本,从而确保所有对象都访问唯一实例

灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程 ,而且利用下面的 4 或者是 5的例子是可以提升大概 1%的系统性能。

缺点 :

开销:虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题,上面的五种实现方式中已经

说过了。

可能的开发混淆:使用 singleton 对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用 new 关键字实例化对象。因为可能无法访问库源代码,因此

应用程序开发人员可能会意外发现自己无法直接实例化此类。

对象的生存期:Singleton 不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于 .NET Framework 的语言),只有 Singleton 类能够导致实例被取消

分配,因为它包含对该实例的私有引用。(即是一出生就到程序死亡,但是我们可以在类的内部定义方法让它消亡)在某些语言中(如 C++),其他类可以删除

对象实例,但这样会导致 Singleton 类中出现悬浮引用。

适用性 :

当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例(即是此实例纯纯调用Object obj = Singleton5.Instance as

Singleton5;)时。

应用场景:

每台计算机可以有若干个打印机,但只能有一个 Printer Spooler,避免两个打印作业同时输出到打印机。

(摘自吕震宇的 C#设计模式(7)-Singleton Pattern)

PC机中可能有几个串口,但只能有一个 COM1口的实例。

系统中只能有一个窗口管理器。

.NET Remoting中服务器激活对象中的 Sigleton对象,确保所有的客户程序的请求都只有一个实例来处理。

单例模式与静态方法的比较:

观点一:(单例类 sealed),一句话,单例类可以面向对象设计,而且适合比较繁多的事务,因为静态方法不会持续地初始化与释放,对内存的处理比较消耗。。

单例模式比静态方法有很多优势:首先,单例可以继承类,实现接口,而静态类不能(可以集成类,但不能集成实例成员);

其次,单例可以被延迟初始化,静态类一般在第一次加载是初始化(都懂的);

再次,单例类可以被集成,他的方法可以被覆写;

最后,或许最重要的是,单例类可以被用于多态而无需强迫用户只假定唯一的实例。举个例子,你可能在开始时只写一个配置,但是以后你可能需要支持超过一个配置集,

或者可能需要允许用户从外部从外部文件中加载一个配置对象,或者编写自己的。你的代码不需要关注全局的状态,因此你的代码会更加灵活。观点二:(静态方法 static)

会随着方法的完毕而完毕,在执行方法的时候是不会实例化所在的类的,占据内存不会被删,除非程序结束,占用内存

静态方法中产生的对象,会随着静态方法执行完毕而释放掉,而且执行类中的静态方法时,不会实例化静态方法所在的类,即是只会执行方法,而不会实例化类对象。如

果是用 singleton, 产生的那一个唯一的实例,会一直在内存中,不会被 GC清除的(原因是静态的属性变量不会被 GC清除),除非整个程序(程序执行完毕)退出了。

这个问题我之前也想几天,并且自己写代码来做了个实验。

观点三:(Good!)

由于 DAO的初始化,会比较占系统资源的,如果用静态方法来实现,会不断地初始化和释放,所以我个人认为如果不存在比较复杂的事务管理,用 singleton会比较好。

总结:

个人认为:

1、内存占用上,都一样。

2、垃圾回收上,静态方法回收及时,但是对内存的操作过多,单例由于存在静态类变量,是随同 JVM、CLR的消失而消失的

所以,不涉及事务时,方法使用率高用静态方法,类的使用率高则用单例类

136、 技术实例:(单例模式)

52、 利用内部对象进行单例

这种方式的实现对于线程来说并不是安全的,因为在多线程的环境下有可能得到Singleton类的多个实例。

如果同时有两个线程去判断(instance == null),并且得到的结果为真,这时两个线程都会创建类Singleton的实例,这样就违背了Singleton模式的原则。实际上在

上述代码中,有可能在计算出表达式的值之前,对象实例已经被创建,但是内存模型并不能保证对象实例在第二个线程创建之前被发现。

namespace 单例模式

{

// 1、第一种模式

// sealed即是无法继承该修饰的类

public sealed class Singleton1

{

//对自身里面的类进行单例化

static Singleton1 instance = null;

Singleton1(){ }

Page 147: Csharp

www.happy12.com 010-82387501

public static Singleton1 Instance

{

get

{

if (instance == null)

{

instance = new Singleton1();

}

return instance;

}

}

}

}

优点:1、由于实例是在 Instance 属性方法内部创建的,因此类可以使用附加功能(例如,对子类进行实例化),即使它可能引入不想要的依赖性。

2、直到对象要求产生一个实例才执行实例化;这种方法称为“惰性实例化”。惰性实例化避免了在应用程序启动时实例化不必要的 singleton

2、线程安全型

这种方式的实现对于线程来说是安全的。我们首先创建了一个进程辅助对象,线程在进入时先对辅助对象加锁然后再检测对象是否被创建,这样可以确保只有一个实例被

创建,因为在同一个时刻加了锁的那部分程序只有一个线程可以进入。这种情况下,对象实例由最先进入的那个线程创建,后来的线程在进入时(instence == null)

为假,不会再去创建对象实例了。但是这种实现方式增加了额外的开销,损失了性能。

namespace 单例模式

{

//禁止继承

public sealed class Singleton2

{

static Singleton2 instance=null;

static readonly object padlock = new object();

Singleton2()

{ }

//实例是在 Instance 属性方法内部创建的,因此类可以使用附加功能

//(例如,对子类进行实例化),即使它可能引入不想要的依赖性

public static Singleton2 Instance

{

get

{

//所有的线程在访问的时候先访问这里,但是这里会先lock一个线程,即是只给一个进程进行访问,然后再实例化,

//这样就确保了不会出现惰性实例化了,用readonly于lock同时控制

lock (padlock)

{

if (instance==null)

{

instance = new Singleton2();

}

return instance;

}

}

}

}

}

3、双重加锁

这种实现方式对多线程来说是安全的,同时线程不是每次都加锁,只有判断对象实例没有被创建时它才加锁,有了我们上面第一部分的里面的分析,我们知道,加锁后还

得再进行对象是否已被创建的判断。它解决了线程并发问题,同时避免在每个 Instance 属性方法的调用中都出现独占锁定。它还允许您将实例化延迟到第一次访问对

象时发生。实际上,应用程序很少需要这种类型的实现。大多数情况下我们会用静态初始化。这种方式仍然有很多缺点:无法实现延迟初始化。

namespace 单例模式

{

sealed class Singleton3

{

static Singleton3 instance=null;

static readonly object padlock = new object();

Singleton3()

{ }

public static Singleton3 Instance

{

get

{

if (instance==null)

Page 148: Csharp

www.happy12.com 010-82387501

{

lock (padlock)

{

if (instance==null)

{

instance = new Singleton3();

}

}

}

return instance;

}

}

}

}

4、静态初始化

在此实现中,将在第一次引用类的任何成员时创建实例。公共语言运行库 CLR负责处理变量初始化。该类标记为 sealed 以阻止发生派生,即是由于阻止了派生,所以

无法派生获取实例,只能是利用 readonly关键字下的类构造函数的初始化与类的静态初始化来引起实例。此外,变量标记为 readonly,这意味着只能在静态初始化期

间(此处显示的示例)或在类构造函数中分配变量。

不同之处在于它依赖公共语言运行库 CLR来初始化变量。它仍然可以用来解决 Singleton 模式试图解决的两个基本问题:全局访问和实例化控制。(此处使用的难题分

析法)公共静态属性为访问实例提供了一个全局访问点。此外,由于构造函数是私有的,因此不能在类本身以外实例化 Singleton 类;因此,变量引用的是可以在系统

中存在的唯一的实例。

由于 Singleton4 instance 实例被私有静态成员变量引用,因此在类首次被对 Instance 属性的调用引用之前,不会发生实例化。

这种方法唯一的潜在缺点是,您对实例化机制的控制权较少。在 Design Patterns 形式中,您能够在实例化之前使用非默认的构造函数或执行其他任务。由于在此解决

方案中由 .NET Framework 负责执行初始化,因此您没有这些选项。在大多数情况下,静态初始化是在 .NET 中实现 Singleton 的首选方法。

namespace 单例模式

{

public sealed class Singleton4

{

//由于sealed所以Singleton4无法由于继承而产生实例

//只能利用readonly关键字下的类构造函数的初始化与类的静态初始化来引起实例

//它依赖公共语言运行库CLR来初始化变量

//因此在类首次被对 Instance 属性的调用引用之前,不会发生实例化。

//即是依赖于CLR,当第一次调用Instance的时候才实现实例化,而且往后的都这个Instance中的instance实例

static readonly Singleton4 instance=new Singleton4();

static Singleton4()

{ }

Singleton4()

{ }

//封装好了

public static Singleton4 Instance

{

get

{

return instance;

}

}

}

}

5、延迟初始化

namespace 单例模式

{

//同样也是第一次真正调用Instance才实例化

public sealed class Singleton5

{

Singleton5()

{

}

public static Singleton5 Instance

{

get

{

return Nested.instance;

Page 149: Csharp

www.happy12.com 010-82387501

}

}

class Nested

{

static Nested()

{

}

//初始化工作有Nested类的一个静态成员来完成,这样就实现了延迟初始化,并具有很多的优势

//利用嵌套类Nested对 instance 进行内部保护

//其实达到的效果也就是:区别例子4,例子4是一用到Singleton4就实例化,而这里是实际用到instance才实例化

internal static readonly Singleton5 instance = new Singleton5();

}

}

}

论坛地址: http://www.sisheng.net.cn/forum/forum.php

17、 技术标签:(数据库 使用实例)

18、 技术细节:(数据库 的具体使用环境 MSSQL、mySQL、Oracle)

1、数据库简介:

数据库是专门开发数据管理的软件,或者说专门管理数据的软件就是数据库。

数据库存在的意义就是:减轻开发人员的负担。数据库是一个综合的软件,那么我们不需要队要进行 2 进制保存数据进行处理了,但是却是要与数据库产生交互,

那么命令式 SQL,有技巧的 ,数据库就是万物皆关系(面向对象,万物皆是对象)有所区别。

2、数据库的发展:

一开始的是层次化的数据与网状数据库 ,后来也发现使用确实很麻烦。

于是到了 1970年 EFCO公司开创了关系性的数据库 ,技术难度大。后来,Oracle(甲骨文)公司的创始人,拉里投入到关系型数据库的研发,并且得到了一个大

客户 —美国国防部。随即开始出现关系数据库的旋风,随后各个公司都纷纷推出自己的数据库系统。比如:IBM的 DB2 ,还有风靡一时的 DBS3。

但是随即出现不兼容的问题,由于最早的时候都没有进行没规范。所以到最后各个数据库巨头统一了操纵数据库的 SQL(结构化 Struct 数据查询语言) 变成了标

准语言,而关系型数据库也俨然变成大家的宠儿,Oracle也从一个小公司,变成现在的数据库巨头,而我们的微软也推出了 SQLServer。当然还有 PHPer的最爱

mySQL。但是mySQL被 SUN,SUN被 Oracle收购,现在有免费版与收费专业版了。所以我们学习 SQL语言的时候,先学共同点,再学特异性。各种数据库软

件在使用上有一点区别。

3、数据库系统详解:

为适应数据处理的需要而发展起来的一种较为理想的数据处理的核心机构。计算机的高速处理能力和大容量存储器提供了实现数据管理自动化的条件。

数据库系统一般由 4个部分组成:

数据库,即存储在磁带、磁盘、光盘或其他外存介质上、按一定结构组织在一起的相关数据的集合。(个体)

数据库管理系统(DBMS)。一组能完成描述、管理、维护子数据库的程序系统。它按照一种公用的和可控制的方法完成插入新数据、修改和检索原有数据的操作。

数据库管理员(DBA)。

用户和应用程序。(微软的称作 SSMS)

4、数据库系统的基本要求是:

1、能够保证数据的独立性。数据和程序相互独立有利于加快软件开发速度,节省开发费用。

2、冗余数据少,数据共享程度高。

3、系统的用户接口简单,用户容易掌握,使用方便。

4、能够确保系统运行可靠,出现故障时能迅速排除,能够保护数据不受非受权者访问或破坏,能够防止错误数据的产生,一旦产生也能及时发现。

5、有重新组织数据的能力,能改变数据的存储结构或数据存储位置,以适应用户操作特性的变化,改善由于频繁插入、删除操作造成的数据组织零乱和时空性能变

坏的状况。

6、具有可修改性和可扩充性、可维护性。

7、能够充分描述数据间的内在联系。

5、数据库(Database):

由众多的数据、数据表、约束、存储过程、函数、视图、索引构成的一个数据存储与交互单元,是按照数据结构来组织、存储和管理数据的仓库。

6、数据表(table):

数据表,实际上是一个二维表。一般是围绕一个事务、动作记录,或者是一个信息主题作为一个数据表。数据表由行与列构成。

7、列(column、field):

列,其实就是字段。也是决定了信息的基本单元。列,包含有数据类型的设定。

8、行(row、record):

Page 150: Csharp

www.happy12.com 010-82387501 行,实际上就是一条基本信息。一行包含了多列数据的存储的信息。所以一行也有一条记录之称。

9、行业(trade)

一个行业一种需求,没一个需求每一种数据库的设计模式与思想。每个行业的数据设计的重点都是不同的。侧重查询(要求低范式)还是操作(要求搞范式)就是自

己选择的问题了。

10、索引(index)

索引是一个单独的、物理的数据库结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引其实就是一个 B+树,

但是这个索引是 N^n层数次方的。目的就是在数据库中划分出一定的区域优化查询。可以提升大量数据的查询速度。索引一般可以分为:基于字段优化查询速度的

普通索引、唯一性索引、主键索引、全文索引、单列与多列索引。现在由于数据库系统的不断升级,我们只要设定索引就可以了,不需要特殊的维护。而且数据在查

询的时候也会根据查询适当地选择是利用索引查询,还是仅仅是表查询。由于数据库系统的发展,系统内部已经自动帮我们完成对索引的维护。但是在设计的时候要

考虑到索引的损耗问题。数据库 DB就像是一个字典,索引就是根据指定字段制成的快速指向。由于只是指向数据对象标识,真正的数据是存储在 DB中,所以查询

速度极快。但是额外的内存与硬盘花销也是一个需要考虑的问题。比如:增加、删除、修改时数据库都要对索引进行维护,但是这样也是为了最后查询的效率的提升,

特别适合W行级别的数据查询。而索引可以分为:隐式索引(针对单个字段)、唯一索引(唯一约束)、函数索引(函数(字段))、聚簇索引(主键)、组合索引(最

多 16个 field)与全文索引(text)。一般索引会占用原数据库大小的 20%。

11、视图(view)

固化的子查询,将一个子查询起了一个固化的名字,保存在数据库中,方便以后的使用。其实调用大量的 Join 来进行一个查询一般也是用视图。视图与索引都是为

了优化查询的速度与语句。视图是优化语句,索引是优化单查速度。一般是 DBA来设定数据库的视图, 封装内部数据库的数据关系,范式修改数据容易了,视图

让我们查询复杂关系的数据变得容易。

12、触发器(trigger)

触发器(trigger)是个特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由个事件来触发,比如当对一个表进行操作( insert,delete, update)

时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。 触发器可以从 DBA_TRIGGERS ,USER_TRIGGERS 数据字典中查到。

13、SQLServer数据类型详解

数据 类型 描述

bit 整型 bit 数据类型是整型,其值只能是 0、1 或空值(null)。这种数据类型用于存储只有两种可能值的数据,如 Yes 或 No、True 或 Fa lse 、On 或

Off 。

int 整型 int 数据类型可以存储从- 231(-2147483648)到 231 (2147483 647)之间的整数。存储到数据库的几乎所有数值型的数据都可以用这种数据类

型。这种数据类型在数据库里占用 4个字节

smallint 整型 smallint 数据类型可以存储从- 215(-32768)到 215(32767)之间的整数。这种数据类型对存储一些常限定在特定范围内的数值型数据非常有用。

这种数据类型在数据库里占用 2个字节空间

tinyint 整型 tinyint 数据类型能存储从 0到 255 之间的整数。它在你只打算存储有限数目的数值时很有用。 这种数据类型在数据库中占用 1 个字节

numeric 精确数字型 numeric数据类型与 decimal 型相同

decimal 精确数值型 decimal 数据类型能用来存储从-1038-1到 1038-1的固定精度和范围的数值型数据。使用这种数据类型时,必须指定范围和精度。 范围是小数

点左右所能存储的数字的总位数。精度是小数点右边存储的数字的位数。左边是总数位,右边是小数点后的数位。

money 货币型 money 数据类型用来表示钱和货币值。这种数据类型能存储从-9220亿到 9220 亿之间的数据,精确到货币单位的万分之一

smallmoney 货币型 smallmoney 数据类型用来表示钱和货币值。这种数据类型能存储从-214748.3648 到 214748.3647 之间的数据,精确到货币单位的万分之

float 近似数值型 float 数据类型是一种近似数值类型,供浮点数使用。说浮点数是近似的,是因为在其范围内不是所有的数都能精确表示。浮点数可以是从

-1.79E+308到 1.79E+308 之间的任意数

real 近似数值型 real 数据类型像浮点数一样,是近似数值类型。它可以表示数值在-3.40E+38到 3.40E+38之间的浮点数

datetime 日期时间型 datetime 数据类型用来表示日期和时间。这种数据类型存储从 1753年 1月 1日到 9999年 12月 3 1日间所有的日期和时间数据, 精确到三

百分之一秒或 3.33毫秒,但是在输出的时候我们可以使用拼接的技术,也可以使用 SQLSwrver内部的指令

Smalldatetime 日期时间型 smalldatetime 数据类型用来表示从 1900年 1月 1日到 2079年 6月 6日间的日期和时间,精确到一分钟

cursor 特殊数据型 cursor 数据类型是一种特殊的数据类型,它包含一个对游标的引用。这种数据类型用在存储过程中,而且创建表时不能用

timestamp 特殊数据型

timestamp 数据类型是一种特殊的数据类型,用来创建一个数据库范围内的唯一数码。 一个表中只能有一个 timestamp列。每次插入或修改一

行时,timestamp 列的值都会改变。尽管它的名字中有“time”, 但 timestamp 列不是人们可识别的日期。在一个数据库里,timestamp 值是

唯一的

Uniqueidentifier 特殊数据型 Uniqueidentifier数据类型用来存储一个全局唯一标识符,即 GUID。GUID确实是全局唯一的。这个数几乎没有机会在另一个系统中被重建。可

以使用 NEWID 函数或转换一个字符串为唯一标识符来初始化具有唯一标识符的列

char 字符型 char数据类型用来存储指定长度的定长非统一编码型的数据。当定义一列为此类型时,你必须指定列长。当你总能知道要存储的数据的长度时,此

数据类型很有用。例如,当你按邮政编码加 4个字符格式来存储数据时,你知道总要用到 10个字符。此数据类型的列宽最大为 8000 个字符

varchar 字符型 varchar 数据类型,同 char 类型一样,用来存储非统一编码型字符数据。与 char 型不一样,此数据类型为变长。当定义一列为该数据类型时,

你要指定该列的最大长度。 它与 char数据类型最大的区别是,存储的长度不是列长,而是数据的长度。其实就是可变长的 char类型。

text 字符型 text 数据类型用来存储大量的非统一编码型字符数据。这种数据类型最多可以有 231-1或 20亿个字符。有点像 BLOB、CLOB,只保留 16个字

节的地址,速度会变慢。它不是 char所以字符串的函数对其无效

ntext 字符型 也是用 Unicode的 text。

nchar 统一编码字符 nchar 数据类型用来存储定长统一编码字符型数据。统一编码用 2个字节来存储每个字符,而不是用单字节(普通文本中的情况)。它允许大量的扩

展字符。此数据类型能存储 4000种字符,使用的字节空间上增加了一倍。可以针对特殊的字符。就会使用 Unicode的编码来存储。8000个字节。

Page 151: Csharp

www.happy12.com 010-82387501

nvarchar 统一编码字符型 nvarchar 数据类型用作变长的统一编码字符型数据。此数据类型能存储 4000种字符,使用的字节空间增加了一倍。变长、特殊字符。这种 Unicode

编码要比 char、varchar存储相同的数据耗用了

ntext 统一编码字符型 ntext 数据类型用来存储大量的统一编码字符型数据。这种数据类型能存储 230 -1或将近 10亿个字符,且使用的字节空间增加了一倍

binary 二进制数据类型 binary数据类型用来存储可达 8000 字节长的定长的二进制数据。当输入表的内容接近相同的长度时,你应该使用这种数据类型

varbinary 二进制数据类型 varbinary 数据类型用来存储可达 8000 字节长的变长的二进制数据。当输入表的内容大小可变时,你应该使用这种数据类型

image 二进制数据类型 image 数据类型用来存储变长的二进制数据,最大可达 231-1或大约 20亿字节

BLOB、CLOB 统一编码字符型 记录大量的文字,适合记录博文。

注:Max的突破限制,可以存特别长的数据。这样就可以突破原本的数据类型的长度限制。

14、命名规范:

数据库对象 前缀 举例 1 举例 2

表(Table) tbl tbl_Student 值域 D{只读,完全,禁止},就可以实现访问级别。 tbl_StudentCourse_ReadOnly

字段(Column) 无 Title,studentID 日期 LogionDate、次数 LoginCount、链接 LoginUrl、Is是否、Has有无 或者 Can 能否开头

参数(parameter) @ @CurrentDate 遵循 Pascal命名规则

视图(View) v 视图(View)

存储过程(Stored procedure) pr prDelOrder pr操作或者动作的名字

触发器(Trigger) tr trOrder_D

索引(Index) ix_ ix_CustomerID

主键(Primary key) Pk_ pk_Admin

外键(Foreign key) fk_ fk_Order_OrderType

Check约束(Check Constraint) ck- ck_TableColumn

Unique约束 uq_ uq_TableColumn

用户定义数据类型(User-defined data type) udt udtPhone

用户定义函数(User-defined function) fn fnDueDate

15、Null的三值关系

null也是一个集合,但是仅仅表示的是一个空集,但是实际上是 null=Unknow。

1、 数值运算 null为 null;

2、 逻辑判定 null为 null;

3、 主外键联接 null为忽略;

4、 语句连结 null为 or或真、and和假。

具体可查三值逻辑的真值表。

5、特殊情况:

<1>where null = null,where column = value:表中 column为 NULL的行永远不会返回,即使 value是 NULL,直接断言;

<2>case null when null then XXX:XXX永远不会执行,即使 value是 NULL,直接断言;

<3>unknow判断,if <unknow> {XXX} else {YYY} end或 case when <Unknown> then XXX else YYY end:这两种情况下,<unknow>,即是 null会

执行。

<4>唯一约束(unique index)的字段只允许一个 null的行,再插入或更新该字段为 NULL的行会报字段重复的错误。

<5>group by时,所有 null被视为一组。

<6>order by时,所有 null排在一起,但 null排在最前面.(如 SQL Server),或者是最后面(如 Oracle),SQL标准未规定。

<7>聚集函数(sum/avg/max/min/count)忽略 null的行,即是不返回此行数据,直接断言

<8> declare时,在未赋值之前为 null。

<9>与 NULL处理相关的运算符和函数:

A B A ∨ B A ∧ B ¬ A

1 1 1 1 0

1 N 1 N 0

1 0 1 0 0

N 1 1 N N

N N N N N

N 0 N 0 N

0 1 1 0 1

0 N N 0 1

0 0 0 0 1

Page 152: Csharp

www.happy12.com 010-82387501

- is null/is not null:用这两个运算符来判断一个值是否为 NULL,而不是=或<>;

- is null/ coalesce:取第一个非空值(注意两个函数的数据类型转换规则不同);

- nullif(a,b):等价于如果 a等于 b返回 null,如果不等于返回 b

- isnull(a,b):取两者中不为 null的值,都为 null返回 null。

16、Not Null的建表

由于三值关系的存在,很多开发人员在建表的时候,除非是非 null 不可,基本都是允许为 null 的,其结果往往是一张表除了主键以外所有的字段都可以为 Null。之

所以会有这样的思路,是因为 Null好啊,程序不容易出错啊,你插入记录的时候如果不小心忘输了一个字段,程序依然可以 R运行 un,而不会出现 “XX字段不能

为 Null”的错误消息。

但是,这样做的结果却是很严重的,也会使你的程序变得更加繁琐,你不得不进行一些无谓的空值处理,以避免程序出错。更糟的是,如果一些重要数据,比如说订

单的某一项值为 Null了,那么大家知道,任何值与 Null相操作(比如加减乘除),结果都是 Null,导致的结果就是订单的总金额也为 Null。

你可以运行下面的代码尝试一下: Select Null + 5 As Result

但是我们如何解决输入为空的问题呢?我们为什么不使用我们强悍的工具—check约束与默认值呢? Field Varchar(500) default ‘nothing’ Not Null Constraint ck_ColumnName Check(Len(ColumnName)>0), [Type] TinyInt Not Null Default 0 Constraint ck_ArticleType Check([Type] in (0,1,2)), 所以,合理的思维方式应该是这样的:默认这个字段是 Not Null的,然后判断这个字段是不是非 Null不可,如果不是这样,OK,这个字段是 Not Null的,进行下

一个字段。

17、数据库的原子性

1、你的表是描述什么事物,明确表的信息对象主体

2、你的表是为了适合什么操作语句的设计的,面向操作设计

3、列的内容要不要原子性的切块,让查询直逼要害,列的设计的小块的程度要拿捏好

4、表必须是二维表,而且要根据不同的需求进行设计,表的设计与列的设计一样都要依赖与操作与需求

原子性的存在是为了切分适合的信息块 ,从而达到信息的最大化、最优化的使用,并不是无限切分就好,要看实际的应用。但是由于原子性数据的表容易设计,而

且运行的所需时间较短(查询信息的指向性比较强,同时也便于维护喝更新操作,但是却是在海量数据搜索面前有点乏力),所以对大量的数据处理的时候要加分效

果。

1、 同一列中不能存在多个类型相同的值,一列不能多值(除非是)

2、 同一个表中也不能存在有多个存储相同类型数据的列

3、 无重复的行,每列只存储一份同类型下的一份数据(列是单值的),无重复列名

18、结合信息对象与业务设计数据库设计

1、数据库的设计师根据信息要素、关系来设计的;

2、数据库的信息查找依赖于信息的使用方式的;

3、对于可有可无的东西,我们需要花点时间去好好斟酌;

4、简短的查询,比囧长的业务查询更加需要思考;

5、使用数据的方式将会与我们占用系统内存与硬盘息息相关,影响着服务器的整体表现,所以我们的设计会有所倚重与侧重;

现在基本是双数据库,外层是方便查询,内层是方便修改。

SQL换一句话其实就是关系数据库管理系统 Realtional Database Management System ,RDBMS

表的设计的方法:

1、挑出事物对象(对象信息浓缩法)

2、围绕事物对象的信息收集(信息扩散聚拢法)

3、信息拆分成块(字段原子性)

4、事务需求拆分法(关系设计)

5、数据的发散与聚合程度的分析(表设计的检验)

19、范式 1NF 2NF 3NF 4NF

1NF,主要是解决表中字段设计、信息与业务之间的关系的问题

1、 数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。在第一范式(1NF)中表

的每一行只包含一个实例的信息。简而言之,第一范式就是无重复的列,而且单列无重复的值。

2、 所有属性都必须是原子的——每个属性一个值。一个实体的所有实例都必须包含同等数量的值。一个实体的所有实例必须两两不相同。

2NF,主要是设定主键,解决数据库的数据冗余、更新、插入、更新的指向性的问题

1、 要求数据库表中的每个实例或行必须可以被唯一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。这个唯一属性列被称为主关键字

或主键、主码、唯一 关联。引入主键约束primary key,Constraint pk_Article Primary Key(Id)。主键的设定也是有要求的。主键默认不能为空,保持唯

一性。插入、更新删、除记录的时候必须指定主键的值。要求主键必须简洁,主键值不能被修改。

2、 实体必须满足第一范式。所有属性描述的事实都必须与整个键相关,而不能只描述键的一个子集。

3NF,主要是解决排除部分列之间的依赖关系,利用了表与表的主外键关系解决。

9、 要求实体数据记录(record)相对于外部完全依赖于主关键 ID。所谓完全依赖,是指在除主键外其他的属性列之间不存在对应依赖。如果存在,那么这一依赖部

分应该分离出来形成一个表(关联),一般抽离出这一部分的主依赖项的 ID,把这一部分作为一个新的表记录,同时原表也存储此次依赖项 ID,然后利用建立

主外键关系,将一表分成两表,解决原表因为主次依赖项存在而造成的数据冗余等一系列问题(但是对于以查询操作为主、记录大量数据的表此范式就需要斟

酌了)。第二范式就是建立主键,与排除其他列对其属性列的依赖(消除部分列的依赖)。

10、 实体必须满足第二范式。如果每个非键属性描述的事实都与一个键属性相关,则实体满足第三范式所有属性描述的都必须是关于键的事实,除此之外别无其他。

4NF,主要是解决根据属性列的相似(不同的从属对象)与共同(相同的从属对象)信息的建表问题,即是表中所有列对外的一对多关系不受限制

6、 因为比较抽象,即是 A表中含有 a1,a2两个属性列,B表中记录 a1的信息(包含 b1),C表中包含 a2的信息(包含 c1),但是 b1,c1实际上是相同类型

的信息,但是从对象不同。此处就是要我们明确建表的时候,要仔细区分共有与相似(决定建表)的关系,从属对象与属性列之间关系与一对多关系的搭设与

Page 153: Csharp

www.happy12.com 010-82387501 否的问题。

7、 在实体中,不会出现多于一个的多值依赖。

5NF,主要是解决将信息切割得更细,清除所有冗余,但是在 4NF设计会出现联接不当而产生的错误 record

1、在 4NF 下,一般我们仅仅是区分了属性列的相似与共有信息,但是这个时候就会因为新建的 b、c 而产生误解数据或者是错误记录。因此可以从第五范式(实

际上是所有范式)中得到的启示是,当你觉得可以将表分解为带着不同自然键的更多、更小的表时,这么干很可能就是最好的方式。如果你想要把各个部分联结

到一起,表示最初的、分解得更少的数据形式,数据库干这事比你干得强多了。很明显,如果你不能通过联结来重新构建分解前的表,那就最好不要进行分解。

即是有一个道理,更少得冗余,更多的错误。唯有靠联接来解决了。或者采用树状分层设计法,同层合并,也可以单独建立一个事务记录表。

2、当分解是信息无损的时候,所有关系都被分解成了二元关系。

但是面对日益变态的信息几何级的增长,为了令到数据库从焦油坑变成金矿我们会加入数据挖掘的思想,但是这个时候就需要无损的信息与高度分块的。所以在

物理建表之前,我们还是需要遵循规范化建表的原则。

20、规范化建表

让数据具有原子性是设计出规范化数据表的第一步(同时也是为了提高数据库的可读性),但是到后期你可能会因为数据量以及性能的问题打破这种规范化。因为你

的数据库投入使用后数据库的大小日益增大,设计规范化的表可以时刻保持你应对以后各种复杂的组合查询 (主要是应对数据库过分膨胀后的,查询缓慢的问题)

规范化建表的优点:

1、可以减少表中重复数据的存储,减少数据库的大小;

2、因为数据库的切割使得你的查询的指向性更强,查找的数据少,查找得更加快速;

3、但是最后归根到底还是 避免存储重复的数据节省我们的硬盘空间。

21、不规范化建表

规范化主要用来改善性能,过度规范化的结构会造成查询处理器和 SQL Server中其他进程的开销过大(不适用在查询表的设计),或者,有时需要降低复杂性来使

得实现更容易些,非规范化在这些时候就会发挥作用。正如我在这章中一直试图阐明的那样,虽然人们大都认为非规范化到第三范式就可以了(靠着减少所需联结

的数量,查询过程已经被简化了)然而,这样做冒着引入数据异常的风险。每个使用数据库的应用程序都要复制任何额外写的,用来处理这些异常代码,因此就增

加了人为错误的可能性。在这种情况下必须作出的判断是:是一个稍微慢点(但是 100%正确)的应用更好呢,还是一个更快但正确性稍差的应用更好些。

在逻辑建模阶段,绝不应该从我们规范化的结构倒退,对应用程序过早过激地进行性能调优工作。OLTP数据库结构上,所以设计中最重要的部分就是:保证我们的

逻辑模型体现了最终的数据库含有的所有实体和属性。一旦开始物理建模过程(这与性能调优应该是同义语),那就有足够充足的理由来对结构进行非规范化操作,

要么是出于性能的考虑,要么是出于减少复杂性的考虑,但是,这两种考虑都不适合用在逻辑模型上。当我们物理上的实现在逻辑上也正确的时候,碰到的问题几

乎总是会更少些。对几乎所有情况来说,我都建议等到物理建模阶段才对解决方案进行实现,或者,至少等到有某种非做不可的原因时(比如,系统中某些部分失

败了)才进行非规范化工作。

总结:一般,我们是采用两层数据库的,一层是外层,用于直接的查询。一层是内层数据库,用于记录与维护更新的。维护更新资料的时候,对内层数据库进行操

作,当操作完成的时候就会马上更新外层数据库。所以外层数据库(以查询为主)设计的范式要求比较低,但是内层数据库(维护更新为主)的要求就比较高了。

22、数据库设计建议:

数据库不仅是用来保存数据,还应负责维护数据的完整性和一致性

我看过很多的开发人员设计出来的数据库,给我的感觉就是:在他们眼里,数据库的作用就如同它的名称一样――不仅仅是用来存放数据的,除了不得不建的主键

以外,什么都没有...没有 Check约束,没有索引,没有外键约束,没有视图,甚至没有存储过程。 一个很好的数据库该有的还是有的。什么都没有的数据库插入

操作是很好,但是多了这点东西的数据库还是很快的。

如果要写代码来确保表中的行都是唯一的,就为表添加一个主键,即是 distinct的使用频率应该是比价少的。

如果要写代码来确保表中的一个单独的列是唯一的,就为表添加一个约束,一般是事务状态记录表。

如果要写代码确定表中的列的取值只能属于某个范围,就添加一个 Check约束。

如果要写代码来连接 父-子 表,就创建一个关系,上下其实都是依据主外键的。

如果要写代码来维护“一旦父表中的一行发生变化,连带变更子表中的相关行”,就启用级联删除和更新。

如果要调用大量的 Join来进行一个查询,就创建一个视图。

如果要逐条的写数据库操作的语句来完成一个业务规则,就使用存储过程。

没有提到触发器,实践证明触发器会使数据库迅速变得过于复杂,更重要的是触发器难以调试,如果不小心建了个连环触发器,就更让人头疼了,所以我更倾向于

根本就不使用触发器 trigger。

3、技术实例:(数据库)

8、 加载数据库脚本

source C:\Users\Administrator\Desktop\script-1.sql ;——mySQL

source (\.) Execute an SQL script file. Takes a file name as an argument.

9、 保存为数据库脚本

Tee C:\Users\Administrator\Desktop\script-1.sql ;

tee (\T) Set outfile [to_outfile]. Append everything into given outfile.

notee 输入的时候就会把 tee与 notee进行保存为 sql脚本。

10、 查询当前实例的数据库集合

Show databases ; ——mySQL

mysql> show databases;

+--------------------+

| Database |

+--------------------+

| information_schema |

| drinks |

| mysql |

Page 154: Csharp

www.happy12.com 010-82387501

| performance_schema |

| test |

+--------------------+

4、使用某个数据库

mysql> use drinks;

Database changed

5、查询当前数据库的表集

mysql> show tables;

+------------------+

| Tables_in_drinks |

+------------------+

| easy_drinks |

| my_contacts |

+------------------+

6、查询表的结构

mysql> desc my_contacts;

+------------+--------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+------------+--------------+------+-----+---------+-------+

7、判断存在

方法 1:精确方法

Sysobjects 是 Master系统视图

object_id 是抓取对象在视图中的 ID

OBJECTPROPERTY 是根据对象判断类型函数,返回的是 bool if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tb]') and OBJECTPROPERTY(id, N'IsUserTable')

= 1) drop table [dbo].[tb]; 方法 2:模糊方法

declare @a varchar(2000) ——MSSQL 删除约束 set @a=(select name from sysobjects where name like 'Name') set @a= 'ALTER TABLE [dbo].[TableName] DROP CONSTRAINT '+@a exec (@a)

8、数据库的新建、删、改

<1>新建数据库

mysql> create database myDB; ——mySQL

Query OK, 1 row affected (0.00 sec) create database mmc; ——MSSQL

<2>数据库修改

exec sp_rename 'a1.name ', 'Name ', 'database' ——MSSQL <3>删除数据库

mysql> drop database drinks;——mySQL

Query OK, 2 rows affected (0.34 sec)

drop database mySQL;——MSSQL

9、数据表的新建、删、改

<1>新建数据表

mysql> show create table servers;——mySQL显示表的创建方式

| servers | CREATE TABLE `servers` (

`Server_name` char(64) NOT NULL DEFAULT '',

`Host` char(64) NOT NULL DEFAULT '',

`Db` char(64) NOT NULL DEFAULT '',

`Username` char(64) NOT NULL DEFAULT '',

`Password` char(64) NOT NULL DEFAULT '',

`Port` int(4) NOT NULL DEFAULT '0',

`Socket` char(64) NOT NULL DEFAULT '',

`Wrapper` char(64) NOT NULL DEFAULT '',

`Owner` char(64) NOT NULL DEFAULT '',

PRIMARY KEY (`Server_name`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='MySQL Foreign Servers table' |

mysql> create table my_contacts( ——mySQL

Page 155: Csharp

www.happy12.com 010-82387501

-> ID int not null Auto_increment,

-> last_name varchar(20) not null,

-> first_name varchar(20) not null,

-> email varchar(50) not null,

-> birthday date,

-> profession varchar(50),

-> location varchar(50),

-> status varchar(20),

-> interests varchar(20),

-> seeking varchar(100) ,

Parmary key (名 ) );

Create Table Article ——MSSQL (

Id Int Identity(1,1) Not Null,——自增 Title Varchar(50) Not Null Constraint uq_ArticleTitle Unique,——1、唯一约束 Keywords Varchar(50) Not Null Constraint ck_KeywordsLength Check (len(Keywords)<10),——2、检查约束 Abstract Varchar(500) Not Null, ——3、非空约束 Author Varchar(50) Not Null, [Type] TinyInt Not Null Default 0 Constraint ck_ArticleType Check([Type] in (0,1,2)), IsOnIndex Bit Not Null Default 1, ——默认值 Content Text Not Null, SourceCode Varchar(100) Null, [Source] Varchar(50) Not Null Default 'TraceFact', SrcUrl Varchar(150) Null, PostDate DateTime Not Null Default GetDate(), ViewCount Int Not Null Default 0, ClassId Int Not Null ,

Constraint pk_Article Primary Key(Id), —— 4、主键约束 Constraint fk_Article foreign key(scoreId) references student(id)——5、外键约束,为主表student建立外键关系 ) <2>修改数据表

mysql> alter table 旧表名 rename to 新表名; ——mySQL

use databasename;

EXEC sp_rename '旧表名', '新表名';——MSSQL <3>删除数据表

mysql> drop table mytables;——mySQL

drop table a1;——MSSQL

10、字段、约束(数据表成员)的增加、删、改

<1>增加字段

mysql> alter table mytable——mySQL 添加字段

-> add column mycolumn2 int first , 其中还有 after column 排在指定的列之后

-> add primary key (mycolumn2); ——mySQL 添加主键

alter table test1 add nob int identity(1,1) not null ——MSSQL 添加字段 alter table test1 add primary key (nob); ——MSSQL 添加主键 alter table [dbo].[Article2] add default ((1)) for [IsOnIndex] ——MSSQL添加默认约束

alter table [dbo].[Article2] with check add constraint [ck_KeywordsLength2] check ((len([Keywords])<(10)))

——新建check alter table [dbo].[Article2] check constraint [ck_KeywordsLength2] ——MSSQL 把 ck_KeywordsLength2 添加 check约束

集合 alter table [dbo].[Article2] with check add constraint [ck_ArticleType2] check (([Type]=(2) OR [Type]=(1) OR

[Type]=(0))) <2>修改字段

mysql> alter table mytables

-> change column firstname firstName varchar(30) ,——mySQL 改变名字、类型

-> add primary key ( lastname );

mysql> alter table mytable——mySQL 不改变名字,改类型

-> modify mycolumn2 varchar(20); exec sp_rename 'a1.name ', 'Name ', 'column ' ——MSSQL 只改变名字

alter table test1 alter column ID varchar(200) null ——MSSQL 不改变名字,改类型

alter table test1 drop Constraint constraintname; ——MSSQL 删除约束

alter table test1 add primary key (nob); ——MSSQL 添加主键约束

alter table Articles2 add constraint fk_job_id foreign key (Id) references Article3(Id); ——MSSQL添加外键约束

alter table dbo.Article2 add constraint uk_Id unique nonclustered (Id); ——MSSQL 添加唯一约束

alter table [dbo].[Article2] add constraint uk_Id default ((1)) for [IsOnIndex] ——MSSQL添加默认约束 alter table [dbo].[Article2] with check add constraint [ck_KeywordsLength2] CHECK ((len([Keywords])<(10)))

——新建check

Page 156: Csharp

www.happy12.com 010-82387501 alter table [dbo].[Article2] chenk constraint [ck_KeywordsLength2] ——MSSQL 把 ck_KeywordsLength2 添加 check约束

集合 alter table [dbo].[Article2] with check add constraint [ck_ArticleType2] check (([Type]=(2) OR [Type]=(1) OR

[Type]=(0))) alter table [dbo].[Article2] with check add constraint [ck_KeywordsLength2] check ((len([Keywords])<(10)))

——新建check alter table [dbo].[Article2] check constraint [ck_KeywordsLength2] ——MSSQL 把 ck_KeywordsLength2 添加 check约束

集合

备注:最后一栏 column/database/index/object等等,还有约束的修改只能是先删除再新建。

还能够建立联合主键,就使用利用两个字段来确定一条数据,一般这样的数据不会进行修改。

<3>删除字段

mysql> alter table mytable ——mySQL

-> drop column mycolumn2; alter table test1 drop column nob; ——MSSQL 删除字段 alter table test1 drop Constraint constraintname; ——MSSQL 删除约束

11、连接词 and、or 、not

<1>and:A and B,即是 A与 B 要同时成立。

<2>or:A或者 B,只要其中一个成立就成立

<3>not:not A and B,当 A不成立而且 B成立;A and not B,当 A成立而且 B不成立; not (A and B),当 A与 B都不成立

12、符号 <、>、=、<=、=>、<>、null

1、<:小于

2、>:大于

3、<=:小于或者等于

4、>=:大于或者等于

5、<>:不等于;=等于

6、is null 或者是 not null

7、<’D’: field的第一个字母早于 D;>’A’:field的第一个字母要晚于 A

13、匹配关键字 LIKE、通配符“%”与占位符 “_”与区间关键字“between”与集合关键字“in“

①:where field Like ‘%CA%’,filed字段里面包含CA字符的所有结果;

②:where field Like ‘CA%’,field字段前面是CA字符的结果;

③:where field Like ‘%CA’,field字段后面是CA字符的结果;

③:where field Like ‘_CA%’,field字段前面第二第三个是CA的结果;

④:where field between 20 and 30 在 20与 30之间 或者 between ‘A’ and ‘Z’ 在 A与 Z之间。

⑤:where field in (1,2,3) filed(类型相同)是 1,2,3中的其中一个 或者 where field in (‘1’,‘2’,‘3’)field在‘1’、‘2’、‘3’中的其中之一,

即是 filed的类型要与 in里面的类型相同。

14、SQL语句 select、insert、delete、update

①:select field from table

②:insert into table (fields) values (values)

③:delete from table where field 条件

④:update table set field = value where field 条件,例子:update table set table.column2= Right(table,2)

⑤:SQL语句是可以结合运算的。Update set const=const=1;

15、SQL字符串处理函数

①:Right (column,2) 从右边开始截取2位的字符

②:Substring _index( column,“,”,2) 截取第二个逗号(字符)前的字符串

③:Substring (column,numberA,numberB) 截取列中,从A位开始读取后面B位的字符串

④:Upper(column) 转换大写、

⑤:Lower (column) 转换小写

⑥:Reverse(column) 反转字符串的顺序

⑦:Ltim( colum ) 左去除空

⑧:Rtrim( column) 右去除空

⑨:Length (column) 获取字符长度,返回一个int,但是在MSSQL len(Keywords)<10

16、数据表约束 Constraint(唯一、非空、检查、主键、外键)

<1>唯一约束:Constraint uq_ArticleTitle Unique,——唯一约束 alter table dbo.Article2 add constraint uk_Id unique nonclustered (Id); ——MSSQL 添加唯一约束

Page 157: Csharp

www.happy12.com 010-82387501

唯一约束即是指定的列的值在此列中只出现一次,null也是不能出现第二次的。

<2>非空约束:Content Text Not Null, alter table student add constraint codenn check(code is not null); 非空约束指定列不能为空。

<3>检查约束:Constraint ck_ArticleType Check([Type] in (0,1,2)), alter table [dbo].[Article2] with check add constraint [ck_KeywordsLength2] check ((len([Keywords])<(10))) check约束是功能最强大的约束,其中可以写很多逻辑条件进去。

<4>主键约束:Constraint pk_Article Primary Key(Id), —— 4、主键约束 alter table test1 add primary key (nob); ——MSSQL 添加主键约束

主键约束是指此列为唯一标识,一般配合 identity(1,1)使用。

<5>外键约束:Constraint fk_Article foreign key(scoreId) references student(id)——5、外键约束,为主表student建立外键关系

alter table Articles2 add constraint fk_job_id foreign key (Id) references Article3(Id); ——MSSQL添加外键约束

B表中使用外键约束字段 ID,那么确保 B表中的输入的 ID的值与 A表中 ID的值匹配。A表 ID为主键,B表 ID为外键,B的 ID依赖与 A的 ID

的存在。

17、case when then语句

<1>一般使用:

select case column when value1 then operate1 end when value2 then operate2 end else operate3 end from table 返回的operate的

<2>结合连接词 :

select ('Disk'+Ltrim(Rtrim(Convert(char,a.Disk_ID)))+'Movie'+Rtrim(Ltrim(Convert(char,b.Movie_ID)))) as 编号, b.Movie_Name as 影片名称,a.RentCount as 租借次数, (case a.States when 0 then '没租' when 1 then '已租出'

when 2 then '已预定' when 3 then '损毁' end ) as 状态 from (tbl_MovieDisk a inner join tbl_Movies b on a.Movie_ID=b.Movie_ID) left join tbl_MovieTypes e on b.Type_ID=e.Type_ID;

<3>结合组函数转置: select [sid],

sum ([mark]) as 总分, avg ([mark]) as 平均分, avg ( case when [cid]=1 then [mark] end) as [database], avg (case when [cid]=2 then [mark] end) as [C#], avg (case when [cid]= 3 then [mark] end) as [xml] from tbl_marks

group by [sid] –-对查询结果字段中没有聚合函数的字段进行分组修饰

18、排序关键字 order by column(顺序) 与 order by column desc(倒序)MSSQL的功能都不是单一、独立的,所以必须对结果集合进行收缩 create table #tmp1

( name nvarchar(20),

name2 nvarchar(20) ) select * from #tmp1; insert into #tmp1 (name) values ('A'); insert into #tmp1 (name,name2) values (1,1); insert into #tmp1 (name,name2) values ('a',1); insert into #tmp1 (name,name2) values (1,'b'); insert into #tmp1 (name,name2) values (1,'?'); insert into #tmp1 (name,name2) values (1,'B'); insert into #tmp1 (name,name2) values (1,'A'); select name2 from #tmp1 order by name2;

①:对于数字 1到 9,顺序是 1-9,由小到大;而倒序是 9-1;

②:对于数字 1到 9,而且夹杂 a-z与 A-Z,顺序是 aABbcCDd 小大大小模式;

③:对于字母 a到 z,顺序是 a-z;而倒序是 z-a;

④:对于字母 a到 z,即是夹杂 a-z与 A-Z,没有排序的时候:aABbcCDd 小大大小模式;

⑤:其实是 MSSQL对大小写都是同等对待。select tmpChar from #tmp1 group by tmpChar,只出现一组的 a-g,而且是不区分大小写的,导致了。

⑥:order by的多组合,先执行列 1再在列 1的区域里面再进行列 2的排序 select tmpChar from #tmp1 order by tmpChar desc倒序,tmpNum asc顺序; ⑦:对于符号的排序的问题,我们有时候要对 nvarchar类型的字段进行排序,里面有很多特殊的字符,那么顺序是:!“&‘(*+=@

⑧:一般规律是:顺序上到下 ,null 非字母字符 数字 大写字母 小写字母 非字母字符

Page 158: Csharp

www.happy12.com 010-82387501

19、分组关键字 group by create table #tmp2

( [Count] int, name2 nvarchar(20)

) select * from #tmp2; insert into #tmp2 ([Count],name2) values (1,1) insert into #tmp2 ([Count],name2) values (2,1) insert into #tmp2 ([Count],name2) values (3,2) insert into #tmp2 ([Count],name2) values (4,2) insert into #tmp2 ([Count],name2) values (5,3) select name2 from #tmp2 group by name2;OK select [Count],name2 from #tmp2 group by name2;wrong select [Count],name2 from #tmp2 group by name2,[Count]; OK select SUM([Count]) as 汇总 ,name2 from #tmp2 group by name2; OK ①:指定的列进行分组,返回的结果集合要是包含其他的列(没有组函数运算),那么需要把其他的列依次加入到分组集合中。

②:在结果集合里面,除分组集合中的列外,其他列必须有组函数修饰。

20、聚合 SUM()、AVG()、COUNT()、MAX()、MIN()

①:SUM(),汇总聚合函数

②:AVG(),平均聚合函数;

③:COUNT(),计数聚合函数;

④:MAX(),求最大值聚合函数;

⑤:MIN(),求最小值聚合函数。

备注:使用聚合函数在查询范围后一定要使用 group by 对聚合函数以外的列进行分组。而且所有的对象是除字符类型的所有数值类型。

21、子查询、范围匹配关键字 in与聚合函数后的查询子句 Having

①:子查询是指当一个查询是令一个查询的条件的时候。即是:查询出来的结果是另外一个查询的搜索域或者条件。

①-1:

搜索域(双重嵌套) select ss.studentid, ts.[name], ss.totalmark from (

select s.studentid, sum( mark ) as TotalMark from ( tbl_students s inner join tbl_marks m on s.studentId = m.sid )

inner join tbl_courses c on m.cid = c.courseId group by s.studentId ) ss inner join tbl_students ts on ss.studentid = ts.studentid 条件(返回的集合区间) select Name

from AdventureWorks.Production.Product where ListPrice =

( select ListPrice from AdventureWorks.Production.Product where Name = 'Chainring Bolts' ) ①-2:集合 in、having、exists

②:in是确定指定的值是否与子查询或列表区域中的值相匹配。返回一个 bool

区间条件:· select FirstName, LastName, e.Title from HumanResources.Employee as e

JOIN Person.Contact as c on e.ContactID = c.ContactID where e.Title in ('Design Engineer', 'Tool Designer', 'Marketing Assistant'); GO Check约束:Constraint ck_ArticleType Check([Type] in (0,1,2)), –-check约束中的使用

③:Having是指定组或聚合的搜索条件,相当于 group by后的where。

Having 只能与 select 语句一起使用。Having 通常在 group by 子句中使用。如果不使用 group by 子句,则 Having 的行为与 where 子句一样。在 Having

子句中不能使用 text、image 和 ntext 数据类型

select SalesOrderID, sum(LineTotal) as SubTotal –-此处有聚合函数 from Sales.SalesOrderDetail group by SalesOrderID Having sum(LineTotal) > 100000.00 –Having不能使用text、image、ntext,Having使用的时候必须跟在分组之后。 order by SalesOrderID ;

22、内连接 inner join table on ,外连接 right join table on 、 Left join table on与全连接 full join table on

Page 159: Csharp

www.happy12.com 010-82387501

现在有 table A 与 table B。A、B表有主外键关于 ID主外键关系。A表是主表,B表是子表。A是影片表,B是影碟表,ID是 MovieID。 Create table #tmpMovie ( MovieID int , MovieName nvarchar(30) ) select * from #tmpMovie; --6条数据,2条没用 insert into #tmpMovie (MovieID,MovieName)values (1,'影片'); insert into #tmpMovie (MovieID,MovieName)values (2,'影片'); insert into #tmpMovie (MovieID,MovieName)values (3,'影片'); insert into #tmpMovie (MovieID,MovieName)values (4,'影片'); insert into #tmpMovie (MovieID,MovieName)values (5,'影片');--多余的 insert into #tmpMovie (MovieID,MovieName)values (6,'影片');--多余的

create table #tmpDisk ( DiscID int, DiscName nvarchar(30), MovieID int ) select * from #tmpDisk; --10条数据,4条没用 insert into #tmpDisk (DiscID,DiscName,MovieID) values (1,'影碟',1); insert into #tmpDisk (DiscID,DiscName,MovieID) values (2,'影碟',1); insert into #tmpDisk (DiscID,DiscName,MovieID) values (3,'影碟',2); insert into #tmpDisk (DiscID,DiscName,MovieID) values (4,'影碟',2); insert into #tmpDisk (DiscID,DiscName,MovieID) values (5,'影碟',3); insert into #tmpDisk (DiscID,DiscName) values (6,'影碟');--为空 insert into #tmpDisk (DiscID,DiscName,MovieID) values (7,'影碟',4); insert into #tmpDisk (DiscID,DiscName) values (8,'影碟');--为空 insert into #tmpDisk (DiscID,DiscName,MovieID) values (9,'影碟',7); --影片不存在 insert into #tmpDisk (DiscID,DiscName,MovieID) values (10,'影碟',8); --影片不存在 --内连A,6条 select a.MovieID from #tmpMovie a inner join #tmpDisk b on a.MovieID=b.MovieID; --内连B,6条 select b.MovieID from #tmpDisk b inner join #tmpMovie a on a.MovieID=b.MovieID;--效果一致 --左连接A,6条+A2条 select * from #tmpMovie a left join #tmpDisk b on a.MovieID=b.MovieID; --左连接B,6条+B4条 select * from #tmpDisk b left join #tmpMovie a on a.MovieID=b.MovieID; --右连接A,6条+B4条 select * from #tmpMovie a right join #tmpDisk b on a.MovieID=b.MovieID; --右连接B,6条+A2条 select * from #tmpDisk b right join #tmpMovie a on a.MovieID=b.MovieID; --外连接A,6条+A2条+B4条 select * from #tmpMovie a full join #tmpDisk b on a.MovieID=b.MovieID; --外连接B,6条+A2条+B4条 select * from #tmpDisk b full join #tmpMovie a on a.MovieID=b.MovieID;

①:内连接,select ID from A inner join B on A.ID = B.ID,查询出 A中依赖于 B中有的,即是 A与 B共有的。

select ID from B inner join A on A.ID = B.ID,查询出 B中依赖于 A中有的。与上面一样。

内连,只查询出 A与 B中共有的数据,不会出现对应 ID为 null的情况。不完全的查询,没有 null的存在。

②:左连接:select * from A Left join B on A.ID=B.ID,先查询出 A的,再根据 A的结果查询 B,B中没 A的会以 A列为 null的形式出现。5 影 片

NULL NULL NULL

select * from B Left join A on A.ID=B.ID,先查询出 B的,再根据 B的结果查询 A,A中没 B的会以 B列为 null的形式出现。10影碟 8 NULL

NULL

左连接,只根据左表的 ID对应查询出右表的数据,右表不存在时将出现 null的情况。左全右不全

③:右连接:select * from A Right join B on A.ID=B.ID,先查询 B的,再根据 B的结果查询 A,B中没 A的会以 A列为 null的形式出现。

Select * from B Right join A on A.ID=B.ID,先查询 A的,再根据 A的结果查询 B,A中没 B的会以 B列为 null的形式出现。

右连接,只根据右表的 ID对应查询出左表的数据,左表不存在时将出现 null的情况。右全左不全

④:全连接:select * from A full join B on A.ID=B.ID,即是在查询出 A与 B共有的数据的同时,一并把 A有 B没有,B有 A没有的数据全部显示。

全连接,把 A、B表的数据全部显示,实际上是内、左、右连接的并集。共有的,两边独自的。笛卡尔积,

备注:凡是出现连接字段(主键没外键、外键没主键)的数据一律称为数据冗余。 23、SQL语句执行顺序

Page 160: Csharp

www.happy12.com 010-82387501

24、使用临时表标记# #temp,模拟转置效果 create table #tmp(rq varchar(10),shengfu nchar(1)) insert into #tmp values('2005-05-09','胜') insert into #tmp values('2005-05-09','胜') insert into #tmp values('2005-05-09','负') insert into #tmp values('2005-05-09','负') insert into #tmp values('2005-05-10','胜') insert into #tmp values('2005-05-10','负') insert into #tmp values('2005-05-10','负') insert into #tmp values('2005-05-11','负') select * from #tmp; 类型转换函数

Cast ,Convert;

insert into #tmp values (cast ‘string’ as datetime);

insert into #tmp values ( Convert (datetime,’strings’) );

where DateDiff ( dd , 开始时间,结束时间) =0 返回的是一个整数

笛卡尔积1(T1、T2都有共有K) select * from ( select rq, count(rq) a1 from #tmp where shengfu='胜' group by rq) a, ( select rq, count(rq) b1 from #tmp where shengfu='负' group by rq) b 笛卡尔积2 (T1与T2) select * from tbl_Type,tbl_Movie

isnull与 full outer join

select a.rq, b.rq, isnull( a.rq, b.rq ) AS 空 , a.胜, b.负 from ( select rq, count(*) as 胜 from #tmp where shengfu='胜' group by rq ) a full outer join ( select rq, count(*) as 负 from #tmp where shengfu='负'group by rq ) b on a.rq=b.rq cast select rq, count( case when shengfu = '胜' then 1 end ) as '胜', sum( case when shengfu = '负' then 1 end ) as '负' from #tmp group by rq pivot

select rq, [胜], [负], [胜] + [负] as 总场数 from #tmp pivot ( count( shengfu ) for shengfu in ( [胜], [负] )

Page 161: Csharp

www.happy12.com 010-82387501 ) as pvt

25、转置 转置一般有两种办法,一种是 case+聚合函数、分组,一种是 pivat

①:case when then 结合聚合函数与分组,值得注意的是结果字段要是没聚合函数修饰,那么就要在查询域后对 field进行分组 select [sid],

sum ([mark]) as 总分, avg ([mark]) as 平均分, avg ( case when [cid]=1 then [mark] end) as [database], avg (case when [cid]=2 then [mark] end) as [C#], avg (case when [cid]= 3 then [mark] end) as [xml] from tbl_marks group by [sid] –-对查询结果字段中没有聚合函数的字段进行分组修饰

②:pivot语句,

select 'AverageCost' as Cost_Sorted_By_Proction_Days,–-排除子查询只能够piovt中的字段就是剩下的唯一字段进行默认分组 [0], [1], [2], [3], [4] --对应的列 From -- 记得在查询域中不能包含non-pivoted column,即是除了最后单一分组字段,其余字段必须是pivoted column ( select DaysToManufacture, StandardCost

from Production.Product) as SourceTable PIVOT ( avg(StandardCost) -–对原来行的数据的目标列进行聚合函数的修饰 for DaysToManufacture IN ([0], [1], [2], [3], [4] –for old field in 集合

) ) as PivotTable;

Select *

From –- 筛选子查询字段信息,排除no pivoted 集合的 column ( select [sid], [cid], [mark] from tbl_marks) p pivot ( sum (mark) for [cid] in ( [1], [2], [3] ) ) as pvt

26、创建视图

在不影响任何关联应用程序的情况下对表进行更改,这种抽象化使安全性得以提高。而且可以封装一些复杂的查询,可以快速地获取所需要的数据。一般是 DBA来

设定数据库的视图, 封装内部数据库的数据关系,范式修改数据容易了,视图让我们查询复杂关系的数据变得容易。 create view vMoneyUsing as select * from MoneyUsing;

if exists (select * from dbo.sysobjects where id=OBJECT_ID(N'[dbo].[vMovieDiskTypeAll]') and OBJECTPROPERTY(id,N'IsView')=1)

drop view [dbo].[vMovieDiskTypeAll]; create view vMovieDiskTypeAll as SELECT tbl_Type.TypeID, tbl_Type.TypeCode, tbl_Type.TypeName, tbl_Type.TypeDate, tbl_Movie.MovieID, tbl_Movie.MovieCode, tbl_Movie.MovieName, tbl_Movie.MovieContent, tbl_Movie.MovieDate, tbl_Disk.DiskID, tbl_Disk.DiskCode, tbl_Disk.DiskCharge, tbl_Disk.DiskState, tbl_Disk.RentRecordID, tbl_Disk.DiskCount, tbl_Disk.DiskDate, tbl_RentRecord.RenRecordCode, tbl_RentRecord.AsscciatorID,tbl_Associator.AsscciatorCode,tbl_Associator.AsscciatorName,tbl_Associator.AsscciatorBalance,tbl_Associator.AsscciatorPhone, tbl_RentRecord.EmployeeID, tbl_Employee.EmployeeName, tbl_Employee.EmployeeTel,

tbl_RentRecord.RentRecordState, tbl_RentRecord.RentRecordDateStart, tbl_RentRecord.RentRecordDateEnd FROM tbl_Associator INNER JOIN tbl_RentRecord ON tbl_Associator.AsscciatorID = tbl_RentRecord.AsscciatorID INNER JOIN tbl_Employee ON tbl_RentRecord.EmployeeID = tbl_Employee.EmployeeID RIGHT OUTER JOIN tbl_Disk ON tbl_RentRecord.DiskID = tbl_Disk.DiskID RIGHT OUTER JOIN tbl_Movie ON tbl_Disk.MovieID = tbl_Movie.MovieID RIGHT OUTER JOIN

tbl_Type ON tbl_Movie.TypeID = tbl_Type.TypeID select * from vMovieDiskTypeAll;

27、创建函数 function create function MathMax (

Page 162: Csharp

www.happy12.com 010-82387501

--1、定义参数 @a int , @b int ) RETURNS int –2、声明返回的数据类型 AS BEGIN declare @max int if(@a > @b) begin set @max= @a; end else begin set @max=@b; end return @max –3、返回值 END GO Select dbo.MathMax(dbo.MathMax(3,4),5) 28、创建索引

数据库 DB就像是一个字典,索引就是根据指定字段制成的快速指向。由于只是指向数据对象标识,真正的数据是存储在 DB中,所以查询速度极快。但是额外的

内存与硬盘花销也是一个需要考虑的问题。比如:增加、删除、修改时数据库都要对索引进行维护,但是这样也是为了最后查询的效率的提升,特别适合W行级别

的数据查询。而索引可以分为:隐式索引(针对单个字段)、唯一索引(唯一约束)、函数索引(函数(字段))与聚簇索引 clusrered(主键)。

<1>视图创建索引

<2>代码创建索引

①:隐式索引: create index ixTableColumn on table(column) ②:唯一索引

不允许具有索引值相同的行,从而禁止重复的索引或键值。系统在创建该索引时检查是否有重复的键值,并在每次使用 INSERT 或 UPDATE 语句添加数据时进

行检查建立唯一约束的时候自动生成(而且 unique关键字是可以用在聚簇与非聚簇索引中的) create unique index ixTableColumn on table(column) ③:函数索引(函数(field)):

create index ixTableColumn on table( upper(column)) ; ④:聚簇索引

使用聚簇索引查找数据几乎总是比使用非聚簇索引快。每张表只能建一个聚簇索引,并且建聚簇索引需要至少相当该表 120%的附加空间,以存放该表的副本和索

引中间页。

一般使用对象:主键列,该列在 where子句中使用并且插入是随机的;按范围存取的列,如 pri_order > 100 and pri_order < 200;在 group by或 order by

中使用的列;不经常修改的列;在连接操作中使用的列。 create clustered index ixTableColumn table(column) 但是此时如果表中有重复的记录,当你试图用这个语句建立索引时,会出现错误。

有重复记录的表也可以建立索引;你只要使用关键字 allow_dup_row create clustered index ixTableColumn table(column) with allow_dup_row

⑤:组合索引

对 N个字段建立了一个索引。在一个复合索引中,你最多可以对 16个字段进行索引。 create index ixTableColum1Column2 ON table(column1,column2)

⑥:全文索引(针对超长文本,一般是博文 text):

全文索引条件:表中的含有唯一约束(唯一索引)的列可以升级为全文索引,但是每个表只可以有一个全文索引,存放在指定的索引目录里,可以通过向导创建,也可

以通过 SQL创建。

1、 启动全文索引

Page 163: Csharp

www.happy12.com 010-82387501 use MoviesDB; exec sp_fulltext_database 'enable'

2、创建全文目录(fulltext catalog 存放全文索引的文件)

create fulltext catalog ixCatalog

3、创建唯一索引 (unique) create unique index ixTableColumn1 on table(column)

4、创建全文索引 (fulltext index)

create fulltext index on table(column1,column2)key index ixTableColumn1 on ixCatalog

注:ixTableColumn1 是指已存在的基于指定表的唯一索引名.而不是唯一索引列名.如果索引不存在,需要先创建唯一索引.

代码创建索引成功后回出现:This command did not return data,and it did not return any rows (此命令不会返回行数据)

5、使用全文索引 (select contain freetext)

主要使用 contains,freetext 进行查询假设已有一个表 table,已为字段 field 创建全文索引,那么要查询含有周杰伦或者 jay的所有记录的语句为:

select * from table where contains(field,'"周杰伦" or "jay"') 也可以使用匹配模式进行包含条件组合,还可以使用 and连接条件.

<3>使用索引

索引一旦创建成功,需要修改时必须先删除再创建:

一般执行查询的时候数据库系统会自动调用索引。 Drop index table.ixTableColumn

<4>全文索引扩展(使用系统存储过程) http://hi.baidu.com/wnq0204/blog/item/e89b9725fe4b106734a80f82.html

1、 库

exec sp_fulltext_database 'enable'—启用全文索引功能 2、 目录

exec sp_fulltext_catalog 'ixTableColum','drop'--删除 exec sp_fulltext_catalog 'ixTableColum','create'--创建 3、表

exec sp_fulltext_table 'table','create','catalog','column'--创建 exec sp_fulltext_table 'table','active','catalog','column'—启动 exec sp_fulltext_table 'table','start_full','catalog','column'—同上 exec sp_fulltext_table 'table','deactive','catalog','clumn'—冻结 exec sp_fulltext_table 'table','drop','catalog','clumn'—删除 4、列

exec sp_fulltext_column 'table','column','add'--添加 exec sp_fulltext_column 'table','column','drop'—删除 5、检查填充情况

While fulltextcatalogproperty('catalog','populateStatus')<>0--检查全文目录填充情况 begin waitfor delay '0:0:5'--如果全文目录正处于填充状态,则等待秒后再检测一次 END 6、使用全文索引(调用关键字 contain、freetext)

select * from table where contains(column,'美赞臣'or ‘宝洁’) –显式使用全文索引查询

29、创建事务

很多时候我们的操作都不是一步完成的,而是由多次的修改插入删除所完成的

在银行数据库里面 ,张三存了1W ,那么转账呢? 那么得至少写两条SQL语句 防止程序出现灾难与数据错误,所以在高度自动化的时代,我们就必须搞好。五角

大楼的事务例子,利用计算机技术去处理,

一般是从4个方面去理解。ACID

A、 原子性 就是执行的时候要么整个完成,要么整个失败,就是两条语句构成一个整体,C#是不支持的,而且不论什么状态下都高度保持这样的原子性

B、一致性 指的是数据库是一条条的执行,但是在外部观察不会出现瞬时的不同步,也就是说我们在任何时候查询数据库,就是转得时候也是已经完成业务的(不

论什么时候查询,都是保持一致的,就是业务都是执行完毕的,保证瞬时执行的完整性)

Page 164: Csharp

www.happy12.com 010-82387501

I、隔离性 就是虽然是一条条地改,但是对于事务外的对象是完全隔离的,但是外部查询是依赖于一致性的,在事务之外是查询不到的。但是Oracle是可以做到的,

还是可以直接查询

D、持久性 一旦事务提交成功那么堆事务的修改是持久更新的,不会因为断电而悲剧。将被持久地存下来。需要DBA提供后备的支持的。支持多种方式的,分布式

的话,就是同时在4个地方存储,银行不是那么低级地存得,要求全部都是实时的备份

create database myBankDB; use myBankDB; create table bank ( 账户 int identity(1,1), 存款 int ) begin transaction insert into bank values(10000); insert into bank values(10000); insert into bank values(10000); select * from myBankDB.dbo.bank; update myBankDB.dbo.bank set 存款=20000 where 账户>10 and 账户<55; delete from myBankDB.dbo.bank; commit; rollback; 开始执行了begin transaction

再执行一半的语句这个时候

停止服务rollback,就会返回原来执行那一条的状态

直到运行至commit才完成事务,要不系统自动回滚

ALTER procedure [dbo].[prReturnDisk] ( @EmployeeID int, @RentRecordID int, @Account int ) as declare @AccountRecordCode nvarchar(50) declare @RentRecordState int declare @DiskID int declare @DateStrat datetime declare @DateEnd datetime declare @Cost float begin try begin transaction select @AccountRecordCode=MAX(AccountRecordID)+1 from tbl_Account;--获取编号 select @RentRecordState=tbl_RentRecord.RentRecordState from tbl_RentRecord;--判断租借记录 if @RentRecordState = 1 begin insert into tbl_Account (AccountRecordCode,EmployeeID,RentRecordID,Account) values('Account'+@AccountRecordCode,@EmployeeID,@RentRecordID,@Account);--还碟子 update tbl_RentRecord set RentRecordState=0,RentRecordDateEnd=GETDATE() where RentRecordID=@RentRecordID; select @DiskID=DiskID,@DateStrat =RentRecordDateStart,@DateEnd=RentRecordDateEnd from tbl_RentRecord where RentRecordID=@RentRecordID; select @Cost=((dbo.fnGetDate(@DateStrat,@DateEnd))*(select tbl_Disk.DiskCharge from tbl_Disk where DiskID=@DiskID)); update tbl_Disk set DiskState=0,RentRecordID=0 where DiskID=@DiskID; if @Account>@Cost begin update tbl_Associator set AsscciatorBalance=AsscciatorBalance+(@Account-@Cost) where AsscciatorID=(select AsscciatorID from tbl_RentRecord where RentRecordID=@RentRecordID); end end commit; end try begin catch rollback end catch

30、创建存储过程

不同的数据库的语言也是不同的,MSSQL的是 TSQL ,存储过程一般是解决复杂的业务逻辑操作(一般是多表的操作)的问题。Oracle的 PLSQL。在 oracle就

Page 165: Csharp

www.happy12.com 010-82387501

没有返回值,但是 MSSQL 有。返回值不是普通的返回值,这个一般不返回计算的结果,一般仅仅是返回整数的类型,若果没有显示返回结果,默认为返回 0,一

般是判断存储过程的执行状态。

<1>单纯的传参 create procedure proc_test ( @NewName nvarchar(20), @OldName nvarchar(20) ) as begin transaction begin try if exists (select Movie_Name from tbl_Movies) return 0; commit; else begin rollback; end end try <2>传参与返回值 output create procedure proc_test ( @NewName nvarchar(20), @OldName nvarchar(20), @Name nvarchar(30), @number int output ) as begin transaction begin try --scope_identity()--标识当前作用域中新创造的主键 --insert之后马上获取当前状态的唯一标识的问题 declare @key int; set @key =scope_identity();--赋值 select @key=scope_identity();--赋值 --但是临时变量@key仅仅在与自己的作用域中,要赋值给传出参数 set @number = @key; commit; end try begin catch rollback; end catch --执行 declare @Pan int; execute @Pan = proc_test 'a','B','C',@number output; print @Pan;--打印,return的 print @number;--返回的 执行存储过程的名字

Execute proc_name parmmarys ;

Execute proc_UpdateName '精武门','新版精武门' ;

31、创建触发器

触发器(trigger)是个特殊的存储过程, 它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行操作( insert,delete, update)

时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。 触发器可以从 DBA_TRIGGERS ,USER_TRIGGERS 数据字典中查到。

触发器可以查询其他表,而且可以包含复杂的 SQL 语句。它们主要用于强制服从复杂的业务规则或要求。例如:您可以根据客户当前的帐户状态,控制是否允许

插入新订单。 触发器也可用于强制引用完整性,以便在多个表中添加、更新或删除行时,保留在这些表之间所定义的关系。然而,强制引用完整性的最好方法是在

相关表中定义主键和外键约束。如果使用数据库关系图,则可以在表之间创建关系以自动创建外键约束。

触发器,可以自己定义,一类是系统级触发器(数据库系统级别),一类是表触发器。 alter trigger [dbo].[tbl_Employee_AspNet_SqlCacheNotification_Trigger] on [dbo].[tbl_Employee] for insert, update, delete as begin set nocount on

Page 166: Csharp

www.happy12.com 010-82387501 exec dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure N'tbl_Employee' end

微软在 framework4.0中 asp.net_regsql.exe用命令行执行 C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regsql.exe

aspnet_regsql –S WIN-0E92J4Q2A85 –E –d MoviesDB –ed ——启动依赖项

aspnet_regsql –S WIN-0E92J4Q2A85 –E –d MoviesDB –lt ——显示监听表

aspnet_regsql –S WIN-0E92J4Q2A85 –E –d MoviesDB –t tablename –et ——为表建立监听触发器

32、时间函数

参考网址:http://wenku.baidu.com/view/b783860c6c85ec3a87c2c5b1.html <1>datepart部分时间提取函数,返回表示指定 date 的指定 datepart 的整数。

datepart (datepart,”datetime”)

SELECT DATEPART(YY,'2007-10-30 12:15:32.1234567 +05:10') <2>datediff时间间隔函数,返回指定的 startdate 和 enddate 之间所跨的指定 datepart 边界的计数(带符号的整数)。 datediff(datepart,stratdate,enddate)