java基础入门

1. 基本数据类型

    基本数据类型分为8类:
    
    整数类型:
    byte   ..... 字节型 长度8位.  -2^7  ~ 2^7  - 1
    short  ..... 短整型 长度16位. -2^15 ~ 2^15 - 1
    int    ..... 整型    长度32位. -2^31 ~ 2^31 - 1
    (java中默认所有数字都为int型)
    long   ..... 长整型 长度64位. -2^63 ~ 2^63 - 1
    
    浮点类型(小数):
    float  ..... 单精度浮点类型 长度32位.
    double ..... 双精度浮点类型 长度64位.(java中默认所有的小数都是double型)
    
    字符类型(Unicode码):
    char   ..... 字符类型 长度16位  0 ~ 2^15 - 1
    (char类型可以当作一个特殊数字类型,
      因为在底层char是数字进行存储,并且只有正数.)
      
    布尔类型(逻辑类型):
    boolean .... 只有两个值(字面量) true/false.
    
    包装类:
    除int类型外,其他基本类型的包装类都是将类型首字母大写.
    只有int类型的包装类的名字是 Integer.
        
    自动类型转换:
    当小类型数据向大类型数据过度时,java会自动将小类型转换为大类型.
    byte --> short --> int --> long --> float ---> double
    
    byte --> short --> int --> float --> long ---> double
    
    强制类型转换:
    当大类型数据向小类型数据过度时,java不会自动转换类型,需要强制将大类型转换
    为小类型.
          (int)       (short)         (byte)
    long ------> int --------> short -------> byte
    
2. java中的转意字符
    反斜线(\)是java中的转意字符,它可以改变符号后第一个字符的含义.

3. java中的运算符

    3.1 算术运算符
        加法(+)
        减法(-)
        乘法(*)
        除法(/)
        取余(%)
        例题: 将数字123颠倒成321.
        优先级:
      *、/、% 优先级大于 +、-
      
       自增/自减运算符 ++/--
       在计算的时候
       1.如果符号在前(++/--i)则先进行算数运算,
             然后将计算的结果作为下一步操作的值.
       2.如果符号在后(i++/--)则先用变量的原值进行
             其他操作,待操作完成后进行自增或自减运算.
        
   *3.2 逻辑运算符
        逻辑与(&/&&)
        逻辑或(|/||)
        逻辑非(!)
        
    3.3 三目运算符(三元运算符)
      ?___:___
    
    3.4 复制运算符
       赋值运算符(=)
       赋值运算符的优先级是最低的.
       执行顺序是将符号 右侧 的值赋值给 左侧 的变量
       
    3.5 比较运算符
      大于(>)
      小于(<)
      大于等于(>=)
      小于等于(<=)
      恒等于(==)
      不等于(!=)
    
    运算符的优先级:
    算数运算符 > 比较运算符 > 三目运算符 > 逻辑运算符 > 赋值运算符



1.从键盘键入数据到程序中
    1.1 Scanner工具
        next():
                接收从键盘输入的文字信息,
                遇到空格则 停止记录 但是没 停止输入.
                只有遇到回车时停止输入.
        nextLine():
                接收从键盘输入的文字信息,
                遇到空格时不会停止记录,
                只有遇到回车时停止输入.
                但是,它会接收从上一次输入遗留下来的回车.
        hasNextInt():
                判断当前输入的内容,是否是指定的类型.
                若输入内容类型正确,则返回真,否则返回假.
                不论输入的内容类型是否正确,都不会拦截输入的内容.
                
2. 随机数Math.rondam()
     随机数默认范围是从0.0~1.0 是double数字,并且随机数不会等于1

3. 类的方法
    方法的组成:
    
    修饰符 返回值类型 方法名(参数类型1 参数名称1, ...参数类型n, 参数名称n){
        方法体...
    }        
    
    public static void main(String[] args){
        ....
    }    
    
    return关键字.    
    
4. 选择结构
    4.1 if语句
    
        * if语句后的代码如果只有一行,可以不写大括号({}).
        
        4.1.1 if(条件){
                  语句...
              }
                多个条件用逻辑运算符连接.
                当条件成立(条件的结果为真)的时候,执行大括号中的内容.
                
        4.1.2 if(条件){
                语句1...
              }else{
                  语句2...
              }
              当条件成立时,执行语句1.否则执行else后语句.
        4.1.2 if(条件){
                语句1...
              }else if(条件2){
                  语句2...
              }else if(条件3){
                  语句3...
              }else if(条件n){
                  语句n...
              }else{
                  else语句...
              }
              无论哪个条件成立,或者那些条件成立,整个if嵌套只执行一个分支.
              如果所有的条件均不成立,执行else的语句(else不是必须存在的).
              如果不存在else分支,并且所有条件均不成立,则该if分支不会执行.
            
             && 中断逻辑与
              条件1 && 条件2
              当条件1和条件2同时成立的时候整个表达式才成立.
            


1. switch(key)...case:(值)...分支结构
    key的类型:
        在JDK1.6以前只能是字符类型(char)或者是整数类型(int).
        在JDK1.6之后(包括1.6)扩展到支持String类型.
2. 循环结构
    死循环,理论上是无限次数的循环.
    break关键字:
    break终止并跳出(结束)当前循环.一般情况下只应用于循环当中.
    2.1 while循环
        结构:
        while(条件){
            循环体...
        }
        执行过程:
        1. 当条件成立时,执行循环体.
        2. 当循环体执行完毕,则判断条件是否成,若成立则再次执行循环体
              若不成立,则跳出循环.
              
            练习:
        随机生成一个1~10之间的数字.从控制台输入数字与之比较,
        若输入的数字大于生成的数字则显示 大了,
        反之若小于随机的数字显示 小了,若等于则显示猜中.
        最多可输入3次.
        分析:
        1. 随机数每次程序运行只生成一个.
        2. 存在一个循环逻辑,循环的次数是固定的3次
        3. ⑴  每次循环输入一个数字.
               校验每次输入的内容是否是整数.
               如果输入的不是数字,不记录在猜数次数.
           ⑵  每次输入的数字都与唯一的随机数进行比较,显示结果.
        
    2.2 for循环
        结构:
        for(条件1;条件2;条件3){
            循环体....
        }
        执行顺序:
        1. 条件1的位置一般情况下是循环变量的初始化
              在for循环当中条件1只执行一次.
        2. 判断条件2是否成立,如果成立则执行循环体中代码.
              如果条件2不成立,则跳出(结束)循环.
        3. 当条件2成立,执行循环体.当循环体执行结束时,执行
              条件3中的语句.
        4. 条件3中的语句执行完成之后,再次判断条件2是否成立.
        特殊写法:
        for(;;){
            
        }
        以上的写法默认为死循环.



1. continue关键字
    使用在循环当中,用于结束本次循环,立即执行下一次循环.
 
2. do...while循环
    结构:
    do{
        循环体...
    }while(条件);
    特点:
    无论条件是否成立,都会执行一次循环体.
    执行顺序:
    1. 执行循环体.
    2. 判断条件.
    3. 条件成立则再次执行循环体.
    4. 条件不成立则结束循环.

3. 数组(引用类型)
    3.1 数组的声明
    类型[] 变量名 = new 类型[长度]. // 动态声明
    或
    类型 变量名[] = new 类型[长度]. // 动态声明
    或
    类型[] 变量名 = {元素1,元素2,...元素n};  // 静态声明
    类型[] 变量名 = new 类型[]{元素1,元素2,...元素n};
    
    数组中的内容的类型必须是相同的.
    特点:
    1. 数组的长度一旦确定了之后就不可更改了.
    2. 数组中的元素,会存在默认值.
       int类型: 0
       double类型: 0.0
       char类型: 0(int类型的)
       boolean类型: false
        异常:
        数组下标越界:java.lang.ArrayIndexOutOfBoundsException
        这个异常(错误信息)表示当前获取的数组元素下标超过了数组的长度或者小于0.

        
    3.2 Arrays工具类
    toString()方法
    显示数组中的所有元素.
    Arrays.copyOf(original, newLength)
    复制数组中的元素并且返回一个的数组
    参数original : 被复制的数组
    参数newLength: 新数组的长度
    
    3.3 数组的复制
    System.arraycopy(src, srcPos, dest, destPos, length);
    参数src      : 被复制的数组.
    参数srcPos   : 从被复制的数组的第几个元素开始复制.
    参数dest     : 复制到哪个数组.
    参数destpost : 复制到目标数组数组的那一位后.(原来位置的数据会被覆盖)
    参数length   : 复制的长度.
    
4. java的内存机制
    java在内存中存储数据的时候,是以堆和栈的形式存储.
    4.1 栈
    一个有序的排列空间.在栈中存储的数据遵循着先进后出的原则.
    java中的基本类型变量存储在栈中.
    
    4.2 堆
    一个很大的无序空间.用于存储引用类型的值.
    每次在需要使用堆空间的时候,需要使用new关键字进行空间开辟.
    类型       引用名      开辟空间
    int[] array = new int[5];
    引用名是存放在栈中,引用的实际值是堆中开辟的空间的地址
5. 排序的效率
    选择排序的效率会略率的比冒泡排序要低一些.
    效率最好的排序是Arrays.sort()
    局限于升序排序.



1.面向对象:
  1.1 (OOP)Java中一切皆是对象.
      类:    具有一系列相同的属性和行为的结合体.
                    例如: 人类
                    特点: 鼻子,眼睛,嘴
                    行为: 吃饭,睡觉,打豆豆.
      对象:  某个类型中的实体(具现化).
               例如: 张三
               特点: 姓名,身高,体重
               行为: 走路,唱歌,跳舞.
             
  1.2 Java中的类与对象
      
      类:    定义一个类型的时候,在java中需要使用关键字class
               类型中会存在(特点)属性和(行为)方法
               案例: 定义一个点类型.
               特点: 坐标(x, y)
               语法: [访问类型(public)] class 类型名{...}
               
        类的属性: 称之为全局变量,在整个类当中任意位置都可以使用.
        
        对象: 类的对象是通过关键字new来生成的.实际上告诉系统在堆开辟
                   一块空间创建对应的类型的实例.
                   (变量名)
                   语法: 类型名 类的引用/引用变量 = new 类型名();
                   
        全局变量: 当变量类型为基本类型时,系统会赋值初始值.
                          初始值与数组中是一样的.
        
        局部变量: 不允许存在访问修饰符,并且在声明之后使用之前必须赋值.
                          系统不会为局部变量赋初始值.
        方法中的变量:在方法中定义的变量,称之为局部变量.
        在一个类当中局部变量可以与全局变量的变量名相同.
        在java中变量在查找其对应的声明时,是选择离该变量最近的声明叫做就近原则.
        
        构造方法: 构造方法是用于创建对象时使用的.
                          语法: public(访问修饰符) 类型名(){...}
                          注意: 构造方法没有返回值类型。
                          特点: 1.每一个类(class)都必须存在构造方法.
                                         当类中没有书写构造方法时,java会自动加上一个
                                         无参的构造方法.
                 2.构造方法可以为类的属性赋值.
                 3.当类存在构造方法时,java将不会再自动为其添加
                                         无参构造方法.
                 4.一个类中可以存在多个构造方法(参数列表不能重复).
                 5.构造方法可以被重载(名称相同,参数列表不同)
                          重载: 参数列表不能相同无论是,参数的个数或是类型均不能相同.
                                     只要参数个数或者参数类型中有一个不同即可.
    this:关键字
        表示的是本类中的属性或方法.
        例如:
        this.变量名  :表示的是类的属性
        this()     :表示的是类的无参构造方法.
        this.方法名   :表示的是调用类的方法
        
        类的方法: 指的是一个类型中,存在的相同的行为.
                                                方法签名
        方法声明: 访问修饰符 返回值类型/void 方法名(参数列表){...}
        方法特点: 每一个方法中都存在return关键.即使是void类型的方法
                          也是存在return.只不过在void类型下return可以不写.
                           
        返回值:   方法的返回值类型可以是任意类型.当方法调用结束的时候,
                           方法的返回值回到方法的调用处.
        参数类表: 1.参数的类型可以是任意类型.
            2.参数的个数可以有很多个.(建议:参数个数不要超过4个)
            3.参数可以是其他方法的返回值.
   
        方法的重载:
                         在类中的普通方法声明时,访问修饰符与返回值类型以及方法名相同
                         并且方法签名(参数类表)不同的方法称之为方法重载.
                         参数类表的个数或者类型中只要存在一条不相同即可.
                         
        方法重载的调用:
              根据方法的参数列表来选择调用哪一个方法.



java.lang.NullPointerException 空指针异常
 表示当前对象的引用中没有任何对象的地址,其内容是空的.
 
 foreach循环(超级for循环)
 语法结构:for(类型 引用名 : 数组/集合){...}
 每一次循环会生成一个对象,直到循环的数组/集合中的元素全部被提取一次.



1. 类的加载机制
   Java代码先通过编译生成对应的.class文件
      在运行时,JVM(java虚拟机)会将生成的.class文件
      装载进来.
      在使用关键字new创建对象的时候,JVM会找出对应的.class文件
      作为对象的模版,然后根据模版中的内容进行创建.
      在创建的过程中:
   1.首先创建类的属性(此时只创建属性的引用,并不赋值).
   2.然后创建类的方法.
   3.如果构造方法中存在参数,将参数赋值到对应的属性上.
          如果没有参数,则类的属性为默认值.
          默认值:
          基本类型时,默认值为对应类型的字面量(数字类型:0,布尔类型:false).
          引用类型时,默认值为空引用(null).
          注意:String是一个特殊的引用类型.
   4.当构造方法运行结束时,对象创建完成将创建好的对象的引用赋值到引用变量中.

2. 继承
   在java中继承体现在两个类之间的关系上,某一个类可以通过继承另一个
      类来获取属性以及方法.
   1. 通过关键字extends实现类与类之间的继承关系.
   2. 作为子类可以获取父类中的属性以及方法.
   3. 每个类只能继承一个类.
      案例:
      创建图形父类,使用圆和矩形两个分别继承图形类.
      
      父类的引用可以创建子类的对象,但是引用不具有子类特有的属性.
      子类中与父类同名的属性会覆盖掉父类中同名的属性.
      子类可以继承到父类中公开的属性.  
      
      子类在创建对象的过程中也就是在调用子类构造器的时候,
      会默认调用父类的无参构造器.
      在子类当中使用super关键字可以调用父类的构造器、属性以及方法.



1. 方法重写(方法覆盖)
      定义:指的是子类中存在与父类相同的方法,并且子类有自己独立的执行逻辑时,
               子类中的方法会默认的覆盖掉父类的方法并重新构造方法中的执行逻辑.
      特点:1.子类的方法签名和返回值类型与父类的一致.
       2.父类的方法可以被子类继承.
      标签:@Override
               表示当前方法来自父类,并且覆盖掉父类中的原方法也就是说在子类的对象
               中使用的是子类的方法.
               注意:这个关键字只在JDK1.5以上版本识别.
               规范:默认情况下凡是没有特殊要求的方法覆盖,必须添加@Override标签.
               
      当子类当中的方法覆盖掉父类的方法时,不论是父类的引用还是子类的引用都会调用
      创建的子类对象的方法.            
   
      引用类型在使用双等号进行比较的时候 (==)比较的是两个对象的引用变量的值(地址值)
      如果想要比较引用类型的对象的值使用equals方法进行比较.
      如果两个对象的地址值相同,那么说明是同一个对象.

2. 访问修饰符
    可修饰范围: 可以修饰类(class)、方法、全局变量
    访问修饰符分四种:
    public(公共的): 作用范围在代码中的任意位置都可以访问.
    protected(保护的): 只能在同一个包中访问.(不能修饰类)
    默认的: 只能在同一个包中访问.
    private(私有的): 只能在本类中访问,一般情下类是没有私有类(class).
        注意:在java所有非内部类的类在没有特殊要求的情况下都是用public修饰.
                 子类中覆盖父类的方法时,子类方法的访问类型不能小于父类的方法的修饰类型.
 
      下表只针对被修饰的属性和方法.
             本类中  子类中  不同包的子类 不同包中其他类
   public      √     √        √            √
   protected   √     √        √            ×
   defualt     √     √        ×            ×
   private     √     ×        ×            ×
   
3. JavaBean规范
      在规范中定,所有类的属性在没有特殊要求的情况下全部对外不可见
      也就是属性的访问类型为private.
      类的属性被设置为私有类型,需要在类中为其添加get/set方法操作
      属性的值.
   get/set方法:
   get方法的返回值为属性的类型.
      方法名:get + 属性名(首字母大写)
   set方法的返回值类型为void
      方法名:set + 属性名(首字母大写)
      当属性为boolean类型的时候
   set方法的方法名分为两种:
   1.set + 属性名(首字母大写)
   2.is + 属性名(首字母大写)



1. static关键字(静态的)
    类级别的修饰符.
    修饰属性:
    当static用来修饰属性的时候, 它的修饰级别是在类当中.
    被static修饰的属性,只要是该类的对象那么将公用这个属性.
    static修饰的属性是在类加载时生成.
    修饰方法:
    用static修饰的方法,是属于类的方法.同样的当前类的所有对象
    公用被static修饰的方法.
    static的方法也是在类的加载中创建的.在静态方法中只能调用其他
    静态方法或者静态属性.如果想要使用对象的属性或方法,需要在方法中
    创建该类型的对象,通过对象去调用属性或方法.
    代码块:
    对象在创建的时候会自动执行的一段代码区域的代码.它的执行优先级
    高于构造方法.
    静态代码块:
    在类的加载的时候执行的代码块.因为每一个类型只被加载一次,所以静态
    代码块在程序中,一次运行只执行一次.无论创建多少个对象也只在创建第
    一个对象时通过类的加载而执行.
    总结:凡是被static修饰的属性、方法、代码块只在类的加载时创建或执行.
        一个类只会存在一个,无论创建多个对象使用的都是同一个属性或方法.
        作为静态代码块则是,无论创建多少个对象都只执行一次.
    注意:静态的方法或属性,只能调用静态的方法或属性.若要调用对象的属性或
        方法需要在方法中创建被调用的类的对象.
    使用:在使用静态方法或属性的时候,不需要创建所在类的对象,只需要用类名
        进行调用即可.
    
2. 常量
    常量指的是不可变化的变量,或者是固定值.
    常量大多是类的属性,并且是静态属性.
    规范:
        常量的命名所有字母都是大写.

3. final关键字(最终的)
    1. final修饰变量
        final修饰的变量是在初始化之后,不能再次更改.
        当修饰的是引用类型变量的,对象中的属性可以改变.
        但是不能变换引用类型变量的值,也就是不能重新生成对象.
        1.1 修饰局部变量
            可以初始化,初始化之后不能再次修改.
        1.2 修饰方法参数
            在方法被调用的时候,可以传递任意同类型的值,但是在方法中
            不可对final修饰的参数做修改.
        1.3 修饰全局变量(对象的属性)
            可以初始化,初始化之后不能再次修改.
        1.4 修饰静态属性
            相当于创建一个常量.
    2. final修饰方法
        Cannot override the final method.
        在子类中是不可以覆盖父类中被final修饰的方法.
        父类中被final修饰的方法在访问修饰符允许的情况下可以在子类使用.
    3. final修饰类
        The type ZooChild cannot subclass the final class Zoo.
        当类被final修饰的时候,表示该类不可以被继承.



1. Object类---一切皆是对象.
    是所有类的父类,即使是自定义类也会默认继承Object类.
    在java中的一切皆是对象,实际意义就是指所有类继承object.
    
    Object类提供了很多为对象服务的方法.
    
    1.1 toString()方法
        默认的toString()方法是用来显示类的完整类名(包名 + 类名)
        加上根据地址值通过哈希算法生成一组整型数字.
        当想要指定对象的显示结果时,覆盖掉toString()方法即可.
        
    1.2 equals()方法
        默认用于比对两个对象的地址值是否相同,来源于Object类.
        在Object类中,equals()方法默认判断当前对象的引用变
        量值是否恒等于(==)目标对象的引用变量值.
        变量之间做恒等于(==)的判断时,实际上是判断栈中两个变量
        的值.
        作为引用变量,栈中存放的是对象的地址.所以默认的比较就是
        比较两个对象的地址值.
        只有在比较的双方是同一个对象的时候,它们的地址值才会相同.
        当子类覆盖equals()的时候,子类中的方法参数是Object类型的.
        不仅仅是子类的类型,默认的equals()可以与任意对象比对.
        
        如果两个对象的恒等于(==)结果为真,那么这两个对象的equals的
        结果也一定为真.
        
        在覆盖equal方法的时候,默认也要将hashCode方法覆盖.
        
        1.2.1 instanceof 关键字
        语法: 判断对象 instanceof 目标类型
        作用: 判定对象是否是属于目标类型,如果属于返回结果为ture
              反之则返回false.
    
    1.3 hashCode()方法.
        默认返回一组通过对象的地址值,再经过哈希算法生成的一个整数值.
        整数值是以十六进制形式体现.
        可以假设hashCode就是地址值.当两个对象equals相同时,我们认
        为两个对象是同一个对象,也就是说应该存在想同的hashCode.
        所以当覆盖equals方法时,要将hashCode方法一起覆盖.
        覆盖hashCode方法时,要保证每一个不相同对象的hashCode值不能
        相同.也就是说hashCode是唯一的.

2. 抽象类(abstract)
    具有抽象方法的类,抽象类中的抽象方法是由子类实现的.
    抽象类中如果存在抽象方法,不能直接创建对象.只能创建
    子类的对象.
    抽象类当中存在构造方法.构造方法是为子类创建对象时子类
    的构造方法调用的.
    2.1 抽象方法
    在方法前使用abstract关键字进行修饰.
    抽象方法不存在方法体,也就是说没有实际的方法功能.
    只是提供方法的概念.方法的具体实现是通过子类继承实现的.
    
    2.2 继承抽象类
    继承抽象类的时候,作为子类必须覆盖父类中的所有抽象方法.
    父类中的普通方法可以不覆盖.
    
    2.3 抽象类的属性
    抽象类的属性与普通类的属性定义是一致的,可以存在任意访问
    类型的属性,也可以存在常量.
    
3. 接口(interface)
    抽象类中可以存在普通方法,接口当中只有抽象方法.
    并且接口中的方法不需要使用abstract关键字修饰.
    并且接口中的方法访问类型默认都是public类型.
    接口不是抽象类.
    可以理解成一个全是抽象方法的超级抽象类.但是接口
    实际上不是抽象类,接口是定义了某些功能开发规范.
    一个类可以实现多个接口.
    接口中的属性默认的全都是常量(static final修饰的).
    接口的实现类是使用关键implements.并且一个类可以实现
    多个接口.
    
    抽象类可以实现接口,并且可以将接口中的部分方法实现.将
    剩余部分的方法留给子类实现.
    
    一个类在继承另一个类或者抽象类的时候同时还可以实现其他接口.
    java当中单继承,多实现.而且可以同时存在.
    当一个类同时存在继承和实现关系时,一定是先继承再实现.



1. String类
    特殊的引用类型,其他的引用类都是通过new关键字创建对象.
    唯独String是一个特例,它可以像基本类型一样通过等号直接
    赋值对象.(可以不是用new关键字).
    特点:
    String的底层是一个char类型的数组.
    特性:
    1. String的构造方法中可以传递另一个字符串作为参数.
    2. 在创建一个字符串的时候,现在堆当中开辟一块空间装字
          符串.如果没有使用new关键字创建另一个相同内容的字
          符串的时候,会把原有的字符串的地址赋值给新的引用.
    3. 原字符串与new关键字创建的字符串(内容相同),equals
          比较相同但是恒等于(==)不同.
    4. 当两个字符串进行连接操作(+)的时候,除了生成两个需要连接
          的字符串对象以外,还有一个是连接之后的结果字符串对象.
          任何数据与字符串连接的时候,连接的结果都是字符串类型.
          双引号表示一个空字符串("").
    5. 当字符串中的内容为中文的时候,可以通过getBytes的方法转换
          成二进制数组.数组的内容是字符串的内容的字符编码.默认的编码
          格式是根据当前操作系统决定的.
       GBK:格式的中文字符每个字符占2个位置.
       UTF-8:格式的中文字符每个字符占3个位置.
       ISO-8859-1:格式的中文每个字符占1个位置.
       (Windos系统:GBK/GB2312,Linux系统:utf-8)
       (国际标准格式:ISO-8859-1)
    6. String类是final类型的.它不能被继承.
          
    属性:
    count属性,表示的是当前字符串的长度.
    (私有属性,如果需要使用当前字符串长度,调用length()方法.)
    
    1.1 String类中的常用方法.
        *length();
            返回字符串的长度,空字符串("")的长度是0.
        concat(String s);
            将目标字符串拼接在当前字符串之后.
        *charAt(int index);
            返回所在index位置的字符,类型是字符(char)类型.
        *indexOf(String s);
            返回当前字符串中,要查找的字符/字符串的位置.
            如果该字符串中存在多个查找的目标,则返回第一次
            找到该字符或字符串的位置.
            若没有找到对应的内容则返回-1.
            当查找的内容是一个字符串的时候,返回的是查找内容的
            第一个字符所在的位置,表示的是从该字符位置开始匹配的.
            匹配空字符串的时候,返回的是第一位(0)
        *lastIndexOf(String s);
            返回当前字符串中,最后一次出现目标字符或字符串所在的位置.
            匹配空字符串返回的是当前字符串的长度.
        *subString(int startIndex [, int endIndex]);
            截取字符串的方法,当参数列表中,只存在一个参数的时候,从
            该位置截取到字符串的末尾的位置.
            如果是两个参数,则从参数一的位置开始截取,到参数二的位置结束.
            包括起始位置的字符,不包括结束位置的字符.
            截取规则:
            1. 起始值不能小于0.
            2. 结束值不能大于字符串的长度.
            3. 起始值不能大于结束值.
            4. 起始值如果等于结束值截取不出任何内容,但是不会报错.
        equalsIgnoreCase(String s)
            或略字符串中英文字符的大小写进行比较.只要是相同的字母,即使
            大小写不一致也不影响.
            针对中西文符号的差异,没有处理的.
        toUpperCase(String s)
            将该字符串所有的英文字符转换为大写字母.
            在使用该方法进行转换的时候,是重新生成了一个新的字符串.
            对原来的字符串没有更改.
        toLowerCase(String s)
            将该字符的所有英文字符转为位小写字母.
            转换的时候是重新生成一个新的字符串,对原有的字符串没有影响.
        *compareTo(String s)
            String类型的比较是逐位比较,从第0个位置开始两个字符串的字符
            进行比较,一旦其中的一个字符大于或小于另一个则直接返回结果.
            如果相等,则比较下一个字符.
        compareToIgnoreCase(String s)
            忽略大小写的比较.比较的方式与上面的方法一致.
            比较的时候考虑长度问题,尤其是在数字内容的字符串比较时.
        *trim()
            去除字符串两端的空白符(\n、\t、\b、\p、空格).
            并且会生成新的字符串,对原有字符串无修改.
        *isEmpty()
            判断当前字符串是否为空字符串.判断当前字符串的长度是否为0.
        *split(String regex)
            切分字符串的时候,作为切分的分隔符不会被记录到数组中.
            如果切分符号没有在字符串中匹配到,那么整个字符串变成了一个
            长度为1的字符串数组,元素就是它本身.
        *replace(char oldChar, char newChar)
            替换当前字符串中的内容,
            方法中的第一个参数是被替换的字符.
            方法中的第二个参数是替换字符.
            替换完成后,生成新的字符串.对原有的字符串没有影响.
            两个参数的内容可以是空字符串("").
        *replaceAll(String regex, String replacement)
        endsWith(String suffix)
            判断当前字符串是否已参数中的字符串结尾.一般情况下
            用于判断文件名的后缀名.



1. 正则表达式
    用于匹配符合某些特定条件而使用的一种符号表达式.
    正则表达式的一个内容在一对中扩号中表示.
    [1-9]:当前1个位置的地方只允许使用1到9之间的数字.
    案例:
    String postCode = "123456";
    邮政编码规则:^[0-9][0-9][0-9][0-9][0-9][0-9]$
    在正则表达式当中,已^作为开头,已$作为结尾.
    一旦定义了开头和结尾那么就必须按照规则进行匹配
    邮编的规则:已数字开头,已数字结尾并且长度被固定到开头和结尾中间.
    注意: java中的匹配都是包括起始值但不包括结束值.[star, end)
    规则:
    {m}   : 可以出现的次数.
    {n,m} : 表示可以出现的次数是最少是n次,最多是m次(n-m)
     ?    : 表示当前规则最多出现1次.(0-1)
     +    : 表示当前规则最少出现1次.(1-n)
     *    : 表示当前规则最少出现0次最多出现n.(0-n)
     .    : 任何字符(与行结束符可能匹配也可能不匹配)
    [n|m] : 表示当前位置可出现的内容要么是m,要么是n.
    [^n(,m)*] : 表示当前位置的内容不能是n.如果有多个可以用","隔开.
    [nm]
    \d 数字:[0-9]
    \D 非数字: [^0-9]
    \s 空白字符:[ \t\n\x0B\f\r]
    \S 非空白字符:[^\s]
    \w 单词字符:[a-zA-Z_0-9]
    \W 非单词字符:[^\w]
    练习:
    1. 编写一个邮箱的正则表达式.
    2. 编写一个身份证号的表达式.
    
2. ArrayList类(集合的一种)
    线性有序的连续的列表集合.底层是个数组.数组的类型是Object类型的.
    特点:
        集中的元素可以不是同一个类型的.如果想要保持集合中的元素的类
        型一致需要使用<泛型>.
    特性:
        1. ArrayList在打印的时候,默认的是调用元素的toString()
                  方法.
        2. ArrayList中的每一个元素都有下标.下标与数组相同.
                  也就是说在遍历集合的时候,是从0开始到结合的长度结束(不包
                  括长度值.)
    方法:
        add(Object obj);
            向集合中添加元素.在未定义集合的泛型时,可以添加任意类型的元素.
        addAll(Collection c)/addAll(int index, Collection c)
            向集合中添加元素,元素来自另一个集合.
            在指定的下标位置添加另一个集合中的全部元素.
        size():
            返回结合的长度值(int).若集合中没有元素长度0.
        get(int index):
            通过下标获取集合中的元素.下标的范围[0, list.size());
        set(int index, Object obj)
            将元素obj放入下标为index的位置上.    
        remove(int index)/remove(Object obj)
            删除集合中的元素.
            1. 可以使用下标删除.
            2. 可以使用元素删除.    
        contains(Object obj)
            判断作为参数的obj是否为集合中的元素.实际上就是判断
            在集合当中是否存在与之相同的元素.
            底层调用的是元素的equals()方法.这个方法在使用的时
            候元素的equals()必须被覆盖.
        clear()
            清空当前集合中的所有元素.
        retainAll(Collection c)
            判断参数中的集合中的元素是否都在当前集合中,如果是则
            返回true,否则返回false.
            当判断结束后,当前集合和参数集合中只保留交集元素.
        isEmpty()
            判断当前集合是否为空集合.
            空集合指的是长度为0的集合对象.
            跟null(空引用)不是一个情况.

3. LinkedList类(双向链表集合)
    是一种有序的双向链表集合(通过前一个节点能找到下一个节点,并且
    反向查找也可以找到.)
    结构:
        头节点 <===>next节点<===>next节点...<===>尾节点.
    方法:
        addFirst(Object obj)
            将元素添加到链表的头部,并标注为头节点.
        add(Object obj)
            将元素添加到链表中.
        pollFirst()
            将链表中的头元素标注移到下一个元素上.
        removeFirst()
            删除链表中头元素的标注,但是元素本身并没有被删除.
    
    优缺点:
        LinkedList优点:
            插入/删除节点时操作便利.
        LinkedList缺点:
            查询时需要消耗比较多的资源.
        ArrayList优点:
            查询节点时操作便利.
        ArrayList缺点:
            插入/删除节点时操作的元素过多.



<<  按位左移运算符
    将数字以二进制形式,向左移动.移动的时候,最高位的符号位不动.
<<<    无符号按位向左
    将数字以二进制形式,向左移动.移动的时候,不保留符号位.
|   二进制的或运算
    将二进制的数字,按位做或运算.
    例如:
        1011011
     |    10001
     --------------
        1011011



1. 集合(Collection)
    1.1 List集合列表接口,包含三个实现类
        ArrayList, LinkedList, Vector
        ArrayList与Vector结构是一样的,但是在使用效率上ArrayList比较高
        但是对于线程安全上Vector效果更好.
        集合中的元素类型都是引用类型,若需要使用基本类型则需要通过基本类型的
        包装类实现.
        
    1.1.1 ArrayList
        构造方法:
            1. 无参构造方法
                创建一个默认长度的集合列表.实际上调用的是参数为int类型的
                构造方法,并且传值是10.
            2. 参数为Collection类型的构造方法
                创建一个以参数中集合元素为蓝本的集合列表.
                (用于集合的浅层复制)
            3. 参数为int类型的构造方法
                创建一个以参数的值为长度的集合列表.
        特点:
            1. 在使用默认构造器创建集合的时候,集合的size()方法返回值是0.
                  如果集合中没有元素,那么size()方法返回的结果就是0.size()
                  方法实际上是返回集合中元素个数.    
            2. 当元素的类型为Integer时,在使用remove()方法时,需要注意直
                  接传递int值作为参数时,是根据下标进行删除.如果需要进行根据元
                  素删除,则需要使用包装类对int值进行引用类型包装.    
                  
    1.2 Set<E>([哈希]散列[线性]集合)    
        线性无序集合,元素的位置是根据元素hashCode决定的.理论上hashCode是
        不重复的,所以在Set集合中元素的位置也不会重复.
        
    1.3 Iterator<E> 迭代器
        用于迭代集合中的元素.
        方法:
            hasNext() 判断是否还有元素,如果没有则返回假
            next()    获取当前元素,并指向下一个元素.
            remove()  删除当前元素.
            
        注意: 在使用迭代器时,如果需要删除元素,那么一定要使用迭代器的
                   删除方法,而不是使用集合的删除.否则会出现错误.
2. 泛型
    指的是在某些特定的情况下,可以规定一组数据的指定类型.
    语法: <E> E表示的是任意类型,一般情况下<E>放置在类型的后面.
    注意: 泛型指定的类型尽量使用引用类型.在指定集合的泛型时,只能使用引用类型.
          集合的元素的类型都是引用类型.
          
3. Collection与Collections
    Collection  是集合接口
    Collections 是集合的工具类提供一些常用的方法
    例如: 排序、乱序、集合的线程安全化等方法.          
    1. binarySearch()              二分查找
    2. emptyList()                 返回一个空的list集合
    3. emptySet()                  返回一个空的set集合  
    4. shuffle(List<?> list)       乱序方法
    5. sort(List<T> list)          默认升序排列
    6. sort(List<T> list,
        Comparator<? super T> c)   自定义排序
    7. synchronizedList(
                List<T> list)      线程安全化(List)
    8. synchronizedSet(Set<T> s)   线程安全化(Set)



1. 包装类
    针对基本类型数据进行包装,将基本类型数据转换成引用类型.
    int     ===> Integer
    double  ===> Double
    float   ===> Float
    short   ===> Short
    byte    ===> Byte
    long    ===> Long
    boolean ===> Boolean
    char    ===> Character
    每个包装的构造方法,都可以将本类型的数据转换成对应的引用类型.
    当将String类型的数字转换成 Integer类型时候,需要注意的是
    有可能出现NumberFormatException.(Double类型也会出现该异常)
    通过对应类型的类型Value()方法可以将包装类的数据转换成基本类型.
    例如: Integer.intValue() ===> int
    
2. 数组与集合相互转换
    集合(List)的底层是数组,所以list可以转换成一个对应类型数组.
    如果当前List没有指定泛型,并且集合中的元素有多个类型,那么转换
    成数组的时候,数组的类型应该是Object类型.
    1. 数组在转换成集合的时候,数组的类型必须是引用类型.如果数组类
          型是基本类型,那么要手动将数组中的每一个元素放入集合中.
    2. 集合转数组时,默认的转换成object类型的数组.如果想要指定类型
          要根据集合中的元类类型决定,并且元素类型必须统一.
    3. 集合转换成的数组的类型,都是引用类型的.即使元素是基本数据类型
          的值那么也是对应的包装类型.
          
    数组转集合 ===> Arrays.asList(T[] t);  // 数组类型是引用类型
    集合转数组 ===> List.toArray([T[] t]); // 可以通过t的类型决定集合类型
    
    注意:
    使用Arrays.asList()方法转换的集合,是只读的集合.该集合不能添加元素
    也不能删除元素.一旦使用添加/删除方法则抛出异常
    java.lang.UnsupportedOperationException
    
3. Map(散列表)
    以键值对形式存在的数据集.Map接口与Collection接口是同级别的接口.
    Map接口下存在两个实现这类
    *1. HashMap<Key, Value> 非线程安全的所以效率高于TreeMap.
     2. TreeMap             线程安全的所以效率略低.
    特点:
    1. 键(Key):
          不能重复,不能为null(规范上).如果key重复了,则最后一个key中的
       value会覆盖掉前面的value.
          当key为null的时候,不影响map的基本操作,但是容易产生歧义并且没有意义.
    2. 值(value):
          可以重复,可以为null.
    注意:
    键(key)可以看作是一个set集合.
    方法:
    put(key, value): 向map中添加元素
    get(key): 获取当前key对应的value
              (key可以null,没有编译错误并且运行不报错).
    containsKey(key): 判断当前map是否包含key,包换返回true否则返回false.
    remove(key): 删除map中的元素.
    keySet(): 将key转换成Set集合,集合中的每个元素是一个key.便于迭代.
    entrySet(): 将map的键值对转换成Set集合,集合中每个元素是一组键值对.



1. 内部类
    在类体中定义的类,被称之为内部类.
    特点:
        在生成字节码(.class)文件时,内部类也是独立的一个文件.文件名
        会标明该类是某一个类的内部类.
    文件名格式:
        外部类名 + $ + 内部类名.class    
        
    1.1  静态内部类
        使用static修饰, 声明在类体中的内部类.
        静态内部类中可以访问外部类的静态成员(静态属性以及静态方法还有其他静态内部类).
        注意:
               在静态静态内部类中,只能直接访问外部类的静态成员.作为外部类
               的非静态成员则需要通过外部类的对象进行调用.
        特点:
               静态内部类,也相当于外部类的静态成员之一,可以通过外部类的类名
               直接进行调用.
               
    1.2  成员内部类
        声明在类体中,不使用static修饰,具有类的成员特性,必须有类的实例才能
        创建内部类的实例.
        语法结构:
            内部类类型 引用 = 外部类的对象.new 内部类类型();
        
    1.3  局部内部类
        声明在类中某个方法内的内部类.局部内部类只能在定义的方法中使用,一旦超
        出方法,则无法访问.
        特点:
            1. 可以访问类中的任意属性.
            2. 访问局部变量时,局部变量必须用final修饰.
            3. 在本类中的其他方法无法获取到该类的类型.
            4. 只能在本方法中创建对象并使用.
            5. 不能被static修饰,特性与局部变量相似.
            6. 遵循先定义,后使用的规则.
        
    1.4  匿名内部类
        只有类体({}),没有类名的内部类.可以写在任意位置上.
        一般用作修改对象的部分方法或属性时使用.可以看作是子类的存在.
        可以作为借口的实现类以及抽象类和普通类的子类出现.
        在匿名内部类中,可以存在原类型中没有的属性以及方法,但只能在匿
        名内部类中使用.



1. 时间类型: Date, Calendar, long
   java中时间的元年:1970年1月1日.
   
   1. long类型
       long类型可以表示系统时间的毫秒数.通过计算得出的年数是1970年到今年的相差
          年数.
          获取今年年份:
       long / 1000 / 60 / 60 / 24 / 365 + 1970 约等于 2016年
       
   2. Date类型
           操作时间.
         Date类型,在创建对象的时候可以使用空构造方法,或者调用参数为long类型的构造
           方法.使用long类型参数的构造方法,表示创建一个指定时间的Date对象.
           年数: 从1900年距离现在的年数
           月数: 从第0个月开始计算,最高是第11个月
           天数: 本周的第几天.起始值是星期天表示第0天.
           
   3. Calendar类
           用于操作时间,默认的都是系统当前时间.
           
   4. 日期格式转换
               new Date(long)       calendar.setTime(date)
         long ---------------> date ----------------------> calendar
                     calendar.getTime()        date.getTime()
         calendar -------------------> date ---------------> long
         
           注意: Calendar不提供直接转换成long类型的方法.
           
   5. 日期的操作(Calendar)
             通过Calendar.add(int type, int value)方法操作.
     
   6. 日期的格式化
           可以将日期格式化成指定的格式.
         2016-12-13 || 2016/12/13 || 2016年12月13日
         
         SimpleDateFormat类
           只能操作Date类型的数据.
           转换规则:
           y  年  Year  1996; 96  
        M  年中的月份  Month  July; Jul; 07  
        w  年中的周数  Number  27  
        W  月份中的周数  Number  2  
        D  年中的天数  Number  189  
        d  月份中的天数  Number  10  
        F  月份中的星期  Number  2  
        E  星期中的天数  Text  Tuesday; Tue  
        a  Am/pm 标记  Text  PM  
        H  一天中的小时数(0-23)  Number  0  
        k  一天中的小时数(1-24)  Number  24  
        K  am/pm 中的小时数(0-11)  Number  0  
        h  am/pm 中的小时数(1-12)  Number  12  
        m  小时中的分钟数  Number  30  
        s  分钟中的秒数  Number  55  
        S  毫秒数  Number  978
        
        练习:
        输入一个商品的生产日期 以及保质期,计算商品的促销日期.
        促销日期: 商品过期的前两个星期的星期五开始促销.
        输出格式: 2016年12月13日
        提示:
        Calendar.FRIDAY 星期五
        WEEK_OF_YEAR    年中的星期数
        DAY_OF_WEEK     星期中的天数
        
2. 异常(Exception)
    出现在java类中的编译或运行时错误.这种错误,是可修复的错误.
    
    Exception类
    异常的父类,所有的异常都继承于该类.
    语法:
    在方法声明时,标注在参数列表之后,方法体({})之前,并且使用
    throws关键字进行修饰.
    
    RuntimeException类
    运行时异常,在程序中出现该种异常或,次异常的子类异常时.程序都
    将终止运行.
    1. NullPointerException
    2. StringIndexOutOfBoundsException --- 4的子类
    3. ArrayIndexOutOfBoundsException  --- 4的子类
    4. IndexOutOfBoundsException
    5. NumberFormatException
    6. IllegalArgumentException
    案例:
    创建User类
    属性:
    int id;
    String username;
    String password;
    创建UserService接口
    方法:
    String login(User user) throws RuntimeException;
    
    捕获异常:
    try{
        ...
    }catch(Exception e){
        ...
    }
    通过try..catch可以将try中代码出现的异常进行捕获操作.当异常
    被捕获之后,程序将继续向下运行而不会终止运行.
    在try中出现异常的代码将不再执行,而是执行catch中的代码.
    
    执行try..catch..finally中代码的时候,可以看作是if...else
    区别在于,如果执行try中的代码(无异常),catch当中代码不会执行,
    但是finally中的代码会执行.
    如果执行try中代码(有异常), catch中的代码会执行,并且try中的
    代码执行不完整,finally中的代码依然会执行完整.
    
    finally模块
    配合在try..catch...finally...使用的.
    finally当中的内容一定会执行.即使在finally之前存在return关键字
    但是在return执行之前优先执行finally.
    finally 最大的作用就是,无论代码中执行的是try中的代码还是catch中
    的代码,如果存在后续必须执行的操作那么都将通过finally来执行.
    
    自定义异常:
    通过自定义一个类, 继承异常类(RuntimeException/Exception)
    自定义异常的好处, 在出现异常的时候能够明确该异常出现的原因.
    
    异常的结构:
    Throwable
        |
        |---- Error(错误):一般是出现在内存中,是java不可修复的错误.
        |        |
        |        |--- StackOverflowError(栈溢出错误)
        |        |--- OutOfMemoryError  (堆移出错误)
        |
        |---- Exception(异常):一般是语法异常和运行时异常,是java中可修复的错误.
                |
                |--- 编译时异常: 一般情况是存在语法错误.
                |--- RuntimeException(运行时异常)
                            |
                            |---- NumberFormatException
                            |---- NullPointerException
                            |---- IndexOutOfBoundsException
                            |---- IllegalArgumentException



1. Java中的文件操作.
    1.File类 文件类型
        用途: 用于java操作硬盘上的文件或目录(文件夹)
        注意: 用File创建文件时,一定要指名后缀名.
        构造方法:
        File(String pathAndFileName)
        参数是:文件名以及文件所在的路径.
        方法:
        exists()          -- 返回当前文件/目录是否已经存在.
        createNewFile()   -- 创建文件,并返回创建结果(true/false)
                                                     如果已经存在,则不再创建,并返回false.
        delete()          -- 删除文件/目录
        isFile()          -- 判断当前file类型是否是文件.
        isDirectory       -- 判断当前file类型是否是目录.
        mkdir()           -- 创建目录
        mkdirs()          -- 创建多个目录
        getName()         -- 获取文件名(包含后缀名)
        length()          -- 获取文件内容的长度(并非文件的大小)
        getCanonicalPath()-- 获取所在项目的绝对路径
    
    2. RandomAccessFile(随机读写)类
        本类是java中提供用于操作(读写)文件内容的工具类.在使用的时候,
        会在文件中生成一个游标,每写入一个内容游标会自动向后移动.
        使用:
        需要配合File类使用,并且打开文件的模式分为两种.
        打开模式: 只读("r"); 读写("rw");
        写入方法: write(...),每一次写入一个byte
        
    3. 序列化与反序列化
        序列化:   将系统中的数据写入文件的操作.
        反序列化: 将文件中的数据读入系统中的操作.



1. IO流(InputStream, OutputStreaqm)
    1. Java中的标准输入/输出流,也是IO流的基础.
        1. InputStream, OutputStream都是抽象类.
            InputStream  包含读取文件中内容到系统的所有方法.
            OutputStream 包含将系统中的内容写入文件的所有方法.
                                        写出的时候,将文件中的内容清空后,再写.
            
        2. 文件的尾部
            EOF = End of File = -1
            
        3. 输入流基本操作方法
            int b = in.read();   读取的是一个byte,但是在java中转成int
                                                         无符号的只有低八位的数字,如果是-1则是EOF
            in.read(byte[] buf); 读取一个byte[]数组长度的数据到数组中.
            in.read(byte[] buf, int start, int size);
                                   读取一个从start位置开始,长度是size的
                                  byte数据到数组中.
            in.close();           关闭流.
            
        4. 输出流基本操作方法
            out.write(int b)      写出一个byte到流中,写的是b的低八位
            out.write(byte[] buf) 将byte数组中(缓冲区)的数据写出到文件.
            out.write(byte[] buff, int start, int size)
                                    将byte数组中(缓冲区)start起始位置的
                                    数据,长度是size的数据写出到文件.
            out.flush()           清空缓冲(如果不调用,则内容无法写进文件)
            out.close()           关闭流(默认调用flush()方法)
            
    2. FileInputStream 和 FileOutputStream 文件字节(I/O)流
        操作的内容都是字节.文件中的内容是正常的.
        
    3. DataInputStream 和 DataOutputStream 数据字节(I/O)流
        用于操作数的字节流.
        注意: 在使用的时候,写出到文件的顺序必须与读入到系统中的顺序一致.
        
    4. BufferedInputStream 和 BufferedOutputStream 缓冲流
        为IO流提供一个缓冲区, 在进行读写操作时,先将数据缓冲到缓冲区
        中, 然后再将缓冲区中的数据一次性读入 或 写出.



1. 文本和文本文件
    java中的文本(char)是无符号16位整数,是字符的unicode码.
    文件是byte的数据序列.
    文本文件是文本(char)序列按照某种编码方案(utf-8,gbk,gb2312)序列化为
    byte的存储结果.
    
2. 字符流(Reader读 Writer写)
    1. 一次性处理一个字符(unicode).
    2. 字符流底层还是字节流.
    3. 字符流的基本实现
        InputStreamReader      完成byte流解析为char流. 按照编码格式
        OutputStreamWriter     提供char流到byte流处理, 按照编码格式
    4. 字符过滤器
        BufferedReader         输入字符流过滤器
        PrintWriter            输出字符流过滤器
    
3. 对象的序列化
    将Object转换为byte序列, 反之则是对象的反序列化.
    1. 序列化流(ObjectOutputStream), 是过滤流.
        ObjcetOutputStream   序列化
        ObjcetInputStream    反序列化
    2. 序列化接口(Serializable)
        是一个空接口,接口当中没有任何方法.作用只是用于标记该对象可以
        被写出到文件中.
        对象必须实现序列化接口.没实现序列化接口则不能写出到文件,否则
        会出现异常.



1. MVC设计结构(代码结构)
    M : 模版(逻辑层和数据层)
    V : 视图(JFrame和JSP/FTL/HTML)
    C : 控制层
    
    分包:
    bean/pojo/entity/doto --- 实体类(包含属性以及get/set方法)
    dao                   --- 数据接口(定义从数据库/文件中操作数据的方法)
    dao.impl              --- 数据接口实现类
    service               --- 业务逻辑接口(处理业务相关的逻辑)
    service.impl          --- 业务逻辑实现类
    util                  --- 自定义工具类
    action/handle         --- 控制层包
    resource              --- 配置文件(.xml/.properties)

1. MVC代码结构
    M: 模型层
        |
        |
        |----逻辑层(serice)
        |
        |----数据层(DAO/DB)
    
                    调用方法
    调用顺序: 逻辑层-------->数据层
                                  返回结果   
                      逻辑层<-------数据层
                      
    V: 视图层
        |
        |-----页面(JSP/HTML/ASP/PHP)
        |
        |-----操作界面(swing/c#界面)
        
    在视图层尽量不做与业务相关的逻辑操作.
    
    
    C: 控制层
        |
        |-----Servlet(请求的处理选择以及页面展示的选择)
        |
        |-----Action(struts)
        |
        |-----Controller(springMVC)
        
代码分包:
    模型层:
        service包: 逻辑处理的方法接口(定义了处理逻辑的抽象方法)
        service.impl包: 逻辑接口的实现类.
        dao包: 数据层用于管理数据的接口(定义了针对业务数据增/删/改/查)
        dao.impl包: 数据层接口实现类包.
        bean/entity/pojo/dto包: 映射数据库表的实体类.
    
    视图层:
        B/S结构的项目,视图层一般放置于WebRoot下,主要已页面为主.
        
    控制层:
        struts框架: action包
        springMVC框架: handler包
        用于存放关联视图与模型之间关系的控制类.
    其他:
        resources: 放置项目中所使用的配置文件(.properties/.xml)
        utilt:  项目中所使用的工具类
        common: 项目中通用工具类或常量类或者基础basic类.
        test: 项目中用于放置测试代码使用类.(junit工具).

2. Java中的多线程编程
    1. 线程的概念
        一般的操作系统中支持多个任务同时运行,一个任务通常是一个程序.每个程序
        运行中程序被分为一个进程.一个进程当中,可以存在多个线程.线程指的是程序
        的运行顺序执行流.
        1). 程序   指令 + 数据的byte序列.
        2). 进程   正在运行的程序,是程序动态执行的过程.(运行在内存中.)
        3). 线程   在进程内部,并发运行的过程(java中的方法可以看作是多线程)
        4). 并发   进程是并发运行的, 系统(OS)将时间划分为许多时间片段(时间片)
                 尽可能的平均分配给正在运行的程序.
    
    2. 创建一个线程
        1. Thread 类
            通过继承Thread类,并且覆盖其中的run()方法.
            java.lang.Thread
        2. 创建步骤
            1). 继承Thread类
            2). 覆盖run()方法
            3). 创建类的对象
            4). 调用star()方法
        注意: 主方法(main()方法)本身就是个线程.
        
    3. 线程的状态
        1). New        新建状态
            继承了Thread类的自定义类,在通过new关键字创建对象之后.
            这个对象就是新建状态下的线程.调用star()方法时,线程启动
            进入 Runnable 状态.
        2). Runnable   可运行状态
            调用star()方法之后的线程,表示当前线程已经准备就绪,等待
            CPU的运行.
        3). Running    运行状态
            当前线程正在运行.
            当前CPU支持几个线程同时运行,那么就有多少个线程进入Running
            状态,其他线程都在Runnable状态.
            例如: 当前CPU是4线程的,而当前系统存在8个线程,那么只有4个线
                       程进入Running状态,其他的都在Runnable状态等待运行.
        4). Block      阻塞状态
            当前线程退出Running状态,进入阻塞状态.阻塞状态结束后,线程回
            到Runnable状态,等待CPU运行.
            1). 调用sleep(time),使线程进入睡眠(阻塞)状态.
            2). 通过IO方式对线程进行阻塞操作.(Scanner阻塞主线程)
            3). 线程阻塞.
        5). Dead       死亡状态
            当前线程的run()方法运行结束,线程进入Dead状态.
            当线程进入死亡状态时,不可在调用star()方法,线程死亡后将不能再
            被视为线程执行.java.lang.IllegalThreadStateException
        
    4. 线程状态管理
        1). 让出CPU Thread.yield()
            当前线程让出CPU(离开Running状态),使当前线程进入Runnable状态.
        2). 休眠  Thread.sleep(time)



1. 线程的创建方式
    1) 继承Thread类, 覆盖run()方法
    2) 实现Runnable接口, 实现run()方法
          通过实现Runnable接口创建的线程,启动时需要new Thread类
          将当前的对象作为Thread构造方法参数传入Thread中,调用Thread
          的start()方法.
          
    好处: 当线程需要继承别的类时,通过实现方式的线程不会影响其他继承以及
               实现.推荐使用实现接口的方式创建线程.
               
2. 线程的常用属性以及方法

    1) 线程的优先级(资源紧张的时候使用)
          设置优先级高的线程,理论上优先占有CPU的资源运行.但是实际上只是增加
          了抢占CPU资源的可能性.并不是一定优先运行.
          方法:
       setPriority(int) 设置优先级
          属性值:
       MAX_PRIORITY  --- 最大优先级
       MIN_PRIORITY  --- 最小优先级
       NORM_PRIORITY --- 普通优先级(默认)
       
    2) 后台线程(精灵线程, 守护线程)
       setDaemon(boolean) 设置成后台线程
          当线程为后台线程时,那么如果前台线程执行完毕,那么无论后台线程是否执行
          完成,都结束运行.
          后台线程如果先结束,那么对普通线程没有影响.
         
    3) 获取线程名字
       getName()
       
    4) 获取当前线程
       Thread.currentThread()
       
3. 线程的sleep状态
    1) Thread.sleep(times)
               使当前处于Running状态的线程,进入block状态.休眠times(毫秒为单位)
               时间,当休眠结束后,在回到Runnable状态.
    2) interrupt()
               打断正在休眠状态中的线程.
    3) 被唤醒的休眠中的线程,会抛出异常InterruptedException.
    4) 休眠正常结束的线程,不会抛出异常.
    
4. 同步与异步
    1) 异步:
          并发操作,各自做各自的事情,互不干扰. 例如:跨栏运动.    
    2) 同步:
          步调一致的处理.例如:老太太扒公交车门:我上不去,你们谁也别走.



关键字
1.简述break、continue、return关键字
    break关键字:
        使用位置:循环结构、分支结构(switch...case...)
        1. 循环结构中,终止本层循环(距离break最近的一层循环.)
        2. 分支结构,在执行某一个case之后终止分支结构其他case的执行.
              注意:一旦在某一个分支中遗漏break,导致的结果就是从中个case之后
                       的所有case将全部执行.
            特点: 在方法中单独使用break,没有任何作用.
            
    continue关键字:
        终止本次循环,回到循环的顶部判断循环条件是否成立,如果成立则进入下一次循环
        如果不成立,则结束循环.
        特点: 只作用于循环当中.
            for(类型 引用 : [数组/集合]){
                ...
            }
        注意: 在使用continue关键字的时候,切记迭代变量有所改变,否则可能出现死循
               环现象.
               
    return关键字:
        用于终止方法的调用,将结果(或者没有结果)返回到方法的调用出.
        注意: 任何返回值类型的非构造方法都有返回值.
                   无返回值类型的方法(void)的返回值是return ;
                   在无返回值的方法中可以忽略不写(JVM会再编译的时候为代码自动添加).
                   分号(;)叫做空语句.严格来说它是一行代码.
        特点:
            1. 除了finally中的语句以外,return之后的所有语句都不会执行,
                   并且编译不通过(存在语法错误).
            2. 当方法为有返回值方法时,return后面的值或者变量 类型必须与方法的
                   返回值类型一致.(符合java当中自动类型转换规则)
            3. return后面只能跟一个值或者是变量.(一个方法只有一个返回值.)
            
2. 简述final的作用.
    1. 修饰变量(包括局部变量/全局变量/静态变量)
        在变量初始化之后,不能更改.
        引用类型变量: 对象不能更改,但是对象中的属性可以更改.
        基本类型变量: 变量的值在初始化之后,不能改变.
        注意: 变量在栈中的值不能更改.
    2. 修饰方法
        final修饰的方法可以被子类获取,但是不能被子类覆盖.
    3. 修饰类
        final修饰的类不能被继承.
        java中提供的典型的final修饰的类是 String.
        
3. 简述static关键字的作用.
    修饰全员(所有根据类创建的对象)共享的属性或方法.
    对象的属性和方法 是在对象创建的时候创建.
    静态的属性和方法, 是在类的加载的时候创建.
    1. 修饰方法
        整个类中,只存在一个.无论创建多少个对象,都是使用同一个方法.
        静态方法中,只能调用静态属性或静态方法.
    2. 修饰全局(成员)变量(类的属性)
        类的所有的对象公用同一个静态属性.
        static和final组合使用的时候, 定义的是常量.
        常量: 在初始化之后不能更改,且只有一个.
    3. 修饰代码块
        类的加载的时候才运行,并且只运行一次.
        因为java中所有类都只加载一次,加载机制是惰性加载(懒加载).
        
4. 简述new、this、super关键字的作用
    new关键字: 创建对象时使用, 告诉JVM在堆中开辟一块空间用于存放对象.
    this关键字:
        1. 本类的属性
            this.属性名;
        2. 本类的方法
            this.方法名([参数列表]);
            参数列表当中的内容: 实际参数(实参)
        3. 本类的构造方法
            this([参数列表]);
            参数列表当中的内容: 实际参数(实参)
    super关键字:
        1. 父类的属性
            super.属性名;
        2. 父类的方法
            super.方法名([参数列表]);
            参数列表当中的内容: 实际参数(实参)
        3. 父类的构造方法
            super([参数列表])
            参数列表当中的内容: 实际参数(实参)

概念题
1. 类、对象和引用之间有什么关系?
    类:   具有相同属性(全局变量)和行为(方法)的一类事物.
    对象: 某一类型的具体的实例.(某一个类型的具现化的结果).
    引用: 用于表示某一对象的地址的变量.类型是由类来决定的.
    可以通过类来创建一个对象,并且将对象的地址赋值给引用.

2. 什么是抽象类?
    使用abstract修饰的类即是抽象类.
    特点:
        1. 抽象类中可以存在抽象方法,抽象方法需要通过子类来实现.
        2. 抽象类也是类,也可存在普通方法.抽象类中普通方法也可以被调用.
        3. 抽象类的子类必须覆盖父类所有抽象方法.
        4. 抽象类可以存在构造方法,构造方法不提供创建对象的作用.
        5. 抽象类可以继承抽象类,并且可以不覆盖父类的抽象不方法.
        6. 抽象类不能直接创建对象,只能创建子类的对象.
              抽象类在任何情况下(无论是否存在抽象方法)都不能直接创建对象.
        7. 抽象类只能被单继承,一个类只能继承一个抽象类.
              
3. 什么叫类、抽象类、接口?
    接口使用interface修饰的规范性的类,接口不是类.
    特点:
        1. 接口中的方法全部都是抽象方法,并且不许要使用abstract修饰.
        2. 方法的访问类型默认的都是public类型.
        3. 接口中的属性全部都是使用static final修饰的常量.
        4. 接口中没有构造方法,因为它不是类.
        5. 接口只能继承接口,不能实现.
        6. 接口可以被多实现,一个子类可以实现多个接口.
    使用:
        当不想要实现接口中的全部抽象方法,可以使用抽象类做中间键.
        在抽象类当中,把不需要的抽象方法实现即可.
        
4. 什么叫方法重写
    发生在子类与父类之间,子类中存在于父类相同的方法时,子类的方法会覆盖
    父类中的方法(方法覆盖).
    方法重写是在JDK-1.5之前就已经存在了,但是@Override标签是在JDK-1.5
    版本之后(包括1.5)出现的.
    特定:
    1. 父类中的非private类型并且没有被final修饰的方法可以被子类覆盖,并且
          子类中的方法的访问修饰符要大于等于父类的方法.
    2. 父类中私有的属性以及方法,在子类当中依然获取不到

5. 什么叫方法的重载
    方法名相同,参数列表不同,返回值类型相同的多个方法.称之为方法重载.
    参数列表不同:
        1. 数量不同
        2. 类型不同
        3. 顺序不同
        
6. 简述你对可见性(访问修饰符)的了解
    1. public       
        1. 修饰类
        2. 修饰属性
        3. 修饰方法
        特点: 只要存在类的对象的位置或类的子类都可以获取使用.
        
    2. protected
        1. 修饰属性
        2. 修饰方法
        特点: 非子类的对象,只能在相同的包下访问或使用.
                   子类的对象可以在不同包下覆盖.
    3. 默认的
        1. 修饰类
        2. 修饰属性
        3. 修饰方法
        特点:
            1. 修饰类时只能在相同包下创建该类的对象,如不同包下则不能创建对象.
            2. 本类或相同包下的子类才能获取到属性以及方法.
    4. private
        1. 修饰属性
        2. 修饰方法
        特点:
            只能在本类中使用,即使是子类也无法获取和覆盖.

8. 构造方法是否可以被子类覆盖, 为什么?
    构造方法不可以被子类覆盖,它是一个特殊的方法.是在创建对象的时候
    使用的.并且没有返回值类型.在子类中,只能调用父类的构造方法,不能
    覆盖构造方法.

9. 静态方法是否可以被子类覆盖, 为什么?
    静态方法不能被子类覆盖.
    继承关系是通过类的对象来实现的,方法覆盖也是由子类对象中的方法去
    覆盖父类对象中的方法.因为静态方法是类级别的方法,所以作为对象级别
    的方法覆盖不能覆盖类级别的静态方法.
    
API使用
1. 请列举出String中的常用方法和作用至少12个
    1. length()              返回字符串的长度,返回值类型是int
    2. charAt(int index)     返回index位置的字符,返回类型是char
    3. indexOf(String s)     返回字符串s的第一次出现的位置,返回值类型int
    4. lastIndexOf(String s) 返回字符串s的最后一只出现位置,返回值类型int
    5. substring(int begin, int end)
                                       截取从begin位置到end位置上的字符串,截取位置
                                       包括begin位置不包括end位置,返回型String.
                             begin的值不能小于0且不能大于end
                             end的值不能大于字符串的长度.
    6. substring(int begin)  从begin位置开始截取一直到字符窜的末尾.
                             begin的值可以等于字符串的长度,等于时截取的是
                             空字符串.但是begin的值不能大于字符串的长度.
    7. split(String s)       以字符串s为间隔切分字符串成一个字符串数组,返
                              回字符串类型的数组.
    8. compareTo(String s)   比较两个字符串的大小, 返回值是int
    9. isEmpty()             判断字符串长度是否为0, 返回值是boolean
    10.replace(char old, char new) 将字符串中old字符串替换成new字符串,
                                      并且生成一个新的字符串,返回值String.
    11.concat(String s)      将字符串s拼接到当前字符串后面,返回值String.
                              生成的是一个新的字符串,对原有字符串无影响.
    12.toUpperCase()         将字符串中的所有英文字母转换成大写字母.
       toLowerCase()         将字符串中的所有英文字母转换成小写字母.
                                 对原有字符串无影响.
    13.equalsIgnoreCase()    忽略字符串中英文字母大小写进行比较.
    14.trim()                去掉字符串两端的空白符.
    
3. Object类有什么用?有哪些我们常用的方法,这个方法有什么用?
    为其他类提供公共的方法,便于使用.object是所有类的父类.
    1. hashCode()
        将对象的在内存中的地址值,通过哈希算法生成一个理论不重复数字,
        以十六进制形式显示.用于计算元素在哈希散列表(Set)中的位置.
    2. toString()
        当通过System.out.print()方法打印对象的时候,默认调用toString()
        toString()在默认情况下,显示的是完整的类名(包名 + 类名)@hashCode()
        一般在需要显示对象信息的时候,会对该方法进行覆盖.
        在集合当中打印集合的时候,集合会自动调用元素的toString()方法
    3. equals()
        在默认情况下,equals()方法比对的是两个对象的地址值.
        在没有被覆盖的情况下,比较的结果等同于两对象的恒等于(==)比较结果.
        在覆盖equals()方法的同时,要覆盖hashCode()方法.
        
    4. wait()     // 线程的
    5. getClss()  // 获取当前对象类型
    
    
        
方法的参数:
    1. 形参(形式参数)
        方法的声明时使用.
        格式: 参数类型1 参数名1, 参数类型2 参数名2...
    2. 实参(实际参数)    
        方法在被调用的时候使用.
        格式: 对应类型的值.(引用类型传对象的地址值;基本类型传的是字面量.)

方法的声明:
    格式: 访问修饰符 [static/final] 返回值类型 方法签名(方法名和参数类表){
             方法体...(方法中的逻辑代码)
             return 关键字(如果返回值类型是(void),return可以省略).
         }
方法签名:
    方法名和参数列表.
    方法的命名规则没有特殊要求,但是要遵循javaBean规范.
    javaBean规范:
        1. 方法名要尽量描述出方法的作用.
        2. 方法名的首字母不用大写(一定是小写的).
        3. 方法名遵循驼峰规则,也即是从第二个单词起,单词是首字母大写.
    参数类表
        多个参数之间使用逗号(,)隔开. 理论上参数列表中可以存在无数个参数.
        但是,出于规范或者增加代码的可读性一般情况下参数个数不超过4个.
        如果参数数量过多,可以将参数封装成bean对象.
        bean对象: 只有属性和get/set方法的类的对象.

构造方法:
    特性:
        1. 没有返回值类型
        2. 方法名与类型一致
        3. 方法中的第一行默认调用父类的构造方法.
        4. 构造方法本身不是创建对象,而是通知JVM创建对象.
        5. 每个类中,如果没有声明构造方法则JVM会默认的添加上无参的构造方法.
              除非当前类在创建对象的时候,必须为某一个属性赋值时,那么将不用提供
              无参构造方法.
              
创建对象的顺序:
    1. 创建属性.
    2. 创建方法.
    3. 执行构造方法.
    
惰性(懒)加载:
    在java中,用到哪一个类的时候才去加载.否则不予理会.调用类的静态
    属性或方法时,或者创建对象时.
        
包的引用:
    但凡是java.lang包下的所有类在代码中使用时,无需声明类的来源(不用导入包).



1. 单例模式
    一个类只创建一个对象,在整个程序的应用当中无论多少个地方
    调用,都使用同一个对象.
    最主要的点: 私有化构造器.
    限制在该类以外的地方创建对象.
    
2. 静态工厂模式
    1. 反射
        Class.forName(className)加载指定的类型到虚拟机中
        返回该类型Class<?>.

3. 类的加载机制
    在程序运行的时候,所有的.class文件都是可以被装载的状态.
    在程序中一旦需要使用哪个类的时候,JVM会相应的加载对应的.class
    文件中内容到虚拟机中.java的加载机制叫惰性加载.

反射:
    1. 类的加载机制
        Java中的加载机制是惰性加载(懒加载),使用到哪一个类的时候会
        将对应的.class文件装载到虚拟机中(JVM)一个.class在程序的
        一次运行当中,值装载一次.
        
    2. 创建类的对象
        根据JVM中加载的类(.class)为模型创建出的实体.正常情况下使用
        new关键字进行创建. 创建对象实际上是调用构造方法(默认情况调用
        无参构造方法).
        
        注意: 一定是先有类再有对象.
        
    3. 反射创建对象
        a. 获取对象的类型.
            Class.forName(String className);
            className: 完整的类名(包名.类型);
            异常: ClassNotFoundException: 没有找到对应类型.
            
        b. 通过类型中的方法创建对象
            1). 当类中存在无参构造方法
                newInstance():调用类的无参构造方法创建对象.
                
            2). 当类中不存在无参构造方法
                需要使用类中的有参的构造方法创建对象.
                getConstructors():获取类型中的所有构造方法.
                
    4. 通过反射获取对象的属性以及方法



1. JDBC原理
    JDBC(Java DataBase Connectivity, java数据库连接)是一种用来执行sql语句
    的java API, 可以为大多数关系型数据库提供统一的访问,它是由java语言编写的类和
    接口组成的.
    
2. JDBC的使用
    2.1 连接Oracle数据库
        1). ip(Oracle数据库所在的地址): localhost/127.0.0.1(本机IP)
        2). sid(Oracle数据库的唯一标识号): XE
        3). port(Oracle数据库的默认端口): 1521
        4). dbUser/dbPassword(数据库访问账号): wanght/123
        
    2.2 Oracle的连接字符串
        jdbc:oracle:thin:@localhost:1521:XE
        
3. 连接数据库
    1. 常用接口(java.sql.*包)
        java.sql.Connection         连接
        java.sql.Statement          SQL语句
        java.sql.PreparedStatement  预编译语句
        java.sql.ResultSet          结果集
    2. 常用类
        DriverManager               驱动管理类(用于区分数据库类型)
        
4. 连接步骤:
    1. 创建.properties(配置文件)文件
        文件中的数据是以键值对的形式存在的 key=value
        用于存放数据库连接信息.
        (包括数据库连接字符串,数据库访问账户,访问密码,驱动字符串)
    2. 使用Properties类读取文件
        Properties类需要配合I/O流使用,其本身不能读取文件.
        
5. 小结:JDBC的使用过程
    1). 在项目中加入数据库的驱动包(jar包)
        不同类型的数据库都有各自的jar包.
    2). 必须有的数据库参数
        主要指的是数据库连接字符串中的组成内容,不同的数据库名称不同,端口不同,书
        写格式不同.
    3). 连接字符串
        Oracle: jdbc:oracle:thin:@ip:port:sid
        mysql: jdbc:mysql:ip:port/database
    4). 构建对数据库操作的数据并连接操作
    
        a). 装载数据库连接驱动
            Class.forName(驱动类名) --- 将对应的数据库类加载到程序中.
            
        b). 构建Connection(连接)对象
            Connection conn =
                DriverManager.getConnection(url, username, password);
            
        c). 构建Statement(语句)对象
            Statement stmt = conn.createStatement();
        
        d). 执行sql语句,使用的是stmt.executeQuery(sql)方法向数据库发送sql
            语句并执行.
        
        e). 通过stmt.executeQuery方法的返回值,获取结果集(ResultSet).
            ResultSet rs = stmt.executeQuery(sql);
            获取数据时,通过rs的next()方法判断是否存在数据.
            rs下每一条记录都是结果集中的一行数据.
            获取列的数据可以通过rs.getXXX()方法(XXX表示是类型)获取.方法参数
            可以是查询的结果集的列名,或者是列的序号(从1开始).
            
        f). 关闭数据库连接
            if(conn != null) conn.close();
            if(stmt != null) stmt.close();
            if(rs != null) rs.close();
        
6. 使用JDBC完成对数据库的增、删、改
    使用的方法:
    executeUpdate(sql) --- 返回值是执行的行数.
    
7. PreparedStatement 预编译语句
    将SQL语句提前组合完成,再传入到数据库中执行.



分页处理:
    1. 在代码中处理(基于缓存的分页)
        一次性将数据库中的数据全部查询出来,通过代码中控制完成分页.
        优点:
            便于操作,并且能够减少数据库的访问次数从而提高效率.
        缺点:
            当数据量过于庞大时,会导致系统崩溃(内存溢出).
        
    2. 在数据库中通过SQL语句处理(基于查询的分页)
        固定每次访问数据库,取到指定页的数据.
        优点:
            节省内存
        缺点:
            加大服务器响应时间.
        
    在oracle数据库存在一个隐藏字段:rownum
    rownum 作为条件时,只能小于等于, 并且between关键字无效.
    
    分页通过子查询处理:
    select rownum,rn, id, name, password from (
        select rownum rn, id, name,
        password from user_wanght where rownum < 7)
        where rn > 3;
    传参:
        参数一:取值的最大行数
        参数二:取值的最小行数



HTML语言(超文本标记语言)
1. html是什么
    超文本标记语言(HTML)
    是一种用于网页设计的标记语言,用改语言编写的文件都是以.html
    或.htm结尾.并且有浏览器进行解析执行.生成相应的页面.

2. html的结构
    html的基本组成部分大体分为两部分: 头(head)和体(body).

    2.1 <head></head>头标记和<body></body>体标记
        1). html头标记,用于描述页面数据
        2). html体标记,用于显示页面内容
        
    2.2 <title></title>标记
        用于展示页面名称的标记.
    
    2.3 <meta>消息头标记
        1) 用于设置消息头
        2) 语法:
            <meta ...>    推荐
            <meta></meta> 不推荐
            <meta/>       不推荐
        3) 消息头:
            浏览器访问服务器时, 服务器会发送一些键值对.
            <meta http-equiv="content-type"
                content="text/html;charset=utf-8">
    
3.CSS样式
    设置页面上内容的显示效果.
    
    3.1 引入CSS样式
        1). 将CSS样式写在<head></heda>标记中
            在<head>标记中增加一对<style>的标记
            将CSS样式写在<style>标记中间.
            
        2). 独立编辑CSS样式文件,文件已.css结尾.
            在页面中引入对应的css文件,引入位置最好在
            <head>标记中引用.引用标记使用的是<link>
            标记.
            
        3). 直接在标记中增加style属性,设定标记内部的显示样式.
    
    注意: CSS样式在页面中距离标记最近的样式优先生效.
    
4. script脚本
    用于执行页面上的逻辑的脚本代码.
    脚本文件是以.js结尾.js的注释与java相同使用的是双斜线(//)



1. 表单中的非input标记
    1) 下拉列表(<select>)
        语法:
        <select name="" multiple="">
            <option value="">文本内容</option>
        </select>
        
        属性:
        name属性:      下拉列表标记的名称
        multiple属性:  设置下拉列表变为一个多选框,值"multiple"
        
    2) 多行文本框<textarea>
        语法:
        <textarea name="" cols="" rows="">文本内容</textarea>
    
2. 列表标签    
    
    1) 无序标签(序号)<ul>
        语法:
        <ul>
            <li>...</li>
        </ul>
        
    2) 有序标签(序号)<ol>
        语法:
        <ol>
            <li>...</li>
        </ol>
        
    3) 列表可以嵌套使用
        <ol/ul>
            <li>
                ...
                <ol/ul>
                    <li>...</li>
                </ol/ul>
            </li>
        </ol/ul>
        
3. 窗口划分
    frameset标记和frame标记
    
    语法:
    <frameset rows="20%,*">
        <!-- 顶部  -->
        <frame name="topFrame" src="top.html" />
        <!-- 底部 -->
        <frameset cols="30%,*">
            <!-- 左侧  -->
            <frame name="leftFrame" src="left.html" />
            <!-- 右侧 -->
            <frame name="rightFrame" src="right.html" />
        </frameset>
    </frameset>
    
    属性:
        frameset标记不能与body标记同时出现.
        rows属性: 将窗口划分成几行(行高可以用百分比显示)
        cols属性: 将窗口划分成几列(列宽可以用百分比显示)
        frame标记定义子窗口,其中src属性指定记载的页面.
    
4. CSS级联样式表
    为网页提供表现的形式,按照w3c的协议,主要是为实现网页设计.
    设计规则:
    1). 网页的结构和数据,应该写在html文件中.
    2). 网页的表现形式(css样式),应该写在css文件中
    3). 网页的行为(js脚本),应该写在js文件中.
    
    4.1 css选择器
        选择器定义了如何查找html标记,浏览器会语句选择器,找到
        匹配的标记,然后对对应的标记增加样式.
        
        4.1.1 常用选择器
            a) 标记选择器(简单选择器)
                以页面中的标记名称为css样式的选择器
                
            b) class选择器(样式选择器)
                在页面的所有标记中,存在一个叫做class的属性
                可以通过使用class属性为某一个标记单独增加样式.
                语法一:
                .样式(选择器)名{
                    属性名: 属性值;
                }
                语法二:(规定了样式的使用对象)
                标记名.样式(选择器)名{
                    属性名: 属性值;
                }
            c) id选择器(标记的id属性)
                以标记的id属性作为选择器.
                语法:
                #标记的id{
                    属性名: 属性值;
                }
                
            d) 选择器的分组
                多个选择器使用同一个样式
                语法:
                选择器,选择器,选择器{
                    属性名: 属性值;
                }
                
            f) 选择器的派生
                在选择器下的有所标记样式.
                选择器.标记{
                    属性名: 属性值;
                }
    
    4.2 样式的优先级
        1) 默认样式: 浏览器默认的样式.
        2) 外部样式: 样式来源css文件.
        3) 内部样式: 定义在html的<head>标记中的样式.
        4) 内联样式: 定义标记里的样式.
        注意: 从上到下,优先级越来越高的顺序.
        
    4.3 两个关键的属性
        
        1) display属性
            用于控制标记是否显示.
            值:
            none :  不显示标记
            block:  按照标记的方式显示
            inline: 按照行内标记的方式显示
            
        2) position属性
            用于控制标记的位置
            值:
            static(默认值): 浏览器在默认情况下,会从左到右,
                             从上到下一次排列标记.
            absolute:     相对父标记偏移.
            relative:     先按照默认方式摆放,然后再偏移.



1. position属性
    用于控制标记的位置,需要配合偏移像素(left, top)属性使用
    值:
    static(默认值): 浏览器在默认情况下,会从左到右,
                     从上到下一次排列标记.
    absolute:     相对父标记偏移.
    relative:     先按照默认方式摆放,然后再偏移.
    
2. 块标记和行内标记
    1).块标记(另起一行)
        每个标记占一行显示.其他的同等级标记在显示时会另起一行.
        
        常见的块标记:
        <div>:    层标记,在标记当中可以放置任意内容.本身一块透明的
                             无边框的矩形模块标记.
        <p>  :    段落标记,标记中的文字会上下各空一行.
        <img>:    图片标记,用于存放图片(jpg,png,gif)
        <form>:   表单标记.
        <table>:  表标记.
        <h1...h6>:标题文字标记
        <ul>:     列表标记
        <li>:     列表项标记
        
    2). 行标记(标记在一行显示)
        每个标记显示时,挨着上一个标记显示(在同一行).
        常见的行内标记:
        <span>  :  文字标记.
        <strong>:  粗体文字标记.
        <a>     :  超链接标记.
        
3. 常见的属性
    1). 文本
        font-size:  60px;     字体大小-像素作为单位(px)
        font-family:"宋体"     字体
        font-style: italic;   字体风格
        font-weight: 100;     字体的从粗细
        text-align: center;   字体的水平对齐方式
        text-decoration: underline; 下划线
        color: red;           字体颜色
        cursor: pointer       光标形状
        
    2). 背景
        background-color: red;          背景颜色
        background-image: url("");      背景图片(url中的内容是图片路径)
        background-repeat: no-repeat    背景图片的平铺方式
        background-position: 20px 10px; 背景位置
        background-attachment:fixed     依附方式
        
        简写
        background: 背景颜色 背景图片 平铺方式 依附方式 水平位置 垂直位置

    3). 边框
        border: 宽度 风格 颜色
        border-left:    左边框
        border-right:   右边框
        border-bottom:  底边框
        border-top:     顶边框

    4). 定位
        外边框定位
        margin:
            margin-left:
            margin-right:
            margin-top:
            margin-bottom:
            
        简化模式:
        margin: 上px; 右px; 下px; 左px;
        margin: 0px;
        margin: 20px auto;   上、下各20px,左右等分.
        
        内边框定位
        padding:
            padding-left:
            padding-right:
            padding-top:
            padding-bottom:
            
        简化模式:
        padding: 上px; 右px; 下px; 左px;    
        padding: 0px;
        
        注意:
        子标记会将父标记撑开.

4. 列表相关
    1). 相关的属性
    list-style-type: none;   // 取消列表的选项符号
    
    2). 浮动
    float: left/right
    clear: both;             // 取消浮动的因影响.
                             // 控件依然会浮动,但是原有位置
                             // 不可以放置其他控件
                             
5. Javascript脚本语言
    javascript是网景公司开发的一种在浏览器上执行的脚本语言
    需要嵌入到html中并且由浏览器执行.
    
    语言基础
        1). 标识符(变量名)
        由字母或下划线和$开头,后面可以是字符,数字和下划线以及
        $组成的.
        语句是以分号(;)作为结尾.
        
        2). 数据类型
            a) 基本数据类型
                number(数字类型)
                    1). 代表数字类型,不管是整数还是小数.
                    2). 存在一个对应的包装类Number
                    最大值: Number.MAX_VALUE
                    最小值: Number.MIN_VALUE
                    如果超过中个范围,返回Infinty
                    
                string(字符串类型)
                    在js中没有char类型,只要是字符类型都是
                    string并且,string类型是一个基本类型.
                    存在包装类String
                    length属性:     返回字符串的长度
                    charAt(index): 返回指定位置的字符(string)
                    match(regex):  返回匹配指定正则表达式的字符串
                                       返回结果是一个数组.
                    search(regex): 返回按照正则表达式检索的字符串.
                    
                boolean(布尔类型 true/false)
                    不为空的字符串,表示为true.(需要转换)
                    非0的数字,表示为true.(需要转换)
                    null、undefined, 表示为false.
                    包装类Boolean.
                    
                null(空类型,只有一个值null)
                    一般配合typeof 检测类型时使用,并且返回
                    是一个object.
                
                undefined(未定义类型)
                    只有一个值undefined.
                    检测页面上的标记,或者某个标记的某个属性,如果
                    不存在则返回undefined.
            
            b) 引用类型
                Array(数组)
                    数组的长度可以改变,并且数组元素的类型可以混合
                    存放.
                    
                Function(函数)
                    使用function关键字定义函数
                    函数不能有返回值类型,但是可以有返回值.
                    函数内部,可以使用arguments进行传参.



1. 创建节点
    DOM操作创建一个元素到页面中.
    document.createElement("tagName");
    
2. 添加节点
    a. 作为子节点添加
        通过DOM对象的 appendChild(node) 方法将元素
        作为DOM的子节点添加到页面当中.
        
    b. 替换原有节点
        通过DOM对象的 replaceChild(newNode, oldNode)
        方法将原有的元素替换为新的元素.
        
    c. 在某个节点前添加
        通过DOM对象的 insertBefore(newNode, oldNode)
        方法将元素添加到某个指定节点之前.
    
3. 删除节点
    DOM操作删除页面中的一个元素
    node.removeChild(node)
    
    确认框
    confirm(提示信息)会弹出一个带有确定/取消按钮的弹窗
    根据点击不同的按钮会对应返回true/false作为结果.
    
4. Html dom
    html dom指的是在W3C的DOM规范出现之前,各个浏览器的支持的
    一些dom操作.最典型的代表就是select对象.
    
    1) Select对象
        属性
            a: selectedIndex 选项的下标,从0开始
            b: length        获取或者设置选项的个数
            c: options       返回一个数组,元素是选项(Option对象)
            
    2) Option对象
        属性
            a: text          选项的文本内容
            b: value         选项的value属性值
            c: selected      返回选项是否被选中,选中true反之false
    
        小知识: 创建一个Option对象
            var op = new Option(text, value);
        
    3) Table对象
        属性
            tHead:    返回表格的thead节点
            tFoot:    返回表格的tfoot节点
            tBodies:  返回表格的所有的tBody节点
            rows:     返回表格的所有行
        方法
            insertRow(index): 在index位置插入一条新的行,
                                                  返回TableRow对象.
            deleteRow(index): 删除index处的行.
    
    4) TableRow对象
        属性
            cells: 返回行中的所有单元格(TableCell).
        方法
            insertCell(index) 在index位置插入一个单元格,
                                返回TableCell对象.
            deleteCell(index) 删除index位置的一个单元格.
            
    5) TableCell对象
        表的一个单元格
        
5. JS框架property-js
    获取页面元素:
    $("id")  ==> document.getElementById("id");
    $F("id") ==> document.getElementById("id").value;
    特性:
    可以使用html dom对象.



1. BOM模型
    BOM(Browser Object Model)浏览器对象模型,是浏览器内置的
    一些对象,用来操作窗口.这些对象包括window, document,
    XmlHttpRequest等.这些对象没有规范,但是各个浏览器都支持这些对象.
    
    1.1 window对象
        方法
            1) open方法
                打开一个新的窗口, 例如:
                window.open(
                    "xxx.html",     // 目标页面
                    "new",          // 弹出的窗口名字
                    "height=200,    // 窗口高度
                     width=100,     // 宽度
                     top=0,         // 窗口距离屏幕顶部的位置
                     left=0,        // 窗口距离屏幕左边的位置
                     toolbar=no,    // 是否显示工具栏, yes是显示
                     menubar=no,    // 是否显示菜单栏, yes是显示
                     scrollbar=no,  // 是否显示滚动栏, yes是显示
                     resizeble=no,  // 是否允许改变窗口大小,yes允许
                     location=no,   // 是否显示地址栏, yes是显示
                     status=no")    // 是否显示状态信息.
                );
                
            2) close方法
                window.close();
                关闭窗口(返回被关闭的窗口的对象句柄)
            
            3) alert方法
                alert();
                弹出信息提示框(只有一个确定按钮)
                
            4) confirm方法
                confirm();
                弹出消息提示框(存在确认与取消按钮),返回值为true/false
            
            5) prompt方法
                prompt();
                弹出一个可供用户输入的对话框,返回用户输入的信息.
        
            6) setTimeout方法
                setTimeout(function(){}, time);
                参数一: 执行的方法.
                参数二: 毫秒数.
                方法用于在指定的毫秒数后调用执行.
                
            7) setInterval方法
                setInterval(function(){}, time);
                参数一: 执行的方法.
                参数二: 毫秒数.
                方法用于重复执行函数,间隔是设定的毫秒数.
                方法返回一个taskId的对象,用于停止执行时
                的对象.
                
            8) clearInterval方法
                clearInterval(taskId);
                停止某一个setInterval所执行的函数.
            
        属性
            1). status属性
                设置或返回窗口状态栏的文本内容.
                
            2). document属性
                获取document对象
            
            3). location属性
                获取Location对象(路径)
                
            4). navigator属性
                获取Navigator对象
            
            5). opener属性
                获取当前打开的窗口对象
            
            6). parent属性
                获取当前窗口的父窗口
                
2. 面向对象

    2.1 如何创建一个js对象
        1) 使用new关键字
            var p = new Person("lisi", 22);
            p.plays(); // 对象中的方法
        
        2) 使用json
            var p = {
                        "name":"lisi",
                        "age":"22",
                        "address":{
                            "city":"shenyang",
                            "street":"yuanhangxilu"
                        }
                    }
            注意:
            属性值如果是字符串必须用引号(")引起来,在某些浏览器下
            如果属性值不是字符串可以不用引号(")修饰.但是建议都使
            用.
            
        3) 使用Object
            Object是所有js类型的父类.
            var p = new Object();
            // js是一种弱类型语言,可以在运行时改变类型
            // 为对象增加新的属性和方法
            p.name = "lisi";
            p.age = 22;
            p.play = function(){alert("hello world!");};
            
    2.2 如何定义一个对象
        定义对象是使用function关键字,类似定义普通函数但是内容
        不同.
            
        注意: 对象的属性一定是用this才能调用,否则只是普通变量.



访问地址:
http://127.0.0.1:9080/JspDay01/listCookie.action
两部分:
第一部分: 服务器地址:端口号
第二部分: 请求资源路径(项目名/请求名?请求参数&多个参数)




1.JSP
java server page(java 服务器页面技术).是sun公司制定的一种用于
服务器动态页面效果的技术.

2.JSP的页面组成部分
    a. html(包括css,javascript)
    
    b. java代码
        第一种: <% ...java代码 %>
               java代码的代码片段.
        第二种: <%=...java代码 %>
    
    c. 指令
        页面中用于区别JSP页面与其他页面的指令,也可以增加jsp页面的
        额外功能.
        
        语法:
            <%@ 指令名 属性名=属性值 %>
        常用的指令:
            import 属性:
            用于导入java代码包.
            例如: <%@page import="java.util.List" %>
            
            contentType 属性:
            用于配制html的contentType属性 等价于<meta>标记
            
            pageEncoding 属性:
            通知jsp引擎,jsp文件在保存时的编码格式.
            
            file属性:
            在jsp页面中引用其他JSP页面.
            <%@include file="文件路径.后缀名" %>
    
    d. 内置(隐含)对象
        所谓隐含对象,在jsp文件中,不用创建和声明直接就能使用的对象,
        在jsp的java代码中已经创建并声明好的对象.
        
        out对象:      用于在页面显示信息,来源于response对象.
        request对象:  请求对象,可以获取来自请求的信息.
        response对象: 响应对象,可以设置响应属性.
        
2. 状态管理
    将客户端(一般指的是浏览器)与服务器之间的多次交互当作一个整体看待,
    多次操作所实际的数据数据以及状态.
    
    第一种方式: cookie
    第二种方式: session (会话:每一个浏览器与服务器之间的交互)
    
    cookie:
    浏览器通过服务器的指令在浏览器所在的物理地址上开辟一块空间,用于存储
    浏览器与服务器之间的交互数据.
    
    特点:
    相同应用下的同名cookie会进行覆盖.后追加的同名cookie会覆盖前面已存
    在的cookie值.
    cookie是随着请求对象(request)传递到服务器中.
    
    1). 创建cookie:
        Cookie cookie = new Cookie(String name, String value);
        // 将cookie绑定到response对象上
        response.addCookie(cookie);
    
    2). 查询cookie:
        Cookie[] cookies = requset.getCookies();
        // 如果当前浏览器中不存在cookie 返回值是null
        String name = cookies[0].getName();
        String value = cookies[0].getValue();
    
    3). cookie的编码问题
        Cookie支持Ascii码值.在默认情况下cookie不支持中文编码.
        需要将中文转为换Unicode码才能够将中文写入cookie.
        URLEncoder.encode(String src, String pattern);
        将中文按照指定的格式转化成Unicode码.编码操作.
        URLDecoder.decode(String enocde, String pattern);
        将转换好的Unicode码按照指定的规则解码成中文文字.解码操作.
    
    4). cookie的有效时间
        默认情况下,cookie会保存到本次会话结束(当前浏览器关闭时,删除
        cookie).
        可以通过setMaxAge(int second)进行设置.
        操作单位是以秒为单位.
        当second > 0时, 浏览器将会把cookie存放到本地硬盘当中.
        当second < 0时, 浏览器把cookie存放到内存中,并且关闭浏
        览器时删除(默认状态).
        当second = 0时, 立刻删除该cookie.
        注意:
        过期,指的是当cookie存在时间超时,那么服务器将无法获取到已
        过期的cookie,但是作为存放在硬盘上cookie却依然存在于硬盘
        中.
    
    5). cookie路径的问题
        浏览器在向服务器发送请求时,会比较cookie的路径与服务器的访
        问路径是否一致.只有路径一致时,服务器才能获取到浏览器携带的
        cookie.
        setPath(String path)方法给cookie设置路径.



1.Session
    浏览器在访问服务器时,服务器会创建一个session对象(会话对象),该
    对象存在一个id(sessionId)在默认情况下,服务器会将sessionId
    响应到发送请求的浏览器的cookie中.并且只保存到浏览器关闭之前.
    当浏览器再次发送请求访问服务器时,会从cookie中携带sessionId访
    问,服务器会检查从浏览器携带的sessionId是否与服务器中的sessionId
    一致.如果不一致则本次session失效.如果用户禁用cookie,服务器中的
    sessionId在默认情况下将不能发送到浏览器中.
    
    1). 获取session对象
        方法一:
            HttpSession session =
                request.getSession(boolean flag);
            当 flag = true
                服务器会先查看请求中是否包含session
                如果没有,则创建一个session对象
                如果有,则依据sessionId去查询对应session对象.
                如果找到匹配的对象,则返回,如果找不到, 则返回null.
            当flag = false
                服务器会先查看请求中是否包含session
                如果没有 则返回null
                如果有,则依据sessionId去查询对应session对象.
                如果找到匹配的对象,则返回,如果找不到, 则返回null.
        方法二:
            HttpSession session = request.getSession();
            相当于 flag = true
    
    提示:
        当访问jsp的时候,服务器会检查浏览器的cookie中是否包含
        sessionId,如果有则与服务器中的session比对.如果没有
        则发送一个sessionId到cookie中.



1. MySQL中型数据库.
    创建数据库:
        // 创建数据库,并且设置该库的默认编码格式为UTF8
        create database 数据库名 default charset utf8;
    
    查看数据库:
        // 查看当前MySQL中存在哪些数据库
        show databases;
        
    使用数据库:
        // 切换到指定的数据库
        use 数据库名;
        
    删除数据库:
        // 可以在任意位置使用
        drop database 数据库名;
    
    查看数据库下所有表:
        // 查看数据表
        show tables;
        
    数据类型:
           类型       |    Oracle    |   MySQL       |   JAVA
        整数类型            number(10)    int(10)      int
        整数类型(长)  number(12)    BigInt(12)   long
        浮点类型            number(7,2)   double(7,2)  double
        字符串类型(1) char(20)          char(20)       String
        字符串类型(2) varchar(20)   varchar(20)  String
        字符串类型(3) varchar2(10)    -          String
        日期类型           date          date          Date
        
    备注:
    在Oracle中默认的日期显示格式是根据当前系统的语言决定的.
    格式固定为: 日-月-年,其中月为英文时,是简写.
    在Oracle中插入日期时,要么是严格按照格式插入,要么使用to_date()
    函数进行转换.
    
    MySQL中的分页查询:
        使用关键字: limit n[,m]
        当参数为一个时:
            表示从表的第一行数据开始,一直到n(包括第n行数据)行数据为查询
            结果.
            例如:
                select * from t_emp limit 3;
            表示:
                从t_emp中查询前三条数据.
                
        当参数为二个时:
            表示从第n行(不包括n行的数据)开始,取m行数的数据为查询
            结果.
            例如
                select * from t_emp limit 3, 2;
            表示:
                从第3行(不包括第3行)开始,向下取2行(第4,5行)数据
                为查询结果.
    
    MySQL与JDBC
    1. 连接URL
        jdbc:mysql://localhost:3306/emp
    
    2. 用户名
        root
        
    3. 密码
        自定义的
    
    4. 驱动类的类名
        com.mysql.jdbc.Driver
        
    MySQL建表时主键自动增长:
        auto_increment关键字, 默认从1开始,每次插入数据时自动增长1.
        即使之前的数据有删除行为,那么增长值依然继续增长,不会受到影响.
    
    Oracle数据库的主键自动增长:
        需要使用数据库对象:(序列sequence)来配合完成.
        序列默认是从1开始,每次调用自动加1.一个序列可以被多个表使用
        但是不建议.
        
        序列(sequence):
        创建语法:
            create sequence 序列名;
        调用语法:
            序列名.nextval



1. 过滤器
    a. 定义
        servlet规范当中定义的一个特殊的类,用于对servlet请求的过滤和
        拦截.
        
    b. 实现方式
        1). 实现Filter接口
            javax.servlet.Filter;
        2). 覆盖doFilter()的方法
        3). 配置web.xml
    
    c. 配置初始化参数
        在web.xml中,使用<init-param>标记配置初始化参数
        (与Serlvet的初始化参数设置一样)
    
    d. 过滤器的优先级
        当多个过滤器都满足过滤条件时,依据<filter-mapping>标记
        的先后顺序执行.



1. 监听器
    用来管理,监控事件的触发或执行.
    监听分为两大类:
    第一类:
    生命周期的监控,request、session、ServletContext等生命
    周期的监控.
    第二类:
    在设置属性时,进行监听.
    配置在web.xml中的<listener>标记中配置
    实现:
        根据不同的对象,实现不同的接口
    案例:
        记录当前的网站的连接数量.
    
2. SerlvetContext接口
    web服务器启动时,会为每一个已部署的web应用创建一个唯一的
    SerlvetContext对象,该实例会一直存在,直到服务器关闭或
    者应用在服务器被卸载.
    
    获取方式:
        1. HttpSession     提供getServletContext的方法.
        2. ServletConfig   提供getServletContext的方法.
        3. GenericServlet  提供getServletContext的方法.
        
    绑定属性:
        通过setAttribute(String name, Object value);
        通过getAttribute(String name)获取属性(类型是Object)
        通过removeAttribute(String name) 移除属性.
        
    配置全局初始化参数
        在web.xml中,使用<context-param>配置参数,可以被配置
        在web.xml中的任意Servlet访问.
        使用String类型的
        ServletContext.getInitParameter(String name)
        
3. Jsp中的内置对象(隐含对象)
    1). out对象                    ====> response.getWriter();
    
    2). request对象
    
    3). response对象
    
    4). session对象
    
    5). application对象   ====> ServletContext
    
    6). exception对象
        当在一个页面中设置了<%@page isErrorPage="true"%>,
        表示当前页面为错误页面,异常信息会再本页显示.
        
        调用页面配置<%@page errorPage="xxx.jsp"%>
        
    7). config对象             ====> SerlvetConfig
        用于加载初始化配置参数的对象
        
    8). pageContext对象
        是PageContext类的实例,服务器会为每一个jsp实例(指定的
        jsp对应的servlet对象创建的唯一的实例).
        作用主要有2个:
        a. 绑定数据
        b. 通过该对象,可以获取其他8个对象.
        
    9). page对象
            表示jsp实例本身.
    
4. jstl与el表达式
    4.1 jstl是什么
        java standard taglib(java标注标签库)
        
    4.2 标签
        是sun公司制定的一种技术规范,用来将jsp页面中的java代码替换
        成类似html标记的一种技术.
    
    4.3 el表达式
        sun公司制订的一种用于计算的一种规则,可以取值,也可输出值.
        
        基本语法:
            ${el表达式 }
            1). 访问javaBean的属性
                jsp引擎会依次从pageContext,request,session,
                application查询数据.
                
                例如:
                    ${user.name}
                    先从四个对象中找到名称为user的属性,根据user的类型
                    去访问.后面的内容,实际访问的是getName().
                
                    ${user['name']}
                    访问结果与${user.name}相同.
                    
                    ${user[name]}
                    此时的name是一个变量,而不再是固定的字符串.
                        
            2). 从指定的对象中访问数据
                指定从pageContext取值: pageScope.user.name
                指定从request取值         : requestScope.user.name
                指定从session取值         : sessionScope.user.name
                指定从application取值 : applicationScope.user.name
                
                一旦指定了取值对象,那么如果对象中没有对应的属性,则返回null.
            
            3). 获取请求参数
                request.getParameter("name")
                ${param.name}
                获取从请求传递过来的参数
        
            4). 计算表达式,将表达式的结果作为标签的属性值或直接
                输出.
                a. 算术运算
                    +、-、*、/、%
                b. 关系运算
                    >、<、>=、<=、!=、 ==
                c. 逻辑运算
                    &&、||、!
                d. empty运算
                    empty list
                    当list为空时,返回true.否则返回false

5. jstl
    java标准标签库.
    jstl.jar 以及 standard.jar
    
    1). 引入标签
        在jsp页面中使用taglib指令引入标签库
        
    2). 常用标签
        a. <c:if test="" var="" scope="">...</c:if>
            test属性:  当值为true时,执行标签体内的内容.
            var属性:   指定一个绑定名.
            scope属性: 指定一个绑定范围.
            scope属性可以通过将var属性中的内容作为名称绑定
            在指定的对象上(四个对象之一),绑定的值是test属性
            中的内容.
        
        b. <c:chose>
            分支标签,当某个条件满足时,执行对应的分支,每一个分支
            使用when标签来表示.(可以出现多次)
            <c:when test="">...</c:when>
                当全部分支都不满足时,使用otherwise标签执行(只出现一次)
            <c:otherwise>...</c:otherwise>
            
        c. <c:forEach var="" itmes="" varStatus="">
            用于遍历集合.
            items属性:     指定要遍历的内容(集合,数组)
            var属性:       指定一个绑定名,jsp引擎会从集中取一个对象,
                                          绑定在PageContext上
            varStatus属性: 指定一个绑定名,对应的的绑定值是一个java对象,
                             封装了遍历时的一些信息,包括当先遍历的下标(index)
                             以及遍历的次数(count)
        
        d. <c:set var="" scope="" value="">
            向指定的对象绑定数据
            var 属性:   绑定名
            value属性:  属性值
            scope属性:  绑定对象
        
        e. <c:remove var="" scope="">
            从指定的对象中移除指定属性.
            var属性:   属性名
            scope属性: 绑定对象
            
        f. <c:import url="">
            url指定一个jsp文件的地址,jsp会在运行时引用中个页面.



1. Servlet基础
    1.1 什么是Servlet
        Servlet是sun公司制定的一种用于扩展web服务器功能的组件规范.
        
        容器与组件
            组件是符合规范,实现功能并且可以在容器上运行软件的模块.
            容器是符合规范,为组件运行提供运行环境,并且可以管理组件
            的生命周期,将组件实例化之后,调用器方法,在调用之后将其
            销毁.
    1.2 如何写一个Servlet
        a) 创建一个java类
            servlet只能使用java类来编写
            实现Servlet接口或者继承HttpServlet抽象类
        b) 编译
            正常情况下应该是通过JVM进行.java文件的编译,因为
            IDE(编译器)集成编译操作,所以在Eclipse中只要保存
            即是编译.
        c) 打包
            将编译好的.class文件以及所使用的配置文件和页面文件
            打包成服务器可运行的war包.
        d) 部署
            将打包好的war包发布到服务器当中.
        e) 启动服务器,访问请求
            目前阶段服务器是部署在本地:
            服务器使用的是:tomcat
            访问路径:localhost:9080
                   127.0.0.1:9080
    
    1.3 Tomcat目录结构
        1). bin目录          存放启动和关闭服务器的一些文本命令.
        2). conf目录        存放服务器的一些配置文件.
        3). logs目录        存放服务器相关日志信息,比如服务器报错信息.
        4). webapps目录  存放部署在服务器的项目的目录.            
        5). work目录        存放服务器运行时,生成的一些临时文件.
        
    1.4 HelloServlet编写
        1) 继承HttpServlet类
        2) 覆盖参数为HttpServletRequest以及HttpServletResponse
              的serivce方法.
        3) 部署到tomcat中
        4) 访问:
               默认路径: 服务器地址:端口号/项目名/请求名
                    url:port/projectName/requestName
           http://127.0.0.1:9080/ServletDay01/sayHello
           
    1.5 处理带有参数的请求
        参数的传递是通过键值对(key=value)的形式传递,通过问号(?)
        连接在访问路径之后,多个参数之间用与符号(&)连接,无论是任何
        类型的参数都没有引号修饰.
        
        在servlet中获取从请求带来的参数使用的是request对象的
        getParameter(参数名)方法.默认类型是String类型,可以
        根据需求对参数类型做转化处理.
        
    1.6 Web项目的结构
        src目录:     代码以及配置文件的目录
        WebRoot目录: 页面以及web.xml的目录,所有的页面以及
                    效果(css)还有脚本(JS)全部在本目录下.
        WebRoot
            |
            |---META-INF
                    |
                    |---打包之后额外的配置信息
            |---WEB-INF
                    |
                    |---lib
                    |    |
                    |    |---项目所用的所有第三方jar包
                    |
                    |---web.xml web项目的配置文件
        页面文件可以放置在WebRoot下也可以是WEB-INF下但是不能
        放在META-INF下.
        WEB-INF下的内容是私有内容,只能通过请求访问,不能通过地址
        直接访问.
    
2. http协议
    定义:
        超文本传输控制协议,是一种应用层协议,定义浏览器(也可以是其他程序)
        与web服务器之间的通讯的过程与数据的格式.
    
    过程:
        1). 浏览器打开与服务器之间的链接.
        2). 打包数据,发送请求到服务器.
        3). 服务器响应请求,将响应数据打包发给浏览器.
        4). 服务器断开与浏览器的链接.
        注意:
        每次浏览器与服务器之间的交互都会打开一个新的链接,一旦请求
        处理完成浏览器得到了相应的响应,那么本次交互结束.服务器会
        主动断开与浏览器的链接.
    
    数据包的结构
        1). 请求数据包(Request)
            第一部分: 请求行(数据包中的一行内容)
                请求行包含三个内容:
                a): 请求方式(get/post)*
                b): 请求资源路径(端口号后面的内容)
                        比如:/helloServlet/showName
                c): 协议的版本与类型
                
            第二部分: 若干消息头(消息头是由W3C定义的一些特殊含义的键值对)
                消息头的样式: 比如:content-type=text/html
                服务器和浏览器会遵守这些消息头的约定.    
                消息头一般是由浏览器或者服务器自动生成,但是也可以自定义.
            
            第三部分: 实体内容
                如果是get方式,请求参数与值会包含在路径当中.
                如果是post方式,请求参数与值会存在当前位置.
        
        2) 相应数据包(Response)
            第一部分: 状态行
                协议的类型与版本
                协议的状态码(状态码是一个数字,不同的数字代表不同含义)
                500: 系统错误(代码崩了或者是配置文件错误.)
                404: 找不到资源(访问路径不正确)
                405: 响应请求的方式不正确(service方法名错误)
                200: 正常
            第二部分: 若干消息头
            第三部分: 实体内容
                服务器返回给浏览器的处理结果.
        
3. 使用表单发送请求
    http://127.0.0.1:9080/    // 服务器URL
    helloServlet/             // 请求资源路径中-项目路径
    addEmp.action             // 请求资源路径中-请求路径
    ?name=%E5%A4%A7%E6%BB%A1  // 请求所携带的参数以?与路径区分
    &salary=2.5               // 多个参数以&作为间隔
    &gander=%E7%94%B7         // 参数必须是key=value的形式.
    
    form表单的action属性值是提交的请求地址.
    提交的请求参数就是表单标记中的元素的value或innerHtml
    参数名就是对应元素的name属性



1. get/post请求
    1). get请求
        a). 在浏览器的地址栏输入一个地址.
        b). 表单的默认提交方式.
        c). 超链接,点击链接的时候也是get请求.
        
    2). post请求
        表单设置提交方式为post.form标记设置method属性值为post.
        
    3). get/post请求区别
        get方式会将请求参数以及参数值存放在请求资源路径里面,携带参
        数大小是有限制的(限制取决于浏览器,浏览器的地址栏允许输入的文
        字的数量),不合适较大数据的提交.
        post方式将参数以及参数值存放在实体内容当中,理论上是没有限制
        的,适合较大数据的提交.
        从安全角度上看,post提交方式相对安全一些.这个安全指的是数据被
        存放在实体内容中,但是没有做加密处理.
        
2. mysql的简单使用

    1). 简单的命令
        a).查看数据库
            show databases;
            
        b).使用数据库
            use 数据库名;
            
        c).查看当前数据库下存在哪些表
            show tables;
        
        d).查看表结构
            desc 表名;
            
        e).创建数据库
            create database 数据库名 ---mysql默认的字符编码格式
            或者
            create database 数据库名 default character set utf8
            create database t_emp default character set utf8
            
        f).创建表
            类型:
                bigint: 对应java中的long类型,默认长度是20.
                double: 对应java中的double类型.
                int   : 对应java中的int类型,默认长度是11.
            属性:
                auto_increment:设置自动增长(整型),默认值从1开始,
                                                每次递增1.一般情况是配合主键使用.
        
            create table t_emp(
                id      bigint      primary key auto_increment,
                name    varchar(50) not null,
                salary  double      default 0,
                age     int
            );
            
3. 重定向
    当浏览器的一次请求发送到服务器中,服务器在处理请求时将请求发送到
    另一个位置进行处理.浏览器并不知道请求不是原来的位置.



1.Servlet中的通配符.
    在web.xml中配置servlet-mapping标记时,在子标记
    url-pattern配置中可以使用*号作为通用配置(/*).
    配置带有后缀名的通用配置时,不能使用斜线(/).
    例如:
    <url-pattern>*.action</url-pattern>
    表示所有后缀名为.action的 请求都会被servlet执行.



1.JSP页面模版
    可以动态生成页面,页面中部分数据是由服务器响应过来的.
    JSP的消息头
    <%@ page language="java"
        contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
    
    jsp在被访问到服务器中时,会在服务器生成一个.class文件以及一个.html
        文件,.class文件是用来实现页面中的逻辑以及动态数据,.html文件用来
        返回给浏览生成的静态页面.
        
        在JSP页面中引入java代码:
        方式一:
        <%=.. %> 直接将java代码的结果显示在页面上 .
            注意:在代码的结尾处不要加分号(;)
    方式二:
        <% ... %> 将java代码块嵌入jsp页面中,代码的结果需要配合
        内置的out对象显示在页面中.       
        
    request.getContextPath()==>获取项目核心位置.



1.Servlet的生命周期
    1). 创建对象
        在servlet部署到服务器中时,当请求到达Servlet时会创建对应的
        servlet对象.在正常情况下每一个servlet类只创建一个对象(
        单例模式).
    
    2). 初始化配置
        在创建对象之后,会主动调用init()方法进行初始化配置,默认情况下
        每一个servlet只调用一次init()方法.如果想多次调用,则需要将该
        对象销毁后再次创建.
        
        初始化时,加载一些参数.
        在web.xml中配置.配置在Serlvet标记中.
        
        <init-param>
              <param-name>key</param-name>     // 参数名
              <param-value>value</param-value> // 参数值
          </init-param>
        
    3). 调用service()方法处理请求
        当请求到达servlet的时候,会调用service()方法处理请求,并生成
        响应.
        
    4). 销毁对象
        在Servlet从服务器中卸载时,会调用destroy()方法销毁servlet
        对象.
        
    注意:
    在 servlet 的整个生命周期当中,init,destroy 只会执行一次,而
    service 方法会执行多次。



1. MVC 和 JSP model
    1) M-Model 模型层
        模型是负责业务逻辑的管理.包含两个部分:业务层和数据层.
        Service以及DAO
        
    2) V-View 视图层
        视图是负责显示界面和用户交互(收集用户信息).
        属于视图的类是不包含业务逻辑和控制逻辑的.
    
    3) C-Controller控制层
        控制器是模型层(M)和视图层(V)之间的连接,用于控制流程.
        例如之前接触过的Servlet
    
    Jsp Model 1
        0) 当请求提交到控制器(Servlet)
        1) 分发请求(在Servlet中根据请求,调用不同的Service)
        2) 根据不同的Service选择不同的DAO
        3) 从DAO查询出的数据会依据方法的调用一层一层的返回给Servlet
              并且在Servlet中将DAO层查询出的数据绑定给Request
        4) 通过Servlet的转发机制,将查询到数据转交给对应的JSP页面
        
        缺陷:
        当所有的请求都只通过一个Servlet处理时,会导致代码臃肿 ,可维护
        以及可读性变差.
        
    Jsp Model 2
        1) 所有的请求都发送到Servlet中,也称之为前端控制器
        2) 前端控制器会维护一个配置文件,文件中是预先配置好的请求路径
        3) 前端控制器会根据配置文件以及请求信息调用对应的Action进行处理
        4) 控制层的Action会调用对应的Model来实现逻辑.
        5) 控制层的Action拿到从Model层返回的数据.数据默认绑定在Request
        6) 将数据转交给JSP
        
2. Struts2
    最早的时候出现的Struts1是一个非常流行的框架,它实现了MVC的分层.
    Struts1很简单小巧,其中最成熟的版本是1.2
    之后出现了WebWork的框架,比Struts1更先进便捷.在之后的过程中由于
    影响力的问题Struts1结合WebWork的核心技术xwork整合出了现在的
    Struts2.
    
    Struts2中的核心jar包
        1) struts2-core-x.xx.x.jar
            Struts2核心包,是Struts的外壳.
        2) xwork-core-x.x.x.jar
            Struts2核心包,是WebWork的内核
        3) ognl-X.X.X.jar
            用来支持ognl表达式,类似EL表达式,比EL功能要强大
        4) freemarker-X.X.X.jar
            freemarker是比JSP更简单好用,功能强大的表现层.
            页面已.ftl结尾.并且不需要生成额外的.class文件辅助.
        5) commons-fileupload-x.x.x.jar
            用于实现文件上传功能.
            
    创建一个Struts项目
            快捷方式,右键点击项目名,在菜单下部分找到Myeclipse
            拉出菜单,找到Add Struts Capabilities点击之后
            选择需要的版本其他默认之后点击创建即可
            快捷方式需要注意:重复引jar包的问题.
        1). 在src下创建struts.xml的文件,路径必须是在src下
            并且文件名不能写错.
            文件中的内容(DTD头):
            struts2-core-X.X.X.jar中的struts-2.1.dtd
            
        2). 配置web.xml的过滤器
            通过过滤器将所有的请求拦截到struts中.
            struts2-core-X.X.X.jar
                |
                |--org.apache.struts2
                        |
                        |--dispatcher
                                |
                                |--ng
                                    |
                                    |--filter
                                          |
                                          |--StrutsPrepareAndExecuteFilter

        3). 创建一个Action类
            类的属性的值可以从页面获取,也可以传递给页面
            用于执行请求的方法返回值类型是String类型
            默认的方法名execute(),方法都是没有参数的.
            
        4). 配置struts.xml文件
            <struts>  在配置文件中,只有唯一的一组
            
            <package> 包含<action>元素的标记,在<struts>标记中
                                 可以存在多个,但是不建议在一个文件内出现多个
                      <package>
                                 属性
                      name属性:      唯一标识,可以被其他struts文件继承
                      extends属性:   继承其他struts文件中的<package>
                                           标记中的内容.对应的值就是被继承文件
                                           的<package>元素的name属性.
                      namespace属性: 应用名与请求名之间的路径,"/"表示没
                                      有其他路径直接应用名+请求名就可以访问.
            
            <action>  是用来指明每个请求对应的处理类.
                        属性:
                      name属性:   表示请求名(不要携带"/").
                      class属性:  表示处理请求所调用的Action类.
                      method属性: 表示处理类中,调用哪个方法处理请求.默认情况
                                     下使用的是execute()方法.方法的返回值类型
                                     一定是String
                                     
            <result> 是用来处理返回结果的元素
                     name属性: 用来区分处理结果.属性值对应的就是Action中用于
                                 处理请求的方法的返回值.
                                 
                     type属性: 用来设置返回结果的响应方式,默认的是转发.
                    
                     标记当中的文本内容定义了结果要返回到的页面.
                    
        5) action类中传值
            从页面到action中的传递是通过属性的set方法传值
            从action到页面的值传递是通过属性的get方法传递
            属性的get/set方法一定要存在,并且要和页面中的控
            件名称对应.否则无法传递.



1.Struts的核心
    1). Action类基本原理
        每一次请求到达服务器都会创建一个Action对象.
        所有的Action类被实例之后,会存放到一个栈当中.
        struts在处理请求的时候,一定获取栈顶的Action对象.
    
    2) 在Action中获取Session以及Application
        ActionContext act = ActionContext.getContext();
        Map<String, Object> session = act.getSession();
        或者
        <s:propety value="#session.XXX" /> 在页面中获取
        
        存在于struts核心jar包中的接口:
        实现SessionAware接口访问session(主流)
        类似接口:
        ServletRequestAware
        ServletResponseAware
        ServletContextAware
    
    3) 使用通配符配置Action
        <action name="*_*_*" class="day04.action.{1}Action"
            method="{2}">
            <result>/{3}.jsp</result>
        </action>
        
        {1}: 表示第一个星号(*)所代表的内容,在使用时会与后面的字符拼接在一起.
        {2}: 表示第二个星号(*)所代表的内容,用于指定处理请求的方法.
        {3}: 表示第三个星号(*)所代表的内容,用于指定返回结果跳转的页面.
        
        http://127.0.0.1:9080/StrutsDay04/Two_cc_two.action
        {1} = Two
        {2} = cc
        {3} = two
        
    4) 给Action注入参数(属性注入)
        <parm name="xxx">XXXX</param>
        name属性: 对应Action类中的属性名
        标记文本 : 表示参数的值
        底层在传递的时候,是通过Action中的属性的set方法实现的.
        
    5) 在struts配置文件中传递参数(OGNL表达式)
        使用?连接参数key=${value}
        
2. Result标签
    在Struts2中,功能强大的标签,实际上也是一个类,职责是生成视图.
    
    1). reuslt标签的type属性:
        a) dispatcher
            转发,也是缺省(默认)属性,在不配置type属性的时候默认值该值
            struts会自动将Action中的属性转发到配置的页面上.
        
        b) redirect
            重定向,会将请求重定向到其他页面或action中.
            
        c) redirectAction
            重定向action, 只能将请求重定向到其他Action中.
        
        d) stream
            以流的形式传递数据,一般应用于上传文件.
        
        e) json
            以json字符串的形式将数据发送到前台页面,或者是前台将
            json字符串传递给后台Action.
        
        f) freemarker
            用于支持跳转freemarker框架的ftl页面.



1. 使用jQuery发送Ajax请求
    语法格式(通用):
        $.ajax({options})
        options是一个形式如(key1:value1,key2:value2....)形式的
        js对象.用于指定发送请求
        参数设置:
            url(string):          请求地址
            type(string):         请求方式(get/post)
            data(object/string):  发送到服务器的请求参数
            dataType(string):     响应参数类型:
                                  json   返回json字符串
                                  xml    返回xml文档
                                  html   返回一个html内容
                                  script 返回一个js脚本
                                  text   返回一个文本
            回调函数success(function(data, textStatus){})
                请求成功后调用的回调函数,有两个参数:data, textStatus
                    data :      服务器返回的数据
                    textStatus: 描述状态的字符串
            
            回调函数error(function(){})
                请求失败时调用的回调函数,有三个参数
                xhr, textStatus, errorThrown
                一般情况下使用textStatus比较多,是在请求异常时出现.
                
    get模式语法格式:
        $.get(url,[data],[callback],[type]);
            参数设置:
                url :     请求地址
                data:     请求参数,格式与$.ajax一样
                callback: 回调函数
                            格式function(data, textStatus);
                type:     响应参数类型与$.ajax设置一致.
                
    post模式语法格式与get完全相同
        $.post(url,[data],[callback],[type]);



1. 拦截器
    定义在struts.xml中的一个元素
    <interceptor name="" class="">
    多个拦截器可以组成一组
    <interceptors>
        ...
    </interceptors>
    struts在默认配置上会有一个固有的拦截器(basicStack),一定要执行
    如果不执行struts的大部分功能将失效.
    在struts.xml中使用时,名称为:defaultStack
    
    拦截器的写法:
        创建一个java类 实现 interceptor接口
        
2. struts.xml的引入
    在struts.xml中可以引入其他struts.xml文件.
    使用<include>标签进行引入操作
    
    文件上传:
        1). 需要使用fileUpload拦截器(struts提供的)
            使用的jar包
                a). commons-fileupload-1.2.1.jar
                b). commons-io-1.3.2.jar



1. 标记语言
    标记语言,是一种文本以及文本相关联的其他信息结合起来的语言。
    用于展现出关于文档结构和数据处理细节的电脑文字编码。当今应
    用较为广泛的标记语言是 超文本能标记语言(HTML)。
    
        1) 超文本标记语言(HTML)
            语法格式:<a href="link.html">跳转页面</a>
            特点: 标记是格式是固定,不可扩展的(<a>...</a>)
        
        2)  可扩展标记语言(XML)
            语法格式: 与html样式相同<a>...</a>
            特点: 标记格式可拓展.
            
        3) xml和html语言是同一种父语言SGML(标准通用标记语言).
        
        4) 语言的解析器
            a) 浏览器
            b) eclipse/myEclipse
        
        5) W3C
            w3c: 开源的语言协会, 万维网联盟(World Wide Web Consortium)
            Html以及Xml都是W3C制定的语言规则.
            
2. 可扩展标记语言(XML)
    消息头:<?xml version="1.0" encoding="gbk/gbk2312/utf-8" ?>
    标记: 可以任意内容
    格式: <标记内容>...</标记内容>
    注意: 起始标记和结尾标记中的标记内容必须一致.包括英文字母的大小写.
    
    语法规则:
        1. xml的声明
            指的是文件中的消息头
            <?xml version="1.0" encoding="gbk/gbk2312/utf-8" ?>
           注意:
           <? xml .... ?> 错误的,?与xml之间不能存在空格.
           version: 版本号必须是1.0
           encoding: 可以省略不写,但是对于中文处理时可能发生错误.
           
        2. 标记
            标记必须包括开始标记和结束标记.
            
        3. 元素(Element)
            a). 元素:     元素实际上是标记和标记中的内容.
            b). 根元素:   最为层的元素叫根元素
            c). 叶子元素: 是最里层的(没有子元素的)元素叫叶子元素
            d). 空元素:   没有元素内容的叫空元素.
                          例如: <a></a>, 可以简写为: <a/>
            规则:
             1). 所有标记必须有结束标记
             2). 开始标记和结束标记必须成对出现(空元素例外)
             3). 元素必须正确嵌套
                  例如: <a><b>...</a></b> 错误的写法
                         <a><b>...</b></a> 正确的写法
             4). 标记的大小写敏感 <Hello>和<hello>是两个不同的标记.
             5). 根元素有且只能有一个.
             
        4. 特殊符号(转义字符)
            a). 小于号(<) : less than  --> &lt;
            b). 大于号(>) : great than --> &gt;
            c). 与符号(&) : &amp;
            d). 双引号(") : &quot;
            e). 单引号(') : &apos;
            注意点: 所有特殊符号,必须以&开头,以;结尾.
            
        5. 属性(定义在开始标记中的键值对)    
            语法:
                属性="属性值"/ 属性='属性值'        
            要求:
                属性必须有值
                属性值必须用引号引起来,单引号或双引号都可以,
                但必须保持一致.
                
        6. CDATA 类型的数据: 特殊标记
            格式: <! [CDATA [文本内容]]>
            特殊标记中的实体引用(特殊符号)将被忽略,所有内容当成
            一整块文本数据对待.
            
        7. 注释
            格式: <!-- 注释内容 -->
            在html文件中,注释不会显示在浏览器里,但是在源码中存在.
            在xml文件中,注释会显示在浏览器,但是编译器不会对其进行编译.
            
        8. 规则小结
            1) 必须有唯一的根元素.
            2) xml中标记区分大小写.
            3) 标记必须配对出现(空标记是单独出现),有开始有结束.
            4) 元素必须被正确嵌套.
            5) 属性必须有值,值必须用引号引起来.值可以是空值.
        
        练习:
            创建db.xml文件
            根元素是 datasource 属性是id, 值db_oracle
            
            元素:property
            属性:name
            值 : url/dbUser/dbPassword/driver
            
            标记中的内容
            jdbc:oracle:thin:@localhost:1521:XE
            wanght
            123
            oracle.jdbc.driver.OracleDriver
            
3 DTD规则
    用于规范XML文件中的标记规则,凡是定义了DTD规则的XML文件
    中的标记必须按照规则使用.
    
    语法:
    <!DOCTYPE 规则名称[
        规则内容
    ]>
    内容语法:
        元素:
        <!ELEMENT 元素名称 (元素的内容)>
        元素内容:
        a. 其他元素(元素标记名)
        b. 文本内容(#PCDATA)
        属性:
        <!ATTLIST 标签名 属性名 属性类型>
        <!ATTLIST 应用图书 id CDATA #REQUIRED>  表示id属性必须出现
        <!ATTLIST 应用图书 name CDATA #IMPLIED> 表示name非必需出现
        <!ATTLIST 应用图书 ishot CDATA "false"> 表示ishot默认值是false



1. DTD文件
    用于规定XML中元素规则的规则文件.
    
    a.文件的定义
        后缀名为.dtd的存在xml消息头文件.
        文件中的内容是<!DOCTYPE XXX[]>中的中括号内的规则内容.
        
    b.文件的引用
        在要引用的xml文件中,声明文件的引用
        <!DOCTYPE XXX SYSTEM/PUBLIC 文件名.dtd>
        
    c.引用模式
        SYSTEM: 小范围的定义(一般情况下规则文件存在于本地)
        PUBLIC: 行业公用的(文件存在于某个服务器上,可以通过域名进行访问)
        
2. 在java中操作xml文件
    java在操作xml文件时,需要第三方jar包:dom4j.jar
    
    a. 将xml文件中的数据读入到java代码中
    
    b. 通过java代码,生成指定结构的xml文件    
    
    c. 两种解析方式:
    
        1). DOM(Document Object Model 文档对象模型)
            关键字: 树(Document)
            优点: 把xml文件中的元素结构转变成树形结构,可以遍历和修改
                  节点.
            缺点: 如果文件比较大, 内存压力会比较大,消耗时间长.
            
        2). SAX(Simple API for Xml 基于XML的简单API)
            关键字: 流(Stream)
                          把xml文件作为输入流,触发标记开始,内容开始,
                          标记结束等动作.
            优点:  解析可以立即开始,速度快,内存没压力.
            缺点:  不能修改节点.



1. Ajax技术
    异步的javascript和xml请求
    为了解决传统的web应用中"等待-响应-等待"的弊端
    而创建的一种技术,其实内部使用浏览器的一个内置的
    对象(XmlHttpRequeset)向服务器发送请求,服务
    器返回xml数据或者文本数据.然后再浏览器端,使用这
    些数据刷新局部页面.整个请求到响应的过程页面整体
    无刷新.
    
    "等待-响应-等待"
    指的是,在传统web应用中,比如注册,用户填写完整所有的注册信息,
    然后提交到服务器.此时,浏览器会将整个注册页面抛弃,等待服务器
    响应一个新的完整的页面,在等待过程中,用户不能够做其他操作.服
    务器生成的新的页面发送给浏览器,浏览器解析新生成的页面.
    
    Ajax执行过程
    1. Ajax引擎(浏览器内置对象XmlHttpRequest),首先为该对象
    注册一个监听器(该监听器是一个事件处理函数,对状态变更事件
    (reayStatechange)进行监听).
    
    2. 当用户对GUI(页面[jsp/html等])做了某种操作(产生事件的时候
          包括onclick或者onblur(失去光标事件)等).
    
    3. 一旦产生事件,将触发处理代码(function)
    
    4. 在执行处理代码(function)时,会调用Ajax引擎
    
    5. 发送请求: Ajax引擎被调用后,将独自向服务器发送请求(
          独立于浏览器之外)
         
    6. 服务器处理请求
    
    7. 访问数据库(需要时)
    
    8. 服务器将处理的结果(部分结果,可以是xml或者txt)响应给Ajax引擎
    
    9. 监听器通过Ajax引擎获取响应数据(xml或者txt)
    
    10. 监听器对GUI中的数据进行更新(局部更新,整个页面不动)
    
2. XMLHttpRequest对象的重要属性:
    1) onreadystatechange: 注册一个监听器也就绑定一个处理函数.
    
    2) readyState: 返回该对象与服务器的通讯状态
                 包含值:
                     0: (未初始化)对象已建立,但是尚未初始化.
                                        没有调用open()方法.
                    1: (初始化)对象已建立,尚未调用send()方法.
                    2: 发送数据(已调用send()方法).
                    3: (数据传输中),已接受到部分数据.
                    4: (响应结束)接收了所有数据.

    3) responseText: 获取服务器返回的文本
    4) responseXML:  获取服务器返回的xml dom对象
    5) status:       获取状态码
    
注意:
    当请求方式时get的时候,并且请求参数与url没变化的时候,浏览器将
    不会再次发送请求到服务器中,而是使用浏览器本身缓存.



1.JSON
    javascript Object notaction, 是一种数据交互的标准.一般
    是用于浏览器与服务器之间的数据转换.比如 一个java对象转换成浏览
    器可识别的javascript对象.
    
    1). 基本语法(Javascript下)
        a. 如何表示一个json对象
            var obj = {"name":"唐伯虎","age":"23"}
            嵌套使用:
            {"name":"秋香",
             "addr":{"street":"hz","number":"12138"},
             "age":"18"
            }
            
        b. 如何表示一个json数组对象
            [{},{},{}]
    
    2). 如何将一个java对象(包括数组,集合)转换成一个json字符串.
        使用json提供的工具类
        a). 单一对象转换
            JSONObject jsonObj =
                JSONObject.fromObject(Object obj);
            String jsonStr = jsonObj.toString();
    
        b). 如何将一个java数组/集合转换成json字符串
            JSONArray jsonArr =
                JSONArray.fromObject(List/Object[] obj);
            String jsonStr = jsonArr.toString();
        
    3). 如何将JSON字符串转换成JSON对象
        javascript中提供一个内置函数eval();
        使用方式: eval("(" + jsonString + ")");



1. JQuery
    javascript的框架,封装了针对javascript的一些脚本处理.
    
    1) dom操作
        a). 查询
            利用选择器找到节点.
            方法:
            text([string])
            输出或者设置节点之间的文本内容,相当与dom节点的innerText属性
            
            html([string])
            输出或者设置节点之间的html内容,相当于dom节点的innerHTML属性
            
            attr()
            输出或者设置节点的属性
            
            val()
            输出或者设置节点的value属性,此外,下拉列表也可以使用val()
        
        b). 创建jquery对象
            $(html)
            
        c). 插入节点
            append()
            向每个匹配元素内部追加内容
            
            prepend()
            向每个匹配元素内部追加前置元素
            
            after()
            在每个匹配元素之后加入元素
            
            before()
            在每个匹配元素之前加入元素
        
        d). 删除元素
            remove()
            删除指定的元素
            
            remove(selector)
            删除指定元素中的选择器筛选出的元素
            
            empty()
            清空节点(清除元素中的所有子元素)
            
        e) 复制节点
            clone()     复制元素(不复制行为)
            clone(true) 复制元素(复制节点所具有的行为)
            
    2) 选择器
        a. 基本选择器
            #id                      id选择器
            .class                   样式选择器
            element                  选择器
            selector, selector,...  多个选择器
            *                        当前页面下所有元素        
        
        b. 层次选择器
            select1 select2
            select1>select2
            select1+select2
            select1~select2
        
        c. 过滤选择器
            :first        例如:ul下的第一个li元素
            :last         例如:ul下的最后一个li元素
            :eq(index)    等于index位置的元素
            :gt(index)    大于index位置的元素
            :lt(index)    小于index位置的元素
            
        e. 属性过滤选择器
            [attribute]          属性名
            [attribute=value]    属性等于某个值的情况下
            [attribute!=value]   属性不等于某个值的情况下
        
        f. 表单对象属性过滤选择器
            :enabled      表单控件为未启用
            :disabled     表单控件不可见
            :checked      复选框或单选框被选中
            :selected     下拉列表被选中



1.    数据库的简介
a)    数据库(DB)
数据库本身是一个软件产品,用于存放数据.
b)    常用的数据库软件
大型数据库
Oracle  甲骨文公司第一款商品化的关系型数据.
DB2    是IBM的关系型数据库.以为大型机服务的数据库.
Sybase  美国Sybase公司的关系型数据库.
中小型数据库
SQL server 微软公司中型关系型数据库产品.
MySql     免费并且开源的关系型数据库产品,之前是一家美帝的小公司的产品.
           2008年的时候被oracle收购.
微型数据库
Access   微软捆绑在office下的微型数据库软件.
c)    SQL语言
是用在关系型数据库上,用于执行操作、检索以及维护所使用的语言。最基本的操作就是增、删、改、查。大部分的关系型数据库都支持该语言。每条语句已分号;作为结尾.
d)    DBA
数据库管理员。
e)    Table(表)
表 是数据中最基本的存储单元,主要作用于对应现实世界实体对象。横向称之为行(Row),也称之为字段。纵向称之为列(Column)。

2. 如何操作Oracle
    a)  创建一个连接
        1. 连接到数据库所在的服务器.指令: telnet  ip地址
|           目标地址的23号端口必须开放.
        2. 输入登陆服务器的用户名和密码.
        3. 登录成功后,使用指令: sqlplus 访问oracle数据库
        4. 访问的用户名以及密码(密码不显示).
b)  测试连接是否成功
        select * from dual;
    dual: oracle内置的虚表.只是用于查询常量使用.
c)  查询当前系统日期
        select sysdate from dual;

3. 创建表(User)
    a) 定义数据(表)结构
       id:          编号
name:        姓名
password     密码
phone        电话
email        邮箱
    b) 编写建表语句(create table)
       create table 表名_XXX(
   字段名  类型(长度),
      …
   字段名  类型(长度)
);
create table User_wanght(
id        number(4),
name      varchar2(20),
password  varchar2(20),
phone     varchar(20),
email     varchar(20)
);
注意: oracle当中,表名与字段名不区分大小写的.

e) 查询表结构(sqlplus命令):
desc 表名

f) 字段类型:
       数字:
       number(n)     整数(长度是n)
   number(n, m)  浮点数(整个数字的长度n, 可保留m位小数)
   例如:
   number(7, 2)  表示的最大值为 99999.99
   注意:         number类型也可以使用默认长度,默认长度是11位.
   字符串:
       char(n)       长度为n的字符串,如果存放的内容长度不足n,则使用空格补位.  
   例如:         char(6) 如果内容为abc, 则实际内容为abc___(_代表空格).
   varchar(n)    长度为n的字符串,如果存放的内容长度不足n,则该字符串最大的
长度为内容长度.
   例如:         varchar(20)如果内容为abc, 则实际内容也是abc,长度为3.
   varchar2(n)   特点与varchar完全一样,是oracle自己定义的.
   日期:
   date          不需要定义类型长度,oracle会自动赋予长度.

    g) 插入数据(insert into)
       语法:
       inser into 表名 values(值1, 值2, 值3,…,值n);
       含义:
       表示向表中的所有字段插入数据, values后面的小括号中的值的数量,
       必须与表中的字段数量一致,顺序必须匹配,类型必须匹配.
       案例:
       insert into user_wanght values
(1001, ‘李狗蛋’, ‘passw0rd’, ‘1300000000’, ‘ligoudan@126.com’);

h) 查询数据(select)
       语法:
   select 字段名1, 字段名2,…字段名n from 表名;
含义:
查询表中的数据,查询结果显示为 select后面跟着的字段.如果select后跟着星号
       * 表示查询表中的全部字段.
案例:
select * from user_wanght;

    i) 三种SQL语句
1) 建表    create table 表名(字段名 字段类型(长度),…);
2) 插入    insert into 表名 values(值…);
3) 查询    select 字段名, 字段名…/* from 表名;

j) sqlplus命令(结尾不需要使用分号)
   1) 查询表结构             desc 表名
2) 清屏                   clear scr
3) 设置显示宽度           set linesize 数值
4) 设置列宽度(非数字类型) column/col 列名 format/for a数值
5) 设置列宽度(数字类型)   column/col 列名 format/for 9 * 数量
6) 执行上一条SQL语句     /

k) 删除语句(delete from)
   语法:
   delete from 表名;
   含义:
   删除表中的全部数据,表结构依然存在.
   案例:
   delete from user_wanght;

l) 条件查询(where)
   语法:
   select 字段名/* from 表名 where 条件
   含义:
   根据条件查询对应的数据信息.
   案例:
   查询name 是李狗蛋的信息.
   select * from user_wanght where name = ‘李狗蛋’;
   注意: 如果查询条件的值是非数字类型,那么要使用单引号(西文符号)修饰.

    m) select查询结构
   1. select name, email from user_wanght
Id    Name    Password    Phone    Email
                
                
                
   
   2. select * from user_wanght where name = ‘李狗蛋’;
Id    Name    Password    Phone    Email
1001    李狗蛋    Passw0rd    1300000    …
                
                

n) 表结构操作语句
   1. 删除数据表(连表结构一起删除)
      语法:
      drop table 表名;
 


1. 查询当前用户所创建的表
    语句: select table_name from tabs;

2. 事务管理
    1) 事务提交
       指令: commit;
       提交对数据表中数据的增、删、改.

3. 创建dept表
    create table dept_wanght(
        deptNo    number(2),
        deptName  varchar2(20),
        location  varchar2(20)
    );
    插入数据(dept_wanght):
    insert into dept_wanght values
                    (10, '开发部', '沈阳');
    insert into dept_wanght values
                    (20, '财务部', '上海');
    insert into dept_wanght values
                    (30, '人事部', '北京');
    insert into dept_wanght values
                    (40, '后勤部', '苏家屯');
                    
    插入数据(emp_wanght):
    insert into emp_wanght values
        (1001, '大力哥', '歌姬', 500, null, '10-12月-11', 1002, 40);
    insert into emp_wanght(id, name, job,     
            salary, bonus, birthday, deptNo)
    values(1002, '典狱长', '看守', 1000, 500,
            '11-11月-11', 30);
    insert into emp_wanght values
        (1003, '犀利哥', '模特', 10000, null,'09-10月-76', 1004, 10);
    insert into emp_wanght values
        (1004, '春哥', '歌手', 5000, null,'30-9月-85', 1002, 40);
    
    插入语句:
    在表名后面可以标明要添加信息的字段,默认情况下是向表中所有字段添加数据.
    
4. oracle中的空(null)
    1). 在Oracle中任何数据类型都可以有null值.
    2). null值可以与任意类型的字段进行计算.
        计算的结果都为null值.
    3). null值与字符串类型进行连接操作时,结果
        相当于null值不存在.
        
    案例:
    计算每个人的实际收入(salary + bonus)
    查询字段: 姓名、工资、奖金、实际收入.
    select name, salary, bonus , salary + bonus
    from emp_wanght;
    
5. 字段(列)的别名
   语法1:
   字段 空格 别名
   select name, salary, bonus , salary + bonus money from emp_wanght;
   语法2:
   字段 as 别名
   select name, salary + bonus as money ...
   拓展:
   别名的使用不局限于字段名,表名也可以使用别名.
   
6. 空值函数(nvl)
   语法:
   nvl(字段名, 替换值);
   含义:
   将特定字段中的null值,替换成替换值.
   select name, salary, nvl(bonus, 0),salary + bonus money from emp_wanght;
   
   select name, salary, nvl(bonus, 0) as bonus,
       salary + nvl(bonus, 0) as money
   from emp_wanght;

7. 指定字段插入数据
    指定 name,id, job字段
    id = 1005, name = '曾哥', job = '歌手'
    insert into emp_wanght(id, name, job)
    values(1005, '曾哥', '歌手');
    
    查询姓名与职位,没有职位的显示"待业"
    select name, nvl(job, '待业') job from emp_wanght;
    
    查询姓名与生日,没有生日记录的显示当前日期
    select name, nvl(birthday, sysdate) birthday
    from emp_wanght;
    
8. 拼接字段(||)
   1.select name || job from emp_wanght;
   2.select name || '是' || nvl(job, '无业游民')
   from emp_wanght;
   案例:
   拼接:姓名与工资
   拼接结果: name的工资是salary
   
9. 复制表(create table)
    复制表中的数据以及表的结构,是来源于目标表的
    查询结果.
    语法:
    create table 表名 as 查询语句
    案例:
    create table emp_job as select name, job from emp_wanght;
    案例2:(错误)
    create table emp_job as select name, nvl(job, '待业') from emp_wanght;
    ORA-00998: 必须使用列别名命名此表达式
    案例3:(正确)
    create table emp_job as select name, nvl(job, '待业') job from emp_wanght;
    
10. distinct 去重复关键字
    必须跟在select 后面使用,与select之间不能有其他的关键字或字段名.null也计算在内.
    使用distinct关键字做去重复操作的时候,根据关键字后所有的字段匹配的.
    
    案例:
    查询emp_job表中存在多少种职位.
    select distinct job from emp_job;
    
    distinct后有多个字段的情况:
    select distinct job, name from emp_job;
    // select distinct * from emp_job; 不推荐
    
11. upper()大写函数
    将要转换大写的字段或值作为参数放入函数中.
    语法:
    upper(字段/值)
    案例1:
    select upper(name) name, upper(job) job from emp_job;
    案例2:
    select * from emp_job where upper(name) = upper('lucy');
    
12. lower()小写函数
    用法: 与大写函数一致,不同点在于是将数据转换成小写字母.
    
    练习:
    1. 查询工资大于等于5000的人员的信息.
    2. 查询工资小于1000的人员信息.
    3. 查询工资大于等于1000并且小于等于5000的人员信息
    4. 查询工资大于5000或者工资小于1000的人员信息.
    
    在使用where条件查询的时候,多个条件时可以使用and连接,前提是并且的关系下才可以使用.

13. and 关键字
    在where条件查询时的并且条件.

14. or 关键字
    在where条件查询时用于或关系的条件关联.
    
15. between...and...区间条件
    查询条件是一个闭合区间,相当于包括起始以及末尾.
    select * from emp_wanght
    where salary between 1000 and 5000;
    查询时,包括1000以及5000.
    查询2011年11月1日到2011年12月31日的员工信息.
    select * from emp_wanght
    where birthday between '01-11月-11' and '31-12月-11';

16. in列表关键字
    表示当前条件可满足的值的列表,多个值之间用逗号间隔.
    例题:
    1. 查询员工编号为1001,1003,1004的员工信息.
    使用or连接(正确)
    select * from emp_wanght
    where id = 1001 or id = 1003 or id = 1004;
    语法1:
    in(值列表);
    案例1:
    select * from emp_wanght
    where id in(1001, 1003, 1004);
    
    2. 查询员工编号不是1001,1003,1004的员工信息.
    select * from  emp_wanght
    where id != 1001 and id != 1003 and id != 1004;
    语法2:
    not in(直列表);表示不在列表中的数据.
    案例2:
    select * from emp_wanght
    where id not in(1001, 1003, 1004);
    
    练习:
    查询 职业是战士 法师 弓箭手的 人员信息.
    
17. 模糊匹配(like %)
    1) % 匹配0到多个字符,跟like一起使用.
    2) _ 表示1个字符.
    
    语法1:
    like '[%]内容[%]';
    语法2:
    like '_内容_';
    含义1:
    表示内容的前后都可以存在0~n个字符.
    案例1:
    1. 搜索职业中包含字符s的人员信息.
        select * from emp_wanght
        where job like '%s%';
    2. 查询职业中以字母s开头的人员信息
        select * from emp_wanght
        where job like 's%';
    3. 查询职业中第四个字符是s的人员信息
        select * from emp_wanght
        where job like '___s%';
    案例:
        查询职业中包含s并且,s后只有2个字符的信息.
        select * from emp_wanght
        where job like '%s__';
    4. 查询职业中以s_开头的数据(escape关键字)
        select * from emp_wanght
        where job like 's|_%' escape '|';
    含义:
    将关键字后面的字符定义成转意字符.

18. 判断是否为null值(is null)
    例题:
    查询表中bonus为null值的信息.
    select * from  emp_wanght where bonus is null;
    无论任何类型,在判断是否为null值的时候,使用的全都是is null;

19. 查询语句中的否定形式
    1) is not null             不为null值
    2) not between... and...   不在范围内
    3) not in(list)            不在列表中
    
20. Oracle中的函数
    1) 数字函数
        a) round(数字, 保留小数位数)
        用于设置保留小数点后小数位数.(四舍五入)
        例题:
        计算金额的四舍五入用salary * 0.12345678
        select ename,
            round(salary * 0.1234567) s1,
            round(salary * 0.1234567, 2) s2,
            salary * 0.1234567 s3
        from emp_wanght;
        在使用时,如果不写第二个参数,默认不保留小数
        
        b) trunc(数字, 保留小数位数)
        用于截取小数,函数不会进行四舍五入.而是直接截取.用法与round()函数一致.
        select ename,
            trunc(salary * 0.1234567) s1,
            trunc(salary * 0.1234567, 2) s2,
            salary * 0.1234567 s3
        from emp_wanght;
        
    2) 日期函数(sysdate)
        a) sysdate 用于显示当前系统日期.配合虚表dual使用.
        如果配合查询普通表,那么只要select语句能
        查询出多少条数据,日期就会显示多少次.
        b) dual虚表, 用于查询Oracle中的常量.
        
    3) 日期的相减(天数)
        计算当前系统日期与入职时间的差
        select ename, hirdate, (sysdate - hirdate) days from emp_wanght;
        配合round函数使用,默认的数据是小数.
        select ename, hirdate, round(sysdate - hirdate) days from emp_wanght;
        
    4) 相差月数(months_between())
        用于计算两个时间相差的月份数.返回结果依然是小数.
        计算当前系统日期与入职时间相差的月数
        select ename, hirdate, months_between(sysdate, hirdate) months
        from emp_wanght;
        也可以配合round函数使用
        select ename, hirdate, round(months_between(sysdate, hirdate)) months from emp_wanght;
        
    5) 添加月数(add_months(日期, 月数))
       select add_months(sysdate, 12) from dual;
       返回结果是日期
       
    6) 本月的最后一天(last_day())
       select last_day(sysdate) from dual;
       返回结果是日期

        
        
1. 转换函数
    a) 将日期转换成字符串(to_char())
    格式:
    to_char(日期, 格式字符串);
    案例:
    1. to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss')
    2. to_char(sysdate, 'year month dd day dy')
    
    b) 日期转换格式
    yyyy    四位数字的年份   例如: 2016
    year    全拼(英文)的年份 例如: twenty sixteen
    month   全拼(英文/中文)的月份 例如: May 或 5月
    mm      两位数字的月份 例如: 12
    mon     简拼的月份     例如: Oct 或者 10月
    dd      两位数字的日期 例如: 23
    day     全拼的星期   例如: Sunday 或 星期日
    dy      简拼的星期   例如: Sun 或 星期日
    am      上午/下午    例如: am/pm
    
    sqlplus中日期默认格式: dd-mon-RR
    RR 两位数字的年份是用于替换两位的YY
    两位的YY在取年份信息的时候,前两位是根据当前系统日期的年份确定的.
    两位的RR在取年份信息时,会针对当前系统日期做比对后再去读取数据.

    年份      YY       RR
    05       2005     2005
    85       2085     1985
    
    b) to_date() 将字符串按照指定的格式转换成日期
    格式:
    to_date('字符串', '格式')
    案例:
    to_date('1985-02-12', 'yyyy-mm-dd')
    向表中插入数据:
    insert into emp_wanght(empno, ename, job, hirdate)
    values(1011, '令狐冲', '刺客', to_date('2016-12-23', 'yyyy-mm-dd'));
    总结:
    to_char() 是将日期按照指定格式转换成字符串.
    to_date() 是将字符串按照指定格式转换成日期.

2. 其他函数
    a) coalesce()
    格式:
    coalesce(参数列表).
    含义:
    返回列表中第一个非null值的参数作为函数的值.
    案例:
    1) 如果bonus 不是null, 年终奖就是bonus
    2) 如果bonus 是null, 年终奖是 salary * 0.5
    3) 如果bonus和salary 都是null, 就发1000补助.
    语句:
    select ename, bonus, salary, coalesce(bonus, salary * 0.5, 1000) year_bonus
    from emp_wanght;
    
    b) case() 语句
    case语句是分支结构,相当于java中的switch...case..
    例题:
    1) 如果职位是战士(sol) , 加薪10%
    2) 如果职位是法师(mas) , 加薪5%
    3) 如果职位是弓箭手(arc), 加薪2%
    4) 其他职位不变.
    语句:
    select ename, job,salary,
        case job when '战士(sol)' then salary + salary * 0.1
             when '法师(mas)' then salary + salary * 0.05
             when '弓箭手(arc)' then salary + salary * 0.02
             else salary  --相当于default
        end new_salary   --别名一定要存在
    from emp_wanght;
    
    c) decode函数
    decode()函数式Oracle中等价于case...when的函数
    语法:
    decode(判断条件, 匹配1, 值1, 匹配2, 值2, 匹配3,值3,...)
    表达式的意思:
    当判断条件与列表中某一项匹配时,返回该项的值.
    例题:
    1) 如果职位是战士(sol) , 加薪10%
    2) 如果职位是法师(mas) , 加薪5%
    3) 如果职位是弓箭手(arc), 加薪2%
    4) 其他职位不变.
    语句:
    select ename, job, salary,
    decode(job,
        '战士(sol)', salary * 1.1,
        '法师(mas)', salary * 1.05,
        '弓箭手(arc)', salary * 1.02,
        salary
    ) new_salary
    from emp_wanght;
    
    d) 函数的嵌套
        在Oracle中函数式可以嵌套使用的,在嵌套的时候要区分开哪些函数可以套在一起使用.
        
3. Oracle中的排序(order by)
    根据某个或某些字段排序,默认排序是升序.
    当需要使用降序排序时,在字段后追加关键字desc.
    语法:
    书写在查询语句的最后面order by 字段1, 字段2...
    语句(升序):
    select * from emp_wanght order by salary;
    语句(降序):
    select * from emp_wanght order by salary desc;
    注意:
    null值在参与排序的时候,是最大值.
    案例:
    select * from emp_wanght order by bonus, salary;
    
4. 组函数
    组函数在使用时,不能单独与字段或普通函数一起使用.
    a)count()函数
        统计数据总数的函数.
    语法:
    count(字段名/*)
    语句:
        select count(mgr) from emp_wanght;
    注意:
        count()在统计数量的时候,null值不被记录在内
    
    b) 平均数函数(avg()函数)
        求一列中的平均数.使用在数字类型的列上.
    语法:
        avg(字段名)
    语句:
        select avg(salary) from emp_wanght;
    注意:
        avg()在统计数量的时候,null值不被记录在内
        
    c) 求和函数(sum()函数)
        求一列数字的总和,列的类型必须是数字类型.
    语法:
        sum(字段名)
    语句:
        select sum(salary) sum_salary, avg(salary) avg_salary from emp_wanght;
    
        select sum(nvl(salary, 0)) sum_salary, round(avg(nvl(salary, 0))) avg_salary
        from emp_wanght;
    注意:
        sum()在统计数量的时候,null值不被记录在内
        
    d) max()函数/min()函数
        最大值/最小值函数.求一列中最大/最小的数.
    语法:
        max/min(字段名)
    语句:
        selec max(hirdate), min(hirdate) from emp_wanght;
    注意:
        max()在统计数量的时候,null值不被记录在内
        min()在统计数量的时候,null值不被记录在内
        
    e) 总结:
        组函数的特点:
        1. 不能与其他字段或普通函数一起查询.
        2. 可以嵌套普通函数.
        3. 组函数不记录null值.
        4. 部分函数需要匹配数据类型.
    
5. 分组查询(group by)
        通过制定的列进行分组.
    语法:
        group by 字段名
    例题:
        分组查询每个部门下有多少员工信息
    语句:
        select deptNo, count(*) from emp_wanght
        where deptNo is not null
        group by deptNo order by deptNo;
    练习:
        1.分组查询每个部门的平均工资以及工资总和
        select deptNo, avg(salary) avg_salary, sum(salary) sum_salary, count(*) emp_num
        from emp_wanght
        where deptNo is not null and
        group by deptNo  -- 根据deptNo分组
        order by deptNo  -- 根据deptno升序排序
    注意:
        1.在where语句中不能使用分组函数.
        2.如果分组的字段不在查询之内,不会表只会不现实.

6. having子句
    配合group by使用的,为了给分组语句添加筛选条件
    案例:
        1.查询平均工资大于10000的部门
        select deptNo, avg(salary) avg_salary, sum(salary) sum_salary, count(*) emp_num
        from emp_wanght
        where deptNo is not null
        group by deptNo  
        having avg(salary) > 10000
        order by deptNo;
    练习:
        1. 查询平均工资小于9000的职位信息.
        select nvl(avg(salary), 0) avg_salary
        from emp_wanght
        group by job
        having nvl(avg(salary), 0) < 9000;
        
    思考:
    select from where group by having order by执行顺序
    1. from
    2. where
    3. group by
    4. having
    5. order by
    6. select
    
    
    
1.子查询
    查询语句的嵌套.
    作为子查询的语句不需要使用分号作为结尾.
    例题:
    查询工资最高的人是谁?
    1. 查询出最高的工资是多少
    select max(salary) max_salary from emp_wanght;
    2. 根据查询的最高工资,查询出对应的人员.
    select * from emp_wanght where salary = 15000;
    组合后:
    select * from  emp_wanght where salary = (
        select max(salary) from emp_wanght
    );
    案例:
    select * from (select ename from emp_wanght)
    where ename = '王重阳';
    
2. 知识点小结
    a) 查询语句的基本格式:
        select    字段1,字段2,...,字段n
        from      表名
        where     条件
        group by  列名(字段名)
        having    带有组函数的条件
        orde by   列名(字段名)
        
    b) 函数
        1) 组函数:
            max()/min()/avg()/sum()/count()
            注意: 组函数或略null值.
            组函数在于普通字段一起查询时,需要配合
            group by 进行.
        
        2) 单行函数
            a) 字符函数
                upper:
                将语句中英文字母转换为大写字母
                lower:
                将语句中英文字母转换为小写字母
                initcap:
                将语句中的英文单词首字母转换为大写
                语句:
                select initcap('tom') from dual;
                lenght:
                取长度
                语句:
                select length('tom') from dual;
                lpad:
                左填充(左补丁)
                语法结构:
                lpad(字段, 长度, 补充内容)
                例题:
                如果ename不足10个长度左填充*补充.
                语句:
                select lpad(ename, 10, '*') from emp_wanght;
                rpad:
                右填充(右补丁)
                语法结构:
                rpad(字段, 长度, 补充内容)
                语句:
                select rpad(ename, 10, '*') from emp_wanght;
                replace
                字母替换
                语法结构
                replace(字段, 旧字符, 新字符)
                语句:
                select replace(job, '(', '_') from emp_wanght;
                trim:
                去除前后的空格
                语句:
                select trim(ename) from emp_wanght;

            b) 数字函数
                round/trunc/mod
                取余函数(mod)
                语法结构:
                mod(字段名, 除数) 返回结果是余数
                案例:
                计算salary 对5000 取余
                select salary, mod(salary, 5000) from emp_wanght;
            
            c) 日期函数
                months_between  两个月份的差
                add_months      添加月份
                last_day        月份的最后一天.
                sysdate         当前系统日期.
            
            e) 转换函数
                to_char/to_date/to_number
                
                    to_char     to_number
                    ------->    --------->
                日期        字符          数字
                    <-------    <---------
                    to_date      to_char
                
                to_number的用法
                案例:
                将数字$123,456,789.67乘以10
                语句:
                select to_number('$123,456,789.67', '$999,999,999.99') * 10 from dual;

            f) 通用函数
                nvl/coalesce/case语句/decode
                注意: case语句不算做函数.
    
        3) 常用的函数
            a) 单行函数
                upper/round/to_char/to_date/nvl
            b) 组函数
                count/avg/sum/max/min
    
3. 子查询二(非关联子查询)
    a) 单行的比较运算符 > >= < <= = !=/<>
        例题:
        查询表中工资高于猪八戒的人.
        分布查询:
        1. 查询猪八戒的工资
            select salary from emp_wanght where ename = '猪八戒';
        2. 根据查询结果,查询出大于猪八戒工资的人.
            select ename, salary from emp_wanght where salary > 8000;
        3. 子查询语句:
            select ename, salary from emp_wanght where salary > (
                select salary from emp_wanght where ename = '猪八戒'
            );
        4. 子查询结果为多行(报错):
            ORA-01427: 单行子查询返回多个行
            1) 插入相同数据
            insert into emp_wanght values(1011,'猪八戒','战士(sol)',8000,300,1001,40,'10-1月 -12');
            2) 使用子查询语句
            select ename, salary from emp_wanght where salary > (
                select salary from emp_wanght where ename = '猪八戒'
            );
    
    b) All
        当子查询中返回的结果为多行时,使用All表示满足返回的所有结果.
        案例:
        查询表中工资高于猪八戒的人.
        语句:
        select ename, salary from emp_wanght where salary > ALL(
            select salary from emp_wanght where ename = '猪八戒'
        );
        
    c) Any
        子查询中结果的任何一个.
        案例:
        查询表中工资高于猪八戒的人.
        语句:
        select ename, salary from emp_wanght where salary > any(
            select salary from emp_wanght where ename = '猪八戒'
        );
        
    d) In
        案例:
        查找跟孙悟空是同一个部门人员信息.不包括孙悟空.
        分步查询:
            1. select deptno from emp_wanght where ename = '孙悟空';
            2. select ename, deptno from emp_wanght where deptno = 10 and ename <> '孙悟空';
        子查询语句:
            select ename, deptno from emp_wanght where deptno = (select deptno from emp_wanght where ename = '孙悟空') and ename <> '孙悟空';        
        插入数据:
            insert into emp_wanght values(1012,'孙悟空','战士(sol)',8000,300,1001,40,'10-1月 -12');
        多行状态下取值:
            select ename, deptno from emp_wanght where deptno in (select deptno from emp_wanght where ename = '孙悟空') and ename <> '孙悟空';
            
    e) 单行比较运算符与any、all、in
        返回一行的时候: >、 >=、 <、 <=、 <>
        返回多行的时候: > all > any <all <any in
        
    f) 子查询的结果是多列的情况.
        案例:
            每个部门最高工资的人员是谁?
        分布查询:
            1. select max(salary), deptno from emp_wanght where deptno is not null group by deptno;
            2. 根据最高工资和部门编号查询
            select ename, salary ,deptno from emp_wanght where salary = 8500 and deptno = 30;
        子查询语句:
            select ename, salary ,deptno from emp_wanght where (deptno, salary) in (select deptno, max(salary) from emp_wanght where deptno is not null group by deptno);
    
    e) 子查询语句出现在having中
        案例:
            查询哪个部门的人数比部门20的人数多
        分步查询:
            1. select count(deptno) from emp_wanght where deptno = 20;
            2. select deptno, count(deptno) from emp_wanght group by deptno having count(deptno) > 2;
        子查询语句:
            select deptno, count(deptno) from emp_wanght group by deptno having count(deptno) > (
                select count(deptno) from emp_wanght where deptno = 20
            ) order by deptno;
        练习:
        1. 哪个部门的平均工资比部门30的平均工资高.
            拆分:
            1. select avg(salary) from emp_wanght where deptno = 30;
            2. select deptno, avg(salary) from emp_wanght group by deptno having avg(salary) > 7166.66667
            组合:
            select deptno, avg(salary) from emp_wanght group by deptno having avg(salary) > (
                select avg(salary) from emp_wanght where deptno = 30
            );
        2. 列出员工姓名和职位,这员工的所在部门的平均工资大于 8000.
        拆分:
            1. select deptno from emp_wanght group by deptno having avg(salary) > 8000;
            2. select ename, job from emp_wanght where deptno in (10,20);
        组合:
            select ename, job from emp_wanght where deptno in (
            select deptno from emp_wanght group by deptno having avg(salary) > 8000
            );
        
        3. 哪些员工的工资比公司平均工资低.
            select ename, salary from emp_wanght where salary < (
                select avg(salary) from emp_wanght
            );
    
4. 子查询(关联子查询)    
    子查询中不再是独立的查询语句,而是需要依靠主查询传来的参数,这种方式称之为 关联子查询.
    
    例题:
    查询所有员工中,工资低于所在部门平均工资的信息.
    语句:
    select ename, deptno, salary from emp_wanght o where salary < (
        --查询的是所在部门的平均工资
        --所在部门是由主查询传递
        select avg(salary) from emp_wanght where deptno = o.deptno
    );
    
    
    
    
    1. 关联子查询
    案例:
        查询哪些人是其他人的经理
        
    Exists 关键字(否定形式: not exists)
        判断子查询返回值.有返回值为true,反之为false
    语句:
        select ename, empno from emp_wanght o where exists (
        select 1 from emp_wanght where o.empno = mgr
        );
        
    案例:
        查询哪些人不是其他人的经理
    语句:
    select ename, empno from emp_wanght o where not exists (
        select 1 from emp_wanght where o.empno = mgr
    );
    
    例题:
    查询没有员工的部门(dept_wanght)信息.
    分析:
    1. 查询的结果集来自于dept表.确认外层查询是dept
    2. 判断emp表的dept字段是否包含所有dept表的deptno
    语句:
    select * from dept_wanght d where not exists (
        select 'abc' from emp_wanght e where e.deptno = d.deptno
    );
    
2. 集合操作
    数据库中的查询结果叫做结果集,针对结果集的操作叫做集合操作.
    集合A : {1,2,3,4,5}
    集合B : {1,3,5,7,9}
    A与B的合集: {1,2,3,4,5,7,9} // 去重 排序
    A与B的交集: {1, 3, 5}
    A与B的差集: A-B {2, 4}

    1) 两个结果集必须结构相同
        当列的个数、顺序、数据类型一致时,我们称这两个结果集结构相同
        只有结构相同的两个结果集才能做合集操作。
        
    2) 合集 union 和 union all
        a) union 去掉重复记录,union all 不去重
        b) union 排序, union all 不排序
        案例:
        查询部门编号为10或工资大于6000的人员信息
        语句:
            select ename, deptno, salary from emp_wanght where deptno = 10
            union all -- 不去重,不排序
            select ename, deptno, salary from emp_wanght where salary > 6000;
    
    3) 交集 intersect
        案例:
        查询部门编号为10并且工资大于6000的人员信息
        语句:
            select ename, deptno, salary from emp_wanght where deptno = 10
            intersect
            select ename, deptno, salary from emp_wanght where salary > 6000;
            
    4) 差集 minus (两个结果集做减法)
        案例:
        查询部门为10但工资不大于6000的集合
        语句:
            select ename, deptno, salary from emp_wanght where deptno = 10
            minus
            select ename, deptno, salary from emp_wanght where salary > 6000;
        
3. 表间的关联查询
    1) 多表的关系:
        a) emp表中的所在部门(deptno)是参照dept表中的部门编号(deptno)
        b)dept表示主表(父表), emp表示从表(子表)
        c)emp表中的所在部门(deptno)称之为 外键.
        d)dept表中的部门编号(deptno)称之为 主键.
        
    2) 单表的内部关系:
        a) emp表中的部门经理(mgr)是参照emp表中的员工编号(empno)
        b) emp表即是主表(父表)又是从表(子表)
        c) 员工编号(empno)是主键
        d) 部门经理(mgr)是外键.
    
    3) 主键(PK)和外键(FK)
        a) 主键(Primary Key, 简称PK)
            1) 不可重复.
            2) 不能为null值.
            3) 主键是一条数据的唯一标识.
            
        b) 外键(Foreign Key, 简称FK)
            1) 外键的值是参照主键.
            2) 外键的值可以为null.
            3) 外键的值不能非null且主键中不存在的值.
        
    4) 内连接
        关键字:
            join ... on ...
        形式一:
            表1 join 表2 on 关联条件
        形式二:
            from 表1, 表2 where 关联条件
        案例:
            查询员工姓名及其所在部门名称.
        语句1:
            select ename, deptname from emp_wanght e join dept_wanght d on e.deptno = d.deptno;
        语句2:(没有使用join关键字)
            select ename, deptname from emp_wanght e,dept_wanght d where d.deptno = e.deptno;
        特点:
            如果在从表中没有找到主表的参照数据,则在结果集中不显示该条数据.
    
    5) 自连接(单表关联)    
        表中的某个字段是参照另一个字段的值.
        案例:
            查询员工姓名和对应领导的名字.
        语句:(内连接)
            select e1.ename, e2.ename as mgr_name from emp_wanght e1 join emp_wanght e2 on e1.mgr = e2.empno;
    
    6) 驱动表和匹配表
        
        表1 join 表2 on 条件
        a) 表1是驱动表, 表2是匹配表
        b) 等值连接方式时,驱动表和匹配表位置可以互换,不影响查询结果.
        
    7 外连接:
        a) 左外连接
            关键字:
                left outer join 表名 on 条件
            简写为:
                left join 表名 on 条件
                
        b) 右外连接
            关键字:
                right outer join 表名 on 条件
            简写为:
                right join 表名 on 条件
                
        c) 外连接的特性
            1) 如果驱动表在匹配表中找不到记录,则匹配一行空行.
            案例:
                查询员工姓名及其所在部门名称.
            语句:
                select deptname,ename from dept_wanght d left join emp_wanght e on d.deptno = e.deptno;
            
            2) 外连接的结果集 = 内连接的结果集 + 驱动的表在匹配表中匹配不上的记录和null值
            
            3) 外连接是驱动表中的数据一个都不能少.
            
            4) left outer join 是以左边的表为驱动表.
            5) right outer join 以右边的表为驱动表.
        
            练习:
            1.列出员工姓名和所在部门,把没有部门的员工也查询出来.
            以员工表(emp_wanght)为主表
            语句(left join):
            select ename, deptname from emp_wanght e left join dept_wanght d on e.deptno = d.deptno;
            语句(right join):
            select ename, deptname from dept_wanght d right join emp_wanght e on e.deptno = d.deptno;
            2.列出员工姓名和所在部门,把没有员工的部门也查询出来.
            以部门表(dept_wanght)为主表
            语句:(左连接)
            select ename, deptname from dept_wanght d left join emp_wanght e on e.deptno = d.deptno;
            语句:(右连接)
            select ename, deptname from emp_wanght e right join dept_wanght d on e.deptno = d.deptno;
            
        d) 全外连接
            关键字:
                full outer join
            特点:
                1)可以把两个表中的数据全部查询出来.
                2)查询的结果集 = 内连接的结果集 + 驱动表中找不到匹配表记录数据和null值+匹配表中找不到驱动表记录数据和null值.
                3) 驱动表和匹配表可以互换.
            案例:
                查询数据表中的员工姓名以及部门名称.
            语句:
                select ename, deptname from dept_wanght e full join emp_wanght d on d.deptno = e.deptno;
        
4. 数据表操作(DML)
    DML数据控制语句:
    
    a) 插入语句(insert)
        1) 写字段名
            向表中的指定字段插入数据.
        2) 不写字段名
            向表中的所有字段插入数据.
            
        建议使用写字段名的方式使用.
        
    b) 更新语句(update)
    
        语法结构:
            update 表名 set 列名 = 新的值,
                            列名 = 新的值,
                        ...
            where 条件
            
        案例:
            将表中没有部门的员工调整到后勤部的员工.
            工资涨500,奖金调整为:500
        语句:
            update emp_wanght set deptno = (
                select deptno from dept_wanght where deptname = '后勤部'
            ),
            salary  = salary + 500,
            bonus = 500
            where deptno is null;
            
    c) 删除语句(delete)
        
        语法结构:
            delete from 表名 where 条件;
        
        注意:
            1).如果语句中不含where条件,清空表中数据.
            2).需要使用commit提交或使用rollback回滚.
            3).drop table删除表结构以及表中的所有数
               据,truncate 删除表中的数据,结构保留.
               drop和truncate都是不可回退.delete只做
               删除数据,可以回退.
        案例:
            删除那个名为东方不败的生物.
        语句:
            delete from emp_copy where ename = '东方不败';
            
        1). 删除重复数据:
            insert into emp_job values('孙悟空', '战士(sol)');
            insert into emp_job values('孙悟空', '战士(sol)');
            insert into emp_job values('孙悟空', '战士(sol)');
            
            insert into emp_job values('猪八戒', '战士(sol)');
            insert into emp_job values('猪八戒', '战士(sol)');
            insert into emp_job values('猪八戒', '战士(sol)');
            
            insert into emp_job values('沙和尚', '辅助(mot)');
            insert into emp_job values('沙和尚', '辅助(mot)');
            insert into emp_job values('沙和尚', '辅助(mot)');
            
            方法一:
                a) 使用复制表方式配合distinct关键字
                    create table emp_job2 as
                    select distinct name, job from emp_job;
                b) 删除原表
                    drop table emp_job;
                c) 使用rename关键字 改名
                    语法结构:
                        rename 表名 to 新表名;
                    语句:
                        rename emp_job2 to emp_job;
            方法二:
                使用rowid 关键字
                rowid是Oracle提供的隐藏字段,可以看作
                是一条数据在数据库中的物理位置.实际
                上是Oracle提供的一个伪列.
                Oracle数据库独有的.
                语句:
                delete from emp_job where rowid not in (
                    select max(rowid) from emp_job group by name, job
                );
                
        2). rename关键字
            用于表重命名.
            语法结构:
            rename 旧表名 to 新表名
        
        3). rowid关键字
            Oracle提供的一个伪列,并且只有oracl中存在
            rowid在表中是唯一的,每一条数据对应一个,
            可以看作数据在数据库中的地址.
    
5. 复制表
    1).复制全表
        create table 表名
        as
        查询语句;
        
    2). 复制表结构
        create table emp_copy
        as
        select * from emp_wanght where 1<>1;
        
    3). 复制数据
        insert into 表名 (查询语句);
        查询语句的结果集必须与表结构一致.
        insert into emp_copy
        (select *  from emp_wanght where deptno = 10);
        
    4). rownum关键字
        rownum是oracle数据库提供的行代号.只在Oracle数据库存在.默认查询时不显示,是一个隐藏字段.
        
        分页:
        数据一共是12条,每5条1页.要求过去第2页数据.
        page    页数 = 2
        count   每页数量 = 5
        total   总页数 = 3
        语句:
        select rownum num, ename, empno from  emp_wanght where rownum <= 2 * 5;
        // 第三页的数据
        select rownum, num, ename, empno from (
            select rownum num, ename, empno from  emp_wanght where rownum <= 3 * 5
        ) where num > (3 - 1) * 5;
        



1. 约束条件(constraint)
    a) 主键约束
        每张表中,只能存在一个主键约束.
        关键字:
        primary key
        
        特性:
        1) 主键约束是唯一的(作为主键数据不能重复)
        2) 主键约束是非空的(作为主键数据不能为null值)
        
        特殊的主键:
        联合主键,两个字段绑定在一起作为主键约束.
        
        特点:
        两个字段连在一起时不能重复,单独其中一个可以
        与其他字段重复.
    
    b) 列级约束:
            约束直接添加在列上.
        语句:
        create table emp_wanght2(
            empno number primary key, --当前列为主键
            ename varchar2(20),
            job varchar2(20)
        );
        insert into emp_wanght2
            values(1001, '小明', '学生');
            
    c) 表级约束
            在建表时,约束是增加在列定义之后.
        语法结构:
            constraint 约束名 约束类型(列名)
            约束名:
                表名_列名_约束类型简称
        语句:
            create table emp_wanght2(
                empno number,
                ename varchar2(20),
                job varchar2(20),
                --约束语句
                constraint emp_wanght2_PK primary key(empno)
            );
            insert into emp_wanght2
                values(1001, '小明', '学生');
                
    d) 非空约束(not null 简称:NN)
        只能使用列级约束定义.并且非空约束没有默认名.
        语句:
            create table student_wanght(
                id number(4) primary key,
                name varchar2(20) not null,
                age number(3)
            );
            insert into student_wanght
            values(1001, '韩梅梅', 13);
            insert into student_wanght
            values(1002, null, 15);
        增加约束名:
            create table student_wanght(
                id number(4) primary key,
                name varchar2(20)constraint student_wanght_name_NN not null,
                age number(3)
            );
    
    e) 唯一约束(Unique 简称UK)
        表示被约束的列中的数据不可重复.
        
        1) 列级定义
            create table student_wanght(
                id number(4) primary key,
                name varchar2(20) not null,
                emali varchar2(30) not null unique,
                age number(3)
            );
            insert into student_wanght
                values(1001, '韩梅梅', 'hanmeimei@126.com',13);
            insert into student_wanght
                values(1002, '李雷', 'hanmeimei@126.com',15);
        
        2) 表级定义
            create table student_wanght(
                id number(4),
                name varchar2(20) not null,
                email varchar2(30),
                age number(3),
                -- 约束条件
                constraint student_wanght_id_pk primary key(id),
                constraint student_wanght_email_uk unique(email)
            );
        
    f) 检查约束(Check 简称 CK)
        约束字段的允许存放内容.
        
        1) 列级定义
            语句:
                create table student_wanght(
                    id number(4) primary key,
                    name varchar2(20) not null,
                    email varchar2(30) unique,
                    age number(3) check(age > 5),
                    gander varchar2(1) check(gander in('f','m'))
                );
                
                insert into student_wanght
                values(1001, '韩梅梅', 'hanmeimei@126', 14, 'f');
                insert into student_wanght
                values(1002, '李雷', null, 15, 'm');
                insert into student_wanght
                values(1003, '林涛', null, 15, 'm');
                
        2) 表级定义
            create table student_wanght(
                id number(4),
                name varchar2(20) not null,
                email varchar2(30),
                age number(3),
                gander varchar2(1),
                ---约束条件
                constraint student_wanght_id_pk primary key(id),
                constraint student_wanght_email_uk unique(email),
                constraint student_wanght_age_ck check(age > 5),
                constraint student_wanght_gander_ck check(gander in('f','F','m','M'))
            );
        
    g) 查看表中约束条件
        数据字典:
            user_constraints  --- 用户的所有约束.
            user_tables       --- 用户的所有表.
            user_objects      --- 用户的所有对象.
            
        查看约束:
            select constraint_name, constraint_type, table_name, owner
            from user_constraints
            where table_name = 'STUDENT_WANGHT';
        
        思考:
            为非空约束增加约束名后,查询约束中是否存在该约束?
    
2. 外键(Foreign key 简称FK)
    之前讲过的约束条件都是用来约束单表中的列,而外键
    约束是定义在两个表的两个字段(或者是一个表的两个
    字段上),用于保证相关两个字段的关系.
    特点:
        1.作为外键的列中的值,只能参照绑定的主键的值
          或者是null值.
        2.如果主键的值存在外键参照,那么在删除该数据
          时要先删除参照的外键,否则无法删除(除非使
          用关联删除).
    
    a) 外键约束
        语法结构:
            constraint 约束名 foreign key(外键列) references 主键表(列名)
            
        创建专业表(major_wanght):
            create table major_wanght(
                id number(2) primary key,
                name varchar2(20) not null
            );
        创建学生表(student_wanght):
            create table student_wanght(
                id number(4),
                name varchar2(20) not null,
                email varchar2(30) not null,
                age number(3),
                gander varchar2(1),
                major_id number(2),
                constraint student_wanght_id_pk primary key(id),
                constraint student_wanght_email_uk unique(email),
                constraint student_wanght_age_ck check(age > 5),
                constraint student_wanght_gander_ck check(gander in ('f','F','m','M')),
                constraint stu_maj_mid_id_fk foreign key(major_id) references major_wanght(id)
            );
            
            insert into student_wanght
                values(1001, '韩梅梅', 'hanmeimei@126', 14, 'f', 10);
            
            insert into student_wanght
                values(1002, '李雷', 'lilei@126.com', 15, 'm', 10);
            
            insert into student_wanght
                values(1003, '林涛', 'lintao@126.com', 15, 'm',10);
                
            insert into major_wanght
            values(10, '英语专业');

    b) 外键的数据删除
        默认情况是,先删除外键数据,再删除主键数据.
        可以通过设置级联删除,一次性清除主/外键数据.
        1) on delete set null
            表示删除主键时,外键数据自动设置为null值.
            先将外键表中的外键数据设置null值(update)
            再将对应的主键数据删除.
            
            删除原来的约束:
                alter table student_wanght drop constraint stu_maj_mid_id_fk;
            增加新约束:
                alter table student_wanght add constraint stu_wht_mid_id_fk foreign key(major_id) references major_wanght(id) on delete set null;
        
        2) on delete cascade 级联删除
            表示删除主键时, 外键一起删除.
            先删除外键表中的关联数据,再删除主表中的
            主键数据.
        
            删除原来的约束:
                alter table student_wanght drop constraint stu_wht_mid_id_fk;
            增加新约束:
                alter table student_wanght add constraint stu_wht_mid_id_fk foreign key(major_id) references major_wanght(id) on delete cascade;
        
3. 数据库中的其他对象
    1). 数据库中主要对象:
        a) 表 Table(掌握)
            表是数据库中存储数据的最基本单元,在关系
            型数据库中,表示一个二维结构,由行(Row)和
            列(Record)组成.
            
        b) 视图 View(掌握)
            视图也可以称之为虚表(虚幻的表),视图对应
            一条select语句,这条查询语句得到的结果集
            被赋予一个名字,就是视图的名字.此后可以当
            做表一样操作中个视图.
            
        c) 索引 Index(掌握)
            索引用于在数据库中快速查询的数据库对象,
            通过快速查询可以访问到数据.可以减少数据
            的I/O才操作.
            
        d) 序列 Sequence(掌握)
            序列是一种用来生成唯一数字的数据库对象,
            主要用于Oralce表中的主键自动增长的.序列
            中的数字是由Oracle自动处理.
            
        e) 存储过程 Procedure
            过程是一种PL/SQL存储程序单元,主要用于在
            数据库中完成特定的操作或者任务.如果在程
            序中经常执行某个操作,可以将值个操作建立
            成一个过程,用于建华客户的开发和维护.并且
            提高性能.
            
        f) 函数 Function
            PL/SQL中的函数用来执行复杂的计算,并返回
            计算结果.
            
        g) 包 Package
            包是一种比较特殊的PL/SQL程序,它并不是一
            个PL/SQL程序模块,而是用于将相关的存储过
            程和函数组织起来,组成PL/SQL存储程序模块.
            
        h) 触发器 Tigger
            PL/SQL中的触发器的结构类似存储过程,与过
            程不同的是触发器是在事件发生时运行.
            
    2). 视图 View
        a) 视图的使用和表相同
        b) 视图的好处: 简化查询,隐藏不必要的数据列.
        c) 视图不包含任何数据,是基表的投影.
        语法:
            create view 视图名 as 查询语句;
        案例:
            create view emp_view_wanght
            as
            select empno, ename, job, salary from emp_wanght;
        语法:
            create or replace view emp_view_wanght
            as
            select empno, ename, job, salary from emp_wanght where deptno = 10;
        
    3). 索引 Index
        inde:用来提高查询效率的机制
        语法结构:
            create index 索引名 on 表名(列名);
        特性:
            主键和唯一约束会自动创建索引.
        查看索引:
            user_indexes -- 数据字典(用户的全部索引)
        语句:
            select index_name from user_indexes where table_name = 'STUDENT_WANGHT';
        案例:
            默认使用索引进行查找,因为id是主键,默认存
            在一个索引.效率比查询全表快.
            select * from student_wanght where id = 1001;
            
            在没有索引时,是全表查询数据,效率较低.
            select * from student_wanght where name = '李雷';
        注意:
            在表中,如果经常使用一个非主键且没有唯一
            约束的字段作为查询条件时,可以主动为该字
            段增加所以以便提高查询效率.
        例如:
            为student_wanght表的name字段增加索引
        语句:
            create index student_wanght_name_index on student_wanght(name);
            
    4). 序列Sequence
        a). 序列的特性:
            1). 产生连续的不同的数字值用来作为表的
                主键.
            2). 序列是数据库中独立的对象.
            3). 表可以用序列产生的数字作为主键.
            4). 序列可以在多个表中使用,但是建议一个
                序列只对应一个表.
            5). 序列存在于Oracle以及DB2等数据库中,
                在mysql,sql server中不存在.
                
        b). 创建一个基本序列
            语法结构:
                create sequence 序列名.
            语句:
                create sequence test_seq_wanght;
            获取序列中的值:
                序列名.nextval
            案例:
                create table student_test
                as
                select id, name from student_wanght where 1<>1;
            注意:
                复制表的时候,约束不会被复制.
                
            插入语句:
            insert into student_test
            values(test_seq_wanght.nextval, 'name' || test_seq_wanght.nextval);
            
        c) 创建一个指定起始值的序列:
            语法结构:
                create sequence 序列名
                start with 起始值
                increment by 每次自增数.
            案例:
                create sequence student_seq
                start with 1000;
            插入数据:
                insert into student_test
                values(student_seq.nextval, 'name' || test_seq_wanght.nextval);

5. 删除数据库对象
    使用drop关键字进行删除操作.
    语法结构:
        drop 对象关键字 名称;

posted on 2021-01-20 13:02  渐行渐远的那些人  阅读(188)  评论(0编辑  收藏  举报