A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 zhangxuchang 于 2018-6-21 15:43 编辑

网上商城实战 & oracle数据库

Filter概述
  • 就是对从客户端发送到服务器的请求进行过滤

FilterConfig的配置
  • 获得初始化参数
  • 获得ServletContext
  • 获得过滤器的名称

过滤器链
  • FilterChain:多个过滤器构成链式结构,与web.xml中的配置顺序有关

生命周期
  • 在服务器启动的时候进行创建,服务器关闭的时候被销毁

过滤器的配置
  • <url-pattern>的配置
  • <url-pattern>所拦截的路径</url-pattern>
  • <servlet-name>的配置
  • <servlet-name>前后要保持一致</servlet-name>
  • <dispatcher>的配置
  • REQUEST :过滤请求
    FORWARD :可以过滤转发
    INCLUDE
    ERROR
增强一个类中的某个方法
  • 继承:需要能够控制这个类的构造
  • 装饰者模式:增强的类和被增强的类实现相同的接口,在增强类中获得被增强类的引用
    缺点:接口中的方法太多
  • 动态代理:被增强的类实现接口即可

JDK中动态代理
  • 使用Proxy对象

    • Object obj = Proxy.newProxyInstance(ClassLoader cl,Class[] interfaces, InvocationHandler ih);

  • 使用动态代理实现字符集编码过滤器部分代码

    • public void doFilter(ServletRequest request, ServletResponse response){
        final HttpServletRequest req = (HttpServletRequest) request;
        //增强req
        HttpServletRequest myReq = (HttpServletRequest)Proxy.newProxyInstance(myReq.getClass().getClassLoader,
        myReq.getClass().getInterfaces(),
          new InvocationHandler(){
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 判断执行的方法是否是getParameter:
                if("getParameter".equals(method.getName())){
                    // 调用的是getParameter:需要增强这个方法.
                    // 判断请求方式是GET还是POST:
                    String type = req.getMethod();
                    if("get".equalsIgnoreCase(type)){
                        String value = (String) method.invoke(req, args);
                        value = new String(value.getBytes("ISO-8859-1"),"UTF-8");
                        return value;
                    }else if("post".equalsIgnoreCase(type)){
                        req.setCharacterEncoding("UTF-8");
                    }
                }
                return method.invoke(req, args);
            }
           });
          chain.doFilter(myReq, response);
      }
      )
      });
      }
代理的企业应用:Spring的AOP
  • AOP的底层使用的就是代理机制:面向切面编程,提高了程序的扩展和维护效率

注解
  • 注解:给计算机看的一种语言符号,框架支持注解开发

JDK提供的注解
  • @Override:描述方法的重写
  • @SuppressWarnings:压制警告(黄线)
  • @Deprecated:标记过时
  • @Overload:描述方法的重载

自定义注解注解属性的类型:
  • 基本数据类型
  • 字符串类型 String
  • Class
  • 注解类型
  • 枚举类型
  • 以及以上类型的一维数组

如果属性名称为value,那么value可以省略Servlet3.0的文件上传功能概述
  • 支持注解开发
  • 提供异步请求
  • 支持文件上传

    • 需要运行在Tomcat7以上的服务器中
    • web.xml不是必须的

注解开发// 使用@WebServlet替换web.xml中配置的Servlet
@WebServlet(urlPatterns="/SerlvetDemo1",loadOnStartup=2)
// 使用@WebListener替换web.xml中监听器的配置
@WebListener
// 使用@WebFilter替换web.xml中的过滤器的配置
@WebFilter(urlPatterns="/*")

异步请求
// 使用多线程的方式,讲一次请求分成多个编程去处理
@WebServlet(urlPatterns="/ServletDemo2",asyncSupported=true)文件上传
  • 指的是将本地文件写到服务器上

    • 实质就是:IO流的读写


文件上传的要素:
  • 表单的提交方式必须是POST
  • 表单中必须有一个文件上传项:<input type="file>",而且文件上传必须有name属性和值.

    • <input type="file" name="upload"/>

  • 表单的enctype属性的值必须是multipart/form-data

文件上传的目录分离
  • 按用户分:一个用户创建一个或多个路径
  • 按时间分:按月,星期,天进行划分
  • 按个数分:一个路径中存在3000个文件
  • 按分离算法分:按照一定的算法进行划分


oracle数据库

1oracle特点:
(1)支持多用户、大事务量的事务处理
(2)数据安全性和完整性控制
(3)支持分布式数据处理
(4)可移植性
oracle体系:
数据库:可以看做oracle就只有一个大数据库实例:由一系列的后台进程和内存结构组成,一个数据库有多个实例
数据文件:数据库的物理存储单位
表空间:对物理数据库上相关数据文件(ORA 或者 DBF 文件)的逻辑映射
用户:用户是在表空间下建立的,用户登陆后只能看到和操作自己的表

2.创建表空间
        create tablespace waterboss           -----表空间名
        datafile 'c:\waterboss.dbf'                -----置物理文件名称
        size 100m                                        -----表空间的初始大小 (单位:m)
        autoextend on                                -----自动增长,如果存储量超过初始大小,则开始自动扩容
        next 10m                                                -----设置扩容的空间大小(每次扩大10m)

3.创建用户
        craete user wateruser                        -----创建用户名
        identified by itcast                                -----设置密码
        default tablespace waterboss         -----指定默认表空间

4.用户赋权
        grant dba to wateruser                         -----用户赋
5.表的创建、修改与删除
        (1)创建表
                语法:
                        create table 表名称(
                                字段名 类型(长度) 约束,
                                字段名 类型(长度) 约束,
                                字段名 类型(长度) 约束
                        )
                数据类型(特别强调:oracle与MySQL数据类型有差异)
                        字符型
                                char                固定长度类型,最多存储2000字节
                                varchar2        可变字符类型,最多存储4000字节
                        数值型
                                number               
                                number(5)                最大存得数为99999
                                number(5,2)                最大存的数为999.99
                        日期型
                                date:                精确到秒
                                timestamp:        精确到秒的小数点后9位
                        二进制(大数据类型)
                                clob:        存储字符,最大存4个G
                                blob:        存储二进制数据,最多存4个G
                                *真正开发时,存储图像一般不会将其存入数据库,而是存储于本地磁盘
        (2)修改表
                增加字段语法:
                        alter table 表名 add (字段1 类型(长度), 字段2 类型(长度))
                修改字段语法:
                        alter table 表名 modify(字段1 类型(长度), 字段2 类型(长度))
                修改字段名语法:
                        alter table 表名 rename column 原字段名 to 新字段名
                删除字段语法:
                        删除一个字段:
                                alter table 表名 drop column 列名
                        删除多个字段:
                                alter table 表名 drop (字段1,字段2...)
                        删除表:
                                drop tabel 表名

6.数据增删改:
        增:insert into 表名 (字段1,字段2...) values (值1,值2...)
        删:update 表名 set 字段 = 值 where 修改条件
        改:(1)delete from 表名 where 删除条件
            (2)truncate table 表名
                        注意:执行delete语句时一定要执行commit提交事物
                        原因:mysql有自动提交功能,oracle没有,需手动提交
                        truncate删除与delete删除的区别:
                                1.delete删除数据可以rollback
                                2.delete删除可能产生碎片,并且不释放空间
                                3.truncate是先摧毁表结构再重构表结构
7.jdbc连接oracle
        jdbc连接MySQL思路结构相同,不同点在于驱动和连接的配置
        jdbc连接MySQL和oracle配置对比:
                MySQL:
                        加载驱动:com.mysql.jdbc.Driver
                        连接字符串:jdbc:mysql://虚拟机的IP:端口号/数据库名
                oracle:
                        加载驱动:oracle.jdbc.driver.OracleDriver
                        连接字符串(瘦连接):jdbc:oracle:thin:@虚拟机的IP:orcl

8.oracle数据库导入导出        
        (1)整库
        导出:        导出数据库,执行命令会生成一个expdat.dmp备份文件
                exp 用户名/密码 full=y                                           ----添加full=y就是整库导出
                exp 用户名/密码 full=y  file=备份文件名                 ----添加file参数即可指定备份文件名称导出
                指定备份文件名称导出:        添加file参数即可,不指定file参数值则默认expdat.dmp备份文件
        导入:
                imp 用户名/密码 full=y                                 
                imp 用户名/密码 full=y file=备份文件名                ---指定备份文件导入,file默认值为expdat.dmp备份文件
        (2)按用户名
        导出
                exp 用户名/密码 owner=表名 file=备份文件名
        导入
                imp 用户名/密码 fromuser=表名 file=备份文件名
        (3)按表
        导出:
                exp 用户名/密码 file=备份文件名 tables=表名1,表名2
                *用 tables 参数指定需要导出的表,如果有多个表用逗号分割即可
        导入:
                imp 用户名/密码 file=备份文件名 tables=表名1,表名2

9.oracle语句查询
        聚合统计:        ORACLE的聚合统计是通过分组函数来实现的,与MYSQL一致
                (1)聚合函数:
                        求和: sum()
                                select sum(字段) from 表名 where 条件
                        求平均:        avg()
                                select avg(字段) from 表名 where 条件
                        求最大:        max()
                                select max(字段) from 表名 where 条件
                        求最小:        min()
                                select min(字段) from 表名 where 条件
                        统计记录个数:        count()
                                select count(*) from 表名 where 条件
                        分组聚合:        group by
                                select 字段1 from 表名 group by 字段2    ----按字段2分组查询表中的字段1
                        分组后的条件查询:        having
                                select 字段1 from 表名 group by 字段2 having 条件  
                                * group by  后面不能使用where条件查询 并且having只能用于group by后面的条件
                (2)连接查询:
                        内连接:        select * 字段 from 表1,表2,表三 where 关联条件(多个关联条件使用and连接)
                        左外连接:        SQL1999标准语法: select 字段 from 表1 left join  表2 on 关联条件
                                                oracle特有语法: select 字段 from 表1, 表2 where 表1关联字段(+) = 表2关联字段
                                                * 这里意为表2为左表,特点:想要将谁用作左表则在另一个表的关联字段后面加上'(+)'即可作为实现表的左连接
                        右外链接:        道理和左外相同,不同点在于表的位置不同,这里记住左外即可,如果想使用右外,将两个表调换位置即可
分页查询:
                简单分页:
                        查询前十条:select rownum,t.* from T_ACCOUNT t where rownum<=10
                        查询第11条到第20条的记录:select * from (select rownum r,t.* from T_ACCOUNT t where rownum<=20) where r>10
                注意:rownum是在查询语句扫描每条记录时产生的,所以不能使用“大于”符号,只能使用“小于”或“小于等于” ,只用“等于”也不行
                基于排序的分页:
                        排序查询前十条:select * from (select rownum r,t.* from T_ACCOUNT t where rownum<=20 order by usenum desc) where r>10
                        排序查询第11条到第20条:select * from (select rownum r,t.* from (select * from T_ACCOUNT order by usenum desc) t where rownum<=20 ) where r>10
                注意:ROWNUM 伪列的产生是在表记录扫描是产生的,而排序是后进行的,排序时R已经产生了,所以排序后R是乱的因此需要先使用子句查询排列在使用rownum排序

10.单行函数:
        常用函数:
                dual:伪表
                字符函数:
                        (1)求字符长度: leng()
                                select length('ABCD') from dual;             ---结果显示:4
                        (2)求字符串的子串: substr()
                                select substr('ABCD',2,2) from dual;    ---结果显示:BC
                        (3)字符串拼接:        concat()
                                select concat('ABC','D') from dual;         ---结果显示:ABCD
                                select 'ABC'||'D' from dual;                        ---结果显示:ABCD
                数值函数:
                        (1)四舍五入函数:        round()
                                select round(100.567) from dual               ---结果显示:101
                                select round(100.567,2) from dual                ---结果显示:100.57
                        (2)截取函数        trunc()
                                select trunc(100.567) from dual              ---结果显示:100
                                select trunc(100.567,2) from dual                ---结果显示:100.56
                        (3)取模        mod()
                                select mod(10,3) from dual                        ---结果显示:1
                日期函数:
                        (1)加月函数:        add_months()
                                select add_months(sysdate,2) from dual
                        (2)求所在月最后一天函数:        last_day()
                                select last_day(sysdate) from dual
                        (3)日期截取:        trunc()
                                select TRUNC(sysdate) from dual                        
                                select TRUNC(sysdate,'yyyy') from dual                        ----截取到年,月和日都为1
                                select TRUNC(sysdate,'mm') from dual                        ----截取到月,日为1
                转换函数:
                        (1)数字转字符串: to_char()
                                select TO_CHAR(1024) from dual                                                ----'1024'
                        (2)日期转字符串:        to_char()
                                select TO_CHAR(sysdate,'yyyy-mm-dd') from dual                 ----'2018-6-15'
                        (3)字符转日期:        to_char()
                                select TO_DATE('2018-6-15','yyyy-mm-dd') from dual  ----2018-6-15
                        (4)字符串转数字:        to_number()
                                select to_number('100') from dual
                其他函数:
                        (1)空值函数:        nvl()
                                用法:nvl(检测的值,如果为null的值)
                                select NVL(NULL,0) from dual
                        (2)空值函数:        nvl2()
                                用法:nvl2(检测的值,如果不为null的值,如果为null的值);
                                select PRICE,MINNUM,NVL2(MAXNUM,to_char(MAXNUM) , '不限') from T_PRICETABLE where OWNERTYPEID=1
                        (3)条件取值:        decode()
                                语法:        decode(条件,值 1,翻译值 1,值 2,翻译值 2,...值 n,翻译值 n,缺省值)
                                方式一:        select name,decode( ownertypeid,1,'居民',2,'行政事业单位 ',3,'商业') as 类型 from T_OWNERS
                                方式二:        select name ,(case ownertypeid when 1 then '居民' when 2 then '行政事业单位' when 3 then '商业' else '其它' end ) from T_OWNERS
                                方式三:        select name,(case when ownertypeid= 1 then '居民' when ownertypeid= 2 then '行政事业' when ownertypeid= 3 then '商业' end ) from T_OWNERS

11.集合运算
        集合运算,集合运算就是将两个或者多个结果集组合成为一个结果集。集合运算包括:
                union all(并集),返回各个查询的所有记录,包括重复记录。
                union(并集),返回各个查询的所有记录,不包括重复记录。
                intersect(交集),返回两个查询共有的记录。
                minus(差集),返回第一个查询检索出的记录减去第二个查询检索出的记录之后剩余的记录.

12.sql优化
        1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

        2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
                select id from t where num is null
                最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库.
                备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用NULL。
                不要以为 NULL 不需要空间,比如:char(100) 型,在字段建立时,空间就固定了, 不管是否插入值(NULL也包含在内),都是占用 100个字符的空间的,如果是varchar这样的变长字段, null 不占用空间。
                可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
                select id from t where num = 0

        3.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。

        4.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描,如:
                select id from t where num=10 or Name = 'admin'
                可以这样查询:
                select id from t where num = 10
                union all
                select id from t where Name = 'admin'

        5.in 和 not in 也要慎用,否则会导致全表扫描,如:
                select id from t where num in(1,2,3)
                对于连续的数值,能用 between 就不要用 in 了:
                select id from t where num between 1 and 3
                很多时候用 exists 代替 in 是一个好的选择:
                select num from a where num in(select num from b)
                用下面的语句替换:
                select num from a where exists(select 1 from b where num=a.num)

        6.下面的查询也将导致全表扫描:
                select id from t where name like ‘%abc%’
                若要提高效率,可以考虑全文检索。

        7.Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。

        8.对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差。

        9.select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。

        10.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。

        11.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

        12.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

        13.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

        14.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。

        15.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时 间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

        16.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

        17.尽量避免大事务操作,提高系统并发能力。

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马