SSM框架学习笔记

SSM框架学习笔记
目录
一、环境变量 3
二、maven项目 18
三、SSM框架介绍 28
四、创建SSM项目 31
五、SSM配置文件 45
六、运行SSM项目 53
七、mybatis反向工程 61
八、DAO调试与测试 67
九、业务逻辑层与测试 73
十、控制器层编写与前端整合 78
十一、显示所有部门信息与代理 82
十二、实现带参查询(按多条件组合模糊查询)与缓存 103
十三、实现部门信息增加 114
十五、实现部门信息批量删除 133
十六、日期转换器 136
十七、控制器使用实体对象接收数据 138
十八、HTTP状态异常和全局异常处理 138
十九、登录与Session 143
二十、DRUID配置 148
二十一、AOP 151
二十二、拦截器 154
二十三、restful 159
二十四、作业-单文件和多文件上传 164

一、环境变量
1、JDK环境配置:
JDK版本至少1.8(主流)部分软件需求JDK11
保证64位操作系统基本上是64位
32位JDK,新的开发工具已不支持
下载并安装JDK:
jdk-8u66-windows-x64.exe
确认位置:

配置环境变量:
新建JAVA_HOME是一个变量名称,并没有生效,要想生效,必须使用path

配置Path

验证:

但是,需要强调linux下,还需要配置JRE_HOME,windows可以省略,但必须是安装版本
新建CLASSPATH

2、配置maven:
下载并解压maven

新建MAVEN_HOME

配置Path

验证:

修改maven的配置文件settings.xml

设置本地仓库

设置镜像:默认是从国外站点下载,速度太慢,换国内源,推荐阿里云
阿里云


nexus-aliyun
central
Nexus aliyun
http://maven.aliyun.com/nexus/content/groups/public


华为

huaweicloud
*
huaweicloud
https://mirrors.huaweicloud.com/repository/maven/

3、开发工具:
eclipse免费的,主要通过插件形式提供更多支持,需要配置
idea社区版本是免费的,足够用的,集成度高,无需配置,代码编写高效
下载并解压eclipse:
https://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/2020-06/R/eclipse-jee-2020-06-R-win32-x86_64.zip

配置eclipse:
配置工作区默认存储位置

配置首选项

设置工作区编码:

确认JDK

设置Java代码提示功能

配置maven

配置tomcat:
下载并解压tomcat
https://tomcat.apache.org/download-80.cgi

eclipse中配置tomcat

二、maven项目
1、maven介绍:
Apache Maven,是一个软件(特别是Java软件)项目管理及自动构建工具,由Apache软件基金会所提供。
基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。
Maven也可被用于构建和管理各种项目,例如C#,Ruby,Scala和其他语言编写的项目。Maven曾是Jakarta项目的子项目,现为由Apache软件基金会主持的独立Apache项目。
Maven项目使用项目对象模型(Project Object Model,POM)来配置。
项目对象模型存储在名为 pom.xml 的文件中。
2、maven常用命令:

  1. 创建Maven的普通java项目:
    mvn archetype:create
    -DgroupId=packageName
    -DartifactId=projectName
  2. 创建Maven的Web项目:
    mvn archetype:create
    -DgroupId=packageName
    -DartifactId=webappName
    -DarchetypeArtifactId=maven-archetype-webapp
  3. 编译源代码: mvn compile
  4. 编译测试代码:mvn test-compile
  5. 运行测试:mvn test
  6. 产生site:mvn site
  7. 打包:mvn package
  8. 在本地Repository中安装jar:mvn install
  9. 清除产生的项目:mvn clean
  10. 生成eclipse项目:mvn eclipse:eclipse
  11. 生成idea项目:mvn idea:idea
  12. 组合使用goal命令,如只打包不测试:mvn -Dtest package
  13. 编译测试的内容:mvn test-compile
  14. 只打jar包: mvn jar:jar
  15. 只测试而不编译,也不测试编译:mvn test -skipping compile -skipping test-compile
    ( -skipping 的灵活运用,当然也可以用于其他组合命令)
  16. 清除eclipse的一些系统设置:mvn eclipse:clean

3、创建项目

通过配置获取原型:https://mirrors.huaweicloud.com/repository/maven/

选择原型:

理解pom.xml

设置对应的JDK版本

添加资源路径

项目结构:

三、SSM框架介绍
使用官方地址学习:
https://docs.spring.io/spring/docs/4.3.26.RELEASE/spring-framework-reference/htmlsingle/
基础:
后端:Java SE、Java Web
前端:HTML、CSS、JavaScript/jQuery
数据库:MySQL
框架:
SSH重量级框架Spring、Structs、Hibernate
部分院校还在继续使用国内IT行业中很少使用
IT行业趋势:
SSH:大量代码 + 少量配置SSM:减少代码 + 大量配置SpringBoot快速开发:保持代码 + 使用约定/习惯简化配置SpringCloud微服务:分布式开发,大厂都有自己的整套分布式框架方案框架融合大数据:基于大数据的分析(离线分析和实时分析),如淘宝和京东:基于分布式框架(商品展示+商品详情+购物车+支付+发货)+ 基于大数据(商品动作分析来推荐商品:协同过滤算法ItemCF/UserCF) + 基于大数据(历史足迹:曾经浏览过的商品记录)…………+ 人工智能(人工智能客服:文字 + 语音) + 5G时代
1、SSM框架:
SSM框架组成:
Spring + SpringMVC + MyBatis
Spring Framework:
IoC控制反转
传统方案:A需要B,在A中直接实例化B对象高内聚,低耦合:耦合度太高
IoC方案:A需要B,在A中通过C返回B对象解耦Spring框架:集成化,负责管理对象的实例化、对象的组装、对象的生命周期管理等等
DI依赖注入
属性注入
构造器注入
接口注入:放弃
AOP面向切面编程
面向过程
面向对象
用人类的思维(面向对象)来解决实现问题
从客观到抽象(OOA/OOD/OOAD:UML)
对象是客观存在人、事、物等
类是具有相同特征和行为的对象集合
例子:小时候妈妈教我们识字(字、拼音、卡片、图形、视频、动物园狮子)
从抽象到具体(OOP:Java/C#)
类是模板、泛化
对象是类的具体化、实例化
例子:长大了我们认识世界(狮子非洲的狮子、美洲的狮子……)
面向接口
依赖于抽象,而不依赖于具体实现负责定义,不管实现抽象类/接口
接口:关注行为因为整个系统我们在需求分析时,只关注行为
行为优先方便团队协作开发:调用者仅知道有哪些行为即可,不关注行为如何实现
宁可增加N个接口,不能修改1个接口
面向组件
业务规模增大组件化:模块化
搭积木的软件研发过程
面向切面
将业务的纵向划分模块进一步细分,横向切分相同功能的模块例如日志模块
资源管理
数据绑定
类型转换
……
SpringMVC

与Spring框架无缝集成

Mybatis:
官网地址:https://mybatis.org/mybatis-3/zh/index.html
JDBC的封装,核心sqlSessionFactory
通过配置文件与实体的Mapper文件关联
通过编写SQL语句实现灵活的数据操作大厂普通使用:统一笔试:考察3题SQL
2、SSM框架的优缺点:
优点:
Spring框架核心IoC、DI、AOP等使得代码复用,可维护性在幅度提升,尤其是AOP面向切面编程,进一步提高了生产力
SpringMVC框架是基于方法拦截,控制器独享request/response数据,采用Servlet入口,与Spring框架无缝对接,而且对于开发而言,SpringMVC更加轻量和低入门
Mybatis框架可以由开发者自由书写SQL语句,可以通过SQL语句进行调优,尤其是针对业务场景复杂的情况下,更加灵活和方便,尤其是连接查询
缺点:
大量配置文件,造成项目后期维护困难,降低了开发效率
Mybatis需要开发者掌握SQL技能,对不熟悉数据库的开发者不太友好,但是上手快
3、需要掌握哪个框架:
如果熟悉SSM,对于SpringBootg理解才能彻底
部分技能在SpringBoot中虽然名称相同,但是是重新实现的版本

四、创建SSM项目
1、N层架构(三层架构MVC N层架构):物理结构或逻辑结构

2、创建SSM项目:
1)创建maven项目

2)创建首页文件index.html

3)修改pom.xml文件
根据需求,确定模块,确定依赖https://mvnrepository.com/


4.0.0

com.neuedu
myoffice

0.0.1-SNAPSHOT

war

myoffice Maven Webapp

http://www.example.com


1.8
1.3
4.12
4.2.3.RELEASE
3.3.0
3.0.9.RELEASE
2.1.1





org.hamcrest
hamcrest-core
o r g . h a m c r e s t . v e r s i o n < / v e r s i o n > < s c o p e > t e s t < / s c o p e > < / d e p e n d e n c y > < ! − − 测 试 依 赖 − − > < d e p e n d e n c y > < g r o u p I d > j u n i t < / g r o u p I d > < a r t i f a c t I d > j u n i t < / a r t i f a c t I d > < v e r s i o n > {org.hamcrest.version} test junit junit org.hamcrest.version</version><scope>test</scope></dependency><!><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>{org.junit.version}
test



org.springframework
spring-context
o r g . s p r i n g f r a m e w o r k . v e r s i o n < / v e r s i o n > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > o r g . s p r i n g f r a m e w o r k < / g r o u p I d > < a r t i f a c t I d > s p r i n g − c o n t e x t − s u p p o r t < / a r t i f a c t I d > < v e r s i o n > {org.springframework.version} org.springframework spring-context-support org.springframework.version</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>springcontextsupport</artifactId><version>{org.springframework.version}


org.springframework
spring-aspects
o r g . s p r i n g f r a m e w o r k . v e r s i o n < / v e r s i o n > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > o r g . s p r i n g f r a m e w o r k < / g r o u p I d > < a r t i f a c t I d > s p r i n g − w e b m v c < / a r t i f a c t I d > < v e r s i o n > {org.springframework.version} org.springframework spring-webmvc org.springframework.version</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>springwebmvc</artifactId><version>{org.springframework.version}


org.springframework
spring-tx
o r g . s p r i n g f r a m e w o r k . v e r s i o n < / v e r s i o n > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > o r g . s p r i n g f r a m e w o r k < / g r o u p I d > < a r t i f a c t I d > s p r i n g − j d b c < / a r t i f a c t I d > < v e r s i o n > {org.springframework.version} org.springframework spring-jdbc org.springframework.version</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>springjdbc</artifactId><version>{org.springframework.version}


org.springframework
spring-test
o r g . s p r i n g f r a m e w o r k . v e r s i o n < / v e r s i o n > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > o r g . s p r i n g f r a m e w o r k < / g r o u p I d > < a r t i f a c t I d > s p r i n g − m o c k < / a r t i f a c t I d > < v e r s i o n > 2.0.8 < / v e r s i o n > < / d e p e n d e n c y > < ! − − s e r v l e t − − > < d e p e n d e n c y > < g r o u p I d > j a v a x . s e r v l e t < / g r o u p I d > < a r t i f a c t I d > j a v a x . s e r v l e t − a p i < / a r t i f a c t I d > < v e r s i o n > 3.1.0 < / v e r s i o n > < / d e p e n d e n c y > < ! − − m y b a t i s − − > < d e p e n d e n c y > < g r o u p I d > o r g . m y b a t i s < / g r o u p I d > < a r t i f a c t I d > m y b a t i s < / a r t i f a c t I d > < v e r s i o n > {org.springframework.version} org.springframework spring-mock 2.0.8 javax.servlet javax.servlet-api 3.1.0 org.mybatis mybatis org.springframework.version</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>springmock</artifactId><version>2.0.8</version></dependency><!servlet><dependency><groupId>javax.servlet</groupId><artifactId>javax.servletapi</artifactId><version>3.1.0</version></dependency><!mybatis><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>{org.mybatis.version}


org.mybatis
mybatis-spring
1.2.3



mysql
mysql-connector-java
5.1.37



commons-logging
commons-logging
1.2


commons-collections
commons-collections
3.2.2


commons-dbcp
commons-dbcp
1.4


commons-pool
commons-pool
1.6


commons-io
commons-io
2.4


org.apache.commons
commons-lang3
3.3.2



commons-fileupload
commons-fileupload
1.3.1


commons-codec
commons-codec
1.10


commons-jxpath
commons-jxpath
1.3



log4j
log4j
1.2.17


org.slf4j
log4j-over-slf4j
1.7.13


org.slf4j
jcl-over-slf4j
1.7.13


org.slf4j
jul-to-slf4j
1.7.13



com.alibaba
druid
1.1.2



org.aspectj
aspectjweaver
1.8.7



javax.inject
javax.inject
1



org.slf4j
slf4j-api
1.7.25


org.thymeleaf
thymeleaf
t h y m e l e a f . v e r s i o n < / v e r s i o n > < / d e p e n d e n c y > < d e p e n d e n c y > < g r o u p I d > o r g . t h y m e l e a f < / g r o u p I d > < a r t i f a c t I d > t h y m e l e a f − s p r i n g 4 < / a r t i f a c t I d > < v e r s i o n > {thymeleaf.version} org.thymeleaf thymeleaf-spring4 thymeleaf.version</version></dependency><dependency><groupId>org.thymeleaf</groupId><artifactId>thymeleafspring4</artifactId><version>{thymeleaf.version}



com.alibaba
fastjson
1.2.35



javax.validation
validation-api
1.1.0.Final



javax.activation
activation
1.1.1



com.fasterxml.jackson.core
jackson-core
2.7.3


com.fasterxml.jackson.core
jackson-databind
2.7.3




myoffice



maven-compiler-plugin

j a v a − v e r s i o n < / s o u r c e > < t a r g e t > {java-version} javaversion</source><target>{java-version}
utf-8




maven-surefire-plugin


**/*Tests.java






4)修改项目属性:
修改JDK版本
增加src/main/resources

5)修改Dynamic Web Module是无法修改,换一种思路:

6)分层设计:

3、解决maven项目中的问题:
方案1:

方案2:

提醒:
通常方案2就可以了
不行,就是先方案1,再方案2
4、友情提醒:

五、SSM配置文件
1、配置web.xml:web application配置



myoffice
use ssm framework created



	org.springframework.web.context.ContextLoaderListener
	




	CharacterEncodingFilter
	org.springframework.web.filter.CharacterEncodingFilter
	
	
		encoding
		UTF-8
	
	
		forceEncoding
		true
	


	CharacterEncodingFilter
	/*




	contextConfigLocation
	classpath:applicationContext.xml




	dispatcher
	org.springframework.web.servlet.DispatcherServlet
	
	
		contextConfigLocation
		/WEB-INF/dispatcher-servlet.xml
	
	1


	dispatcher
	/*




	default
	/robots.txt
	/sitemap.xml




	60





2、配置applicationContext.xml:Spring框架配置 + Mybatis配置
1)数据源文件配置jdbc.properties

驱动:8.0及以上无需提供,低版本mysql存在访问异常,尤其是在spring boot框架中

jdbc.driver=com.mysql.jdbc.Driver

8.0专用

#jdbc.driver=com.mysql.cj.jdbc.Driver

连接字符串

jdbc:mysql://服务器名或IP地址:端口号/数据库名?参数列表

jdbc.url=jdbc:mysql://localhost:3306/myoffice?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useOldAliasMetadataBehavior=true&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8

用户名

jdbc.username=root

密码

jdbc.password=123456

2)配置mybatis-config.xml

3)完整的spring配置文件applicationContext.xml


	
	
	


	
	




	




3、配置dispatcher-servlet.xml:SpringMVC的配置,注解式编程(减少配置)提高开发效率





	
	
	
	


	


	
	












4、更新maven项目 mavenupdate project projectclean 5、项目整体结构:

六、运行SSM项目
1、准备首页:

2、编写控制器:SpringMVC中DispatcherServlet拦截所有用户请求,并派发任务

3、运行项目:

运行效果:

4、返回JSON数据:

运行效果:

5、常见错误:
密码错误:

数据库不存在:

端口被占用:
显示port use

8.0mysql
pom.xml


mysql
mysql-connector-java
8.0.21

jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
6、修改控制器,返回JSON数据:

运行效果:

格式化效果:

七、mybatis反向工程
1、使用工具反向生成mybatis代码:也可以自己编写,代码难度不高
1)解压:

2)修改generatorConfig.xml
连接指定的数据库

实体层的包名

xml文件所在的包名:就是路径

数据访问层的包名

反向生成时所用的表和对应的实体类名

3)运行反向工程:

2、将反向工程生成的代码拷贝至项目对应的位置:

3、调整实体类Department:

4、调整DAO接口DepartmentMapper:

5、调整xml文件:
编写SQL语句
暂时不用
阅读:
resultMap
sql
select
insert
update
delete
添加一个新的方法:查询所有部门信息
接口中:

xml文件中:

八、DAO调试与测试
1、软件测试:software testing,描述一种用来促进鉴定软件的正确性、完整性、安全性和质量的过程。
从测试设计方法
黑盒测试根据用户需求完成测试,通常是测试人员完成
白盒测试根据内部结构完成测试,通常是程序员负责完成
从测试是手动还是自动
手动测试
自动化测试自动化测试框架(与python结合特别多)、测试开发工程师编写的自动化测试框架
从测试目的
单元测试验证最低的功能程序的正确性
功能测试
集成测试
场景测试
系统测试
Alpha测试
Beta测试
非功能测试
压力测试ab
负载测试ab
性能测试
2、测试用例:

3、SSM框架中数据访问层单元测试:
1)创建单元测试:

2)通过注解配置保证SSM框架测试:保证配置能够正确加载

3)编写测试用例:

4)运行测试:

运行效果:

再增加一个测试用例

运行效果

5、新增部门、修改部门、删除部门测试用例:

运行效果:

九、业务逻辑层与测试
1、业务逻辑层:总代码量占比比较高
根据数据库中表的约束产生的业务逻辑
根据需求分析而产生的业务逻辑
简单说:数据需要验证
前端页面需要验证:基于javascript的验证,使用正则表达式验证、表达式判断……
业务逻辑层需要验证:尽量使用第3方(apache/google)类库验证、代码判断、表达式验证、正则表达式……(疯狂行为:将整形转换为字符串,再使用正则表达式判断)
数据库需要约束验证:主键、惟一、检查、外键、非空、触发器、存储过程

2、编码完成业务逻辑层:
1)编写业务逻辑接口

2)编写业务逻辑接口实现类

3、编写单元测试,测试业务逻辑层:
1)创建单元测试

2)编写测试用例

运行效果:

后续还会调整数据访问层和业务逻辑层

十、控制器层编写与前端整合
1、控制器:项目启动时,会自动建立用户请求与方法的映射关系
2、编码实现控制与前端页面展现:
1)控制器:

2)将相应的资源拷贝至项目中:

3)修改页面:
index.html

style.css

left.html

left.css

4)运行效果:

十一、显示所有部门信息与代理
1、统一返回数据类型:
写法1:

写法2:

最终完整代码:

2、编写控制器代码:显示所有部门页面

前端left.html中修改请求地址:

3、前端显示所有部门页面
1)将页面拷贝到项目中的对应位置:

2)修改图片、CSS、js等资源相对路径:

3)运行效果:

4、通过控制器向前端传递数据

5、使用thymeleaf模板引擎
1)thymeleaf介绍(前后端模板引擎)
Thymeleaf是一个现代服务器端Java模板引擎,适用于Web和独立环境,能够处理HTML,XML,JavaScript,CSS甚至纯文本。 Thymeleaf的主要目标是提供一种优雅且高度可维护的模板创建方式。 为实现这一目标,它以自然模板的概念为基础,将其逻辑注入模板文件,其方式不会影响模板被用作设计原型。
支持前端相关的标签不解析,只显示HTML标签内容
支持后端渲染,解析形成静态HTML文件浏览器显示
2)学习thymeleaf
提供完整资料
3)配置thymeleaf支持:

4)配置thymeleaf语法支持:

5)项目支持thymeleaf:

6)HTML页面中支持thymeleaf:

7)配置支持代码自动提示:

6、前端页面绑定数据

7、数据显示的过程

8、代理:

UML-代理模式

1)静态代理:

2)动态代理

3)cglig代理

总结

十二、实现带参查询(按多条件组合模糊查询)与缓存
1、数据访问层:

SQL写法1:基于SQL的表达形式

SQL写法2:基于Mybatis动态语句

2、业务逻辑层:
1)接口

2)接口实现类

3、控制器:

改版:

4、前端页面提交查询请求:
修改页面managerDepartments.html

5、运行效果:
一个条件

二个条件

三个条件

无参数

显示所有部门:

6、分析SQL语句
修改mybatis配置文件

再添加日志文件log4j.properties,文件格式编码UTF-8
log4j.rootLogger=info,console,file

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %m%n

log4j.logger.org.mybatis=DEBUG
log4j.logger.com.neuedu.myoffice.dao=DEBUG

log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.DatePattern=’-'yyyy-MM-dd
log4j.appender.file.File=./logs/myoffice.log
log4j.appender.file.Append=true
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%-5p] %d %37c %3x - %m%n

显示所有部门

各种查询

有可能是同一个SQL语句,结果也是相同的,但是每次均会向数据库请求,数据库压力大
既然结果相同,能不能将结果缓存,这样就不读取数据库,降低数据库的压力
7、Mybatis缓存
mybatis提供查询缓存,用于减轻数据压力,提高数据库性能

一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

如果缓存中有数据就不用从数据库中获取,大大提高系统性能。

开启二级缓存

Mapper中使用缓存

参数含义:

查询中缓存数据:

增删改清空缓存数据:

运行观察结果:显示所有部门信息与各种查询

8、缓存问题:
缓存穿透
缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。
解决方案
有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法(我们采用的就是这种),如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
缓存雪崩
缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。
解决方案
缓存失效时的雪崩效应对底层系统的冲击非常可怕。大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线 程(进程)写,从而避免失效时大量的并发请求落到底层存储系统上。这里分享一个简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
缓存击穿
对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题,这个和缓存雪崩的区别在于这里针对某一key缓存,前者则是很多key。
缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
解决方案
使用互斥锁(mutex key)
"提前"使用互斥锁(mutex key)
“永远不过期”
资源保护
9、其它缓存方案
ehcache方案Ehcache是一个用Java实现的使用简单,高速,实现线程安全的缓存管理类库,ehcache提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管理方案。
redis方案Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。将热点数据表数据写入redis是,查询数据是直接从redis获取,速度非常快,麻烦的是对表进行增删改时,需要将redis中的数据与表中的数据同步一次。
ElasticSearch方案Elasticsearch是一个基于Lucene库的搜索引擎。它提供了一个分布式、支持多租户的全文搜索引擎,具有HTTP Web接口和无模式JSON文档。Elasticsearch是用Java开发的,并在Apache许可证下作为开源软件发布。
clickhouse方案NoSQL代表之一,列式存储
大数据方案hadoop、hbase、hive
10、应用程序优化:
优化数据库
从索引开始,到千万行数据开始分库分表……
SQL语句优化
使用缓存方案
后端方案
前端方案
其它方案
分布式资源将资源分散至各服务器(专业服务器:图片、CSS……),页面同步/异步加载:页面加载控制在3秒内
CDN加速经典方案:有钱自己做、没钱租

十三、实现部门信息增加
1、前提:
数据访问层实现新增部门功能
业务逻辑层实现新增部门功能
2、控制器:显示新增部门页面

前端页面调整一下createDepartment.html:

前端页面调整一下managerDepartments.html:

添加jQuery库引用并编码:

运行效果:

删除页面中编号

3、控制器:响应新增部门请求,完成新增部门操作

4、复习jQuery:javascript
基础:
html
css
javascript(DOM)
常用技能
jQuery
bootstrap
进阶技能
typescriptts
专项技能
react
angularJS
vue
1)javascript
window
location
history
navigator
alert()/confirm()

DOM操作:
查找:getElementById、getElementsByTagName、getElementsByClassName、querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素
样式:document.getElementById(‘id1’).style.color
事件:onclick、onload 、onunload 、onchange 、onmouseover 、onmouseout 、onmousedown、onmouseup
事件监听器:element.addEventListener(event, function, useCapture); 冒泡与捕获
元素操作:createElement/createTextNode/appendChild/insertBefore/removeChild/replcaceChild
2)jQuery
就绪事件:
$(document).ready(function(){……})
KaTeX parse error: Unexpected character: '' at position 29: ……}) 选择器: 基本选择器̲#id,.class,tag,…=value], [attribute*=value], [attribute1=value1] [attribute2=value2]
子元素过滤器:first-child,:last-child,:only-child,:nth-child(x=1), :nth-child(even/odd)
表单过滤器:enabled,:disabled,:checked,:selected
表单选择器:input,:text,:radio,:checkbox,:submit,:reset,:button,:file,:hidden
事件:

样式与效果:
特效
元素:
……
AJAX:

beforeSend(XHR)

类型:Function
发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头
data
类型:String
发送到服务器的数据。
error
类型:Function
默认值: 自动判断 (xml 或 html)。请求失败时调用此函数。
success
类型:Function
请求成功后的回调函数。
type
类型:String
默认值: “GET”)。请求方式 (“POST” 或 “GET”), 默认为 “GET”。
url
类型:String
默认值: 当前页地址。发送请求的地址
5、前端提交新增部门请求
1)前端调整
显示日期控件:

2)提交新增部门请求
调整一下页面:

编码jQuery代码:

6、进阶新增部门:
jQuery的serialize()方法通过序列化表单值,创建URL编码文本字符串,我们就可以选择一个或多个表单元素,也可以直接选择form将其序列化
每个元素必须提供name属性

数据验证功能:
函数的封装在jQuery就绪事件内,还是外部,不重要,因为调用时才能
除非是页面启动,就调用了封装函数,这种场景建议封装在jQuery就绪事件内部
1)获取到表单元素的value值,使用字符串方法进行判断:简单
封装验证数据合法性的函数

调用函数实现数据验证:

2)字符串最佳伴侣之正则表达式:代码简洁强大,如格式验证(18位身份证号、2位数的年龄)
封装在验证合法性函数内:

7、前端调试:
1)弹出对话框:缩短范围,适用代码简单,代码熟练
第一个不弹出对话框之前,代码肯定有问题
2)使用控制台输出:
和上面的方案差不多,但是可以获取更加详细的信息
通过详细的信息来分析代码问题

3)使用浏览器的调试功能:

8、自动增长列:
修改数据访问层xml文件

控制器

前端页面

9、值类型与引用:
不考虑字符串和整型优化问题,内存区别下:

10、解释:

十四、实现部门信息修改
1、修改“部门信息修改链接“:
managerDepartments.html

运行效果:

2、控制器显示修改部门信息页面:

3、前端显示数据:
修改updataDepartment.html页面
显示日期控件:

绑定数据:

4、控制器编写修改部门信息功能:
将新增部门代码注释,编写共用代码完成新增部门和修改部门操作:

记得修改新增部门ajax请求(insertsave)
5、前端提交修改部门请求:
调整页面:updataDepartment.html

ajax请求修改部门

十五、实现部门信息批量删除
1、数据访问层:

2、业务逻辑层:

3、控制器:

4、前端页面:

6、运行效果:

7、使用List,如何编码:
数据访问层

业务逻辑层

控制器

十六、日期转换器
1、控制器中使用注解@InitBinder:
仅限于某一个控制器有效定义父类(父类中使用注解@InitBinder实现日期转换),让所有控制器继承之,意味着所有控制器均能够实现日期转换

控制器中,凡是涉及至日期转换代码,不需要转换,直接将类型定义为Date即可
String dateDate date
升级版本:保证类型能够正确转换的前提下,可以将控制器参数定义为实体对象

2、日期转换器:全局,针对所有控制器
1)编写日期转换器

2)配置日期转换器

3)重新启动一下项目:
再修改或新增修改

十七、控制器使用实体对象接收数据
1、控制器参数为实体对象:
保证实体对象的每一个属性,能够正确转换
如果不能正确,请编写转换器
2、编码实现:

十八、HTTP状态异常和全局异常处理
1、http状态异常:

1)web.xml中配置异常请求页面地址:

2)控制器编码:

3)页面和结构:

2、全局异常处理
1)、异常:
代码异常代码有红色
运行时异常运行时发生的错误面向对象的异常处理机制建议从后向前抛,日志记录
逻辑异常难以处理,需要更高的调试技巧,1+1=3
2)异常处理结构:

3)编码实现:

故意引发异常:

十九、登录与Session
1、mybatis反向工程:表management

2、添加登录方法:Management login(String name, String password)

3、业务逻辑层
接口:

接口实现类:

4、控制器:显示登录页面

页面

5、登录功能:
1)控制器编写方法登录检查和注销

2)前端页面登录请求和注销请求
index.html

login.html

3)前端页面显示session中的内容
content.html

效果:

6、共享数据:
1)、session:
优势:存储在服务器端、生命周期、轻量级、缓存
缺点:用户量多,占用内存越大、持续时间包括非活动时间
2)、cookie:
存储在客户端、不安全、用户可以禁用cookie
场景:换肤
3)、redis:
登录以后,将相关存储在redis上、通过redis获取数据进行判断是否可以操作
注销就是清空redis中内容
4)、token方案:jwt
服务器生成token(加密),返回给客户端、客户端请求时,带上token即可
服务器对token进行判断
场景:前后端分离
5)、security oauth2:
登录、权限

二十、DRUID配置
1、druid介绍:阿里巴巴计算平台事业部出品,为监控而生的数据库连接池
Druid是Java语言中最好的数据库连接池。
Druid能够提供强大的监控和扩展功能
https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
2、配置:
web.xml



DruidWebStatFilter
com.alibaba.druid.support.http.WebStatFilter


exclusions
.js,.gif,.jpg,.png,.css,.ico,.eot,.svg,.ttf,.woff,.woff2,.json,/druid/*



profileEnable
true


principalCookieName
JSESSIONID


principalSessionName
userInfo



DruidWebStatFilter
/


DruidStatView
com.alibaba.druid.support.http.StatViewServlet



resetEnable
true



loginUsername
admin



loginPassword
123456



DruidStatView
/druid/

3、运行效果:
http://localhost:8080/myoffice/druid
输入web.xml中配置的用户名和密码,进入了首页

4、数据库优化:
1)数据库设计:
字段属性:数据类型、长度、非空
3NF或4NF反规范化
分库分表1000万条记录
2)索引:
索引的类型
索引的键
何时索引无效
3)SQL语句
执行计划:

长期研究,得出一些结论优先使用join、使用union不使用临时表……

4)事务:
SQL中使用
Java中使用

二十一、AOP
1、AOP:
面向切面的程序设计(Aspect-oriented programming,AOP,又译作面向方面的程序设计、剖面导向程序设计)是计算机科学中的一种程序设计思想,旨在将横切关注点与业务主体进行进一步分离,以提高程序代码的模块化程度。
通过在现有代码基础上增加额外的通知(Advice)机制,能够对被声明为“切点(Pointcut)”的代码块进行统一管理与装饰,如“对所有方法名以‘set*’开头的方法添加后台日志”。
该思想使得开发人员能够将与代码核心业务逻辑关系不那么密切的功能(如日志功能)添加至程序中,同时又不降低业务代码的可读性。面向切面的程序设计思想也是面向切面软件开发的基础。
面向切面的程序设计将代码逻辑切分为不同的模块(即关注点(Concern),一段特定的逻辑功能)。几乎所有的编程思想都涉及代码功能的分类,将各个关注点封装成独立的抽象模块(如函数、过程、模块、类以及方法等),后者又可供进一步实现、封装和重写。部分关注点“横切”程序代码中的数个模块,即在多个模块中都有出现,它们即被称作“横切关注点(Cross-cutting concerns, Horizontal concerns)”。
日志功能即是横切关注点的一个典型案例,因为日志功能往往横跨系统中的每个业务模块,即“横切”所有有日志需求的类及方法体。而对于一个信用卡应用程序来说,存款、取款、帐单管理是它的核心关注点,日志和持久化将成为横切整个对象结构的横切关注点。
切面的概念源于对面向对象的程序设计的改进,但并不只限于此,它还可以用来改进传统的函数。与切面相关的编程概念还包括元对象协议、主题(Subject)、混入(Mixin)和委托(Delegate)
2、业务划分理解:

3、切入点(pointcut):
切入点表达式的语法格式:
execution([权限修饰符] [返回值类型] [简单类名/全类名] 方法名)
示例:
execution(* com.atguigu.spring.ArithmeticCalculator.(…))
execution(public * ArithmeticCalculator.
(…))
execution(public double ArithmeticCalculator.(…))
execution(public double ArithmeticCalculator.
(double, …))
execution(public double ArithmeticCalculator.(double, double))
切入点表达式可以通过 “&&”、“||”、“!”等操作符结合起来
execution (
.add(int,…)) || execution( *.sub(int,…))
4、通知类型(advice):
1)前置通知[Before advice]:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常。
2)正常返回通知[After returning advice]:在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行。
3)异常返回通知[After throwing advice]:在连接点抛出异常后执行。
4)返回通知[After (finally) advice]:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容。
5)环绕通知[Around advice]:环绕通知围绕在连接点前后,比如一个方法调用的前后。这是最强大的通知类型,能在方法调用前后自定义一些操作。环绕通知还需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行。
5、编程实现:
1)配置dispatcher-servlet.xml

2)编写AOP处理类:就是一个模块

6、运行效果:

7、典型场景:
日志模块大部分业务均需要日志记录
大数据融合框架(SSM/SpringBoot/SpringCloud……)中商品详情、收藏、加入购买车、支付框架(SSM/SpringBoot/SpringCloud……)中推荐商品信息收集模块:写入消息队列,如kafka……flume/storm/spark……数据存储hbase……MR/Storm/sparlk(协同过滤算法)生成商品推荐信息框架(SSM/SpringBoot/SpringCloud……)再读取展示

二十二、拦截器
1、Servlet:很久的回忆Java Web(Servlet + Filter + ListenerJSP)
Servlet:全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类别,一般情况下,人们将Servlet理解为后者。
Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
最早支持Servlet标准的是JavaSoft的Java Web Server。此后,一些其它的基于Java的Web服务器开始支持标准的Servlet。

Filter:过滤器
请求一个资源或者从一个资源返回信息的时候执行过滤操作的插件。Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,一般常用于实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

Listener:监听器
监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量

2、Servlet历史:

3、Servelt还能在SSM/SpringBoot……框架中使用:
依然可以支持使用
4、拦截器:interceptor
它依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。
由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
场景:判断用户是否登录、检查权限……
注意:拦截器内的代码不能过于复杂,否则用户请求返回时间太长
5、编码实现使用拦截器完成登录验证:
1)添加拦截器类:

2)配置dispatcher-servlet.xml:

3)运行效果:

4)修改拦载器代码:

运行效果:

5)通过配置文件dispatcher-servlet.xml为拦截器传递参数:
通过修改控制器使用常量方法判断,不方便后期维护
使用配置文件dispatcher-servlet.xml为拦截器传递参数,方便后期维护

二十三、restful
1、RESTful:
表现层状态转换(英语:Representational State Transfer,缩写:REST)是Roy Thomas Fielding博士于2000年在他的博士论文中提出来的一种万维网软件架构风格,目的是便于不同软件/程序在网络(例如互联网)中互相传递信息。表现层状态转换是根基于超文本传输协议(HTTP)之上而确定的一组约束和属性,是一种设计提供万维网络服务的软件构建风格。符合或兼容于这种架构风格(简称为 REST 或 RESTful)的网络服务,允许客户端发出以统一资源标识符访问和操作网络资源的请求,而与预先定义好的无状态操作集一致化。因此表现层状态转换提供了在互联网络的计算系统之间,彼此资源可交互使用的协作性质(interoperability)。相对于其它种类的网络服务,例如SOAP服务,则是以本身所定义的操作集,来访问网络上的资源。
目前在三种主流的Web服务实现方案中,因为REST模式与复杂的SOAP和XML-RPC相比更加简洁,越来越多的Web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务运行图书查询;雅虎提供的Web服务也是REST风格的。
2、要点与标准
需要注意的是,REST是设计风格而不是标准。REST通常基于HTTP、URI、XML以及HTML这些现有的广泛流行的协议和标准。
 资源是由URI来指定。
 对资源的操作包括获取、创建、修改和删除,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。
 通过操作资源的表现形式来操作资源。
 资源的表现形式则是XML或者HTML,取决于读者是机器还是人、是消费Web服务的客户软件还是Web浏览器。当然也可以是任何其他的格式,例如JSON。
3、REST优点
 可更高效利用缓存来提高响应速度
 通讯本身的无状态性可以让不同的服务器的处理一系列请求中的不同请求,提高服务器的扩展性
 浏览器即可作为客户端,简化软件需求
 相对于其他叠加在HTTP协议之上的机制,REST的软件依赖性更小
 不需要额外的资源发现机制
 在软件技术演进中的长期的兼容性更好
前后端分离,减少流量
安全问题集中在接口上,由于接受JSON格式,防止了注入型等安全问题
前端无关化,后端只负责数据处理
前端表现方式可以是任何前端语言(html5/ios/android……)
前端和后端更加专注于各自开发,专注于自己擅长的领域,前端只需要后端接口文档就可以完成前后端交互,无需过多相互了解团队架构:产品(美工 + 前端)+ 编码(后端 + 数据库)+ 测试(测试 + 测试开发) + 运维(运营 + 推广 + ……)
服务器性能优化因为前端是静态页面,通过nginx部署,服务器压力放在接口上
4、基于RESTful原则:不同公司可能有不同需求
接口命名时应用用名词,不应该用动词,因为通过接口操作的是资源
在url中加入版本号,方便版本迭代管理更加直观
……
5、请求风格:
传统风格url?参数名1=值1&参数名2=值2
RESTful
 url/参数值1/参数值2
对资源的操作包括获取、创建、修改和删除,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。
6、修改编码:所有操作均统一返回JSON数据
查询所有

查询某一个部门信息:

针对新增、修改、删除控制器的写法:
新增部门

修改部门

删除部门

7、模拟前后端分离显示所有部门数据:
因为没有nginx部署,静态页面,还是使用项目中的显示所有部门页面

请求测试:

前端页面:

运行效果:

8、jsrender使用转换器正确显示日期:
注册转换器

使用转换器

运行效果:

二十四、作业-单文件和多文件上传

你可能感兴趣的:(java)