Java项目的学习
2021-08-05 10:47:17 7 举报
AI智能生成
java学习
作者其他创作
大纲/内容
项目一
项目二
常用注解整理
Mybatis注解
@Param()
多个参数赋值的时候使用,(记得和数据库的字段名一样)
Spring注解
@RequestParam
value:接收集合数据(可以不写)
required:前端必须提供参数,否则会报错
defaultValue:给参数提供默认值
name:解决前后端参数名不一致
同步
异步
@ResponseBody
将结果转换成json,交给前端
常用注解
@Controller
@RestController
(相当于@Controller+@ResponseBody)
(相当于@Controller+@ResponseBody)
GetMapper("")
PostMapper()
PutMapper()
DeleteMapper()
@Service
@Component
@RequestBoby
请求体中的数据
@RequestParam
请求头中的参数
SpringMVC
@ModelAttribute
在controller所有方法执行之前执行
@ModelAttribute
多个请求之间共用数据
@SessionAttributes只能使用在类定义上。
@SessionAttributes 除了可以通过属性名指定需要放到会 话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中 例如:
@SessionAttributes(types=User.class)会将model中所有类型为 User的属性添加到会话中。
@SessionAttributes(value={“user1”, “user2”}) 会将model中属性名为user1和user2的属性添加到会话中。
@SessionAttributes(types={User.class, Dept.class}) 会将model中所有类型为 User和Dept的属性添加到会话中。
@SessionAttributes(value={“user1”,“user2”},types={Dept.class})会将model中属性名为user1和user2以及类型为Dept的属性添加到会话中。
value和type之间是并集关系
@SessionAttributes 除了可以通过属性名指定需要放到会 话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中 例如:
@SessionAttributes(types=User.class)会将model中所有类型为 User的属性添加到会话中。
@SessionAttributes(value={“user1”, “user2”}) 会将model中属性名为user1和user2的属性添加到会话中。
@SessionAttributes(types={User.class, Dept.class}) 会将model中所有类型为 User和Dept的属性添加到会话中。
@SessionAttributes(value={“user1”,“user2”},types={Dept.class})会将model中属性名为user1和user2以及类型为Dept的属性添加到会话中。
value和type之间是并集关系
SpringBoot
@SpringBootApplication
MybatisPlus
表名和数据库名不一致
@TableName("数据库表名")
数据库会自动生成id
随机生成的id(数字很长)
解决方案(自动增长)
@TableId(type=IdType.AUTO)
Lombok
@Builder
相当于一个单例对象,每次不能直接创建对象,用类名.成员变量来使用,用buil()结束
Java SE阶段
java基础
jdk动态代理
Proxy.newProxyInstance(classLoader,interfaces,new InvocationHandler(){
XXXXXXXXXXX
});
XXXXXXXXXXX
});
参数1:目标对象的类加载器
xxx.getClass().getClassLoader();
参数2:目标对象的接口数组
xxx.getClass().getInterface();
参数3:实现增强的业务逻辑
new InvocationHandler(){
public Object invoke(proxy,method,Object[] args){
return null;
}
}
public Object invoke(proxy,method,Object[] args){
return null;
}
}
proxy
参数1:jdk工具类生产的代理对象
method
参数2:当前用户执行的某个方法
args
参数3:当前用户执行的某个具体方法的实际参数列表
CGLab动态代理
Enhancer.create(xxx.getClass,new MethodInterceptor(){
public Object intercept(Object o,Method method,Object[] objects,MethodProxy ){
}
});
public Object intercept(Object o,Method method,Object[] objects,MethodProxy ){
}
});
子主题
参数1:目标对象的class类
参数2:实现增强的业务逻辑
intercept代理对象方法入口
参数1:cglib生产出来的代理对象
参数2:执行代理对象(子)被拦截的方法
参数3:objects:执行代理对象,被拦截的方法中的参数列表
参数4:执行目标对象(子)被拦截的方法
反射技术
@Override
重写注解
@Deprecated
方法已经过期
@SuppressWarnings
忽略警告信息
比如大家使用集合的时候,有时候为了偷懒,会不写泛型,像这样:
List heros = new ArrayList();
那么就会导致编译器出现警告,而加上
@SuppressWarnings({ "rawtypes", "unused" })
List heros = new ArrayList();
那么就会导致编译器出现警告,而加上
@SuppressWarnings({ "rawtypes", "unused" })
@SuppressWarnings 有常见的值,分别对应如下意思
1.deprecation:使用了不赞成使用的类或方法时的警告(使用@Deprecated使得编译器产生的警告);
2.unchecked:执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型; 关闭编译器警告
3.fallthrough:当 Switch 程序块直接通往下一种情况而没有 Break 时的警告;
4.path:在类路径、源文件路径等中有不存在的路径时的警告;
5.serial:当在可序列化的类上缺少 serialVersionUID 定义时的警告;
6.finally:任何 finally 子句不能正常完成时的警告;
7.rawtypes 泛型类型未指明
8.unused 引用定义了,但是没有被使用
9.all:关于以上所有情况的警告。
@SafeVarargs
当使用可变数量的参数的时候,而参数的类型又是泛型T的话,就会出现警告。 这个时候,就使用@SafeVarargs来去掉这个警告
@SafeVarargs注解只能用在参数长度可变的方法或构造方法上,且方法必须声明为static或final,否则会出现编译错误。一个方法使用@SafeVarargs注解的前提是,开发人员必须确保这个方法的实现中对泛型类型参数的处理不会引发类型安全问题。
public class Hero {
String name;
@SafeVarargs
public static <T> T getFirstOne(T... elements) {
return elements.length > 0 ? elements[0] : null;
}
}
String name;
@SafeVarargs
public static <T> T getFirstOne(T... elements) {
return elements.length > 0 ? elements[0] : null;
}
}
@FunctionalInterface(JDK1.8新增的注解)
约定函数式接口
函数式接口概念: 如果接口中只有一个抽象方法(可以包含多个默认方法或多个static方法),该接口称为函数式接口。函数式接口其存在的意义,主要是配合Lambda 表达式 来使用。
@FunctionalInterface
public interface AD {
public void adAttack();
}
public interface AD {
public void adAttack();
}
java进阶
java8新特性
概述
速度更快
代码更少
更强大的API
便于并行
减少了空指针异常
Nashorn引擎
允许在JVM上运行js应用
Lambda
常用语法
(o1,o2)->{System.out.println(o1+o2);};
(o2)->{System.out.println(o1+o2);}
(o1,o2)->System.out.println(o1+o2);
(o1)->{System.out.println(o1+o2);}
-> 左边:参数类型,可以省略(类型推断) 如果只有一个参数,可以不用写变量名
->右边:应该写{},如果只有一句话,并且有return ,return和{}可以省略
自定义函数式接口
只包含一个抽象方法的接口,称为函数式接口
在接口上使用@FunctionalInterface可以检查他是否为函数式接口
方法引用
如何使用
使用格式
类(对象)::方法名
使用情况
类(对象)::非静态方法
类::静态方法
类::非静态方法
stream(主要用于计算)
stream和collection区别
stream关注的是数据,与cpu打交道
集合关注的是数据存储,与内存打交道
执行流程
实例化
通过集合
通过数组
通过of
Stream.of()
创建无限流
Stream.iterate(0,t->t+2).limit(10).forEach(...)
迭代
Stream.generate(Math::random).limit(10).forEach(输出)
生成
中间操作
筛选和切片
filter过滤
all.stream().filter(e->e.getRid()>40).forEach(System.out::println);
skip跳过
distinct去重
映射
map
将集合中的元素,解析出来,变成另外一个stream流
flatMap
如果集合中,有集合,可以解析出来变成另一个stream流
排序
all.stream().sorted((s1,s0)->s1.getRid().compareTo(s1.getRid())).filter(s->s.getRid()>50).forEach(System.out::println);
终止操作
匹配与查找
allMatch()
检查是否匹配所有元素
anyMatch()
检查是否匹配至少有一个元素
noneMatch()
检查匹配是否没有匹配的元素
findFirst
返回第一个元素
findAny
返回任意一个元素
count
返回流中元素的总个数
max
返回流中的最大值
min
返回流中的最小值
forEach
规约
reduce
可以将流中的元素结合起来,得到一个值
收集
collect
转换为list
List<Route> list = all.stream().collect(Collectors.toList());
转换为set
List<Route> list = all.stream().collect(Collectors.toSet());
转换为map
Map<Long, User> map = users.stream().collect(Collectors.toMap(User::getId, o -> o));
Optional(避免空指针)
如何使用
创建optional实例
ofNullable
不会报异常
不管什么都可以为空
不管什么都可以为空
optional方法
orElse()
如果当前的optional为空,就用orElse中的T(条件)
如果不为空,则返回内部的值
如果要获取里面的值,但是怕抛出其他异常,可以先进行判断
isPresent();
如果不为空可以使用get,获取改值
Java EE阶段
前端技术
html
概述
HTML
超文本标记语言
常用标签
a标签
href
绝对地址
相对地址
./当前目录
../上一级目录
target
_self
_bland
打开一个新窗口
标题标签
h1-h6
水平线
hr
列表标签
ul
ol
li
img图片标签
src路径
容器
div
span
转义字符
英文空格
 
中文空格
>
大于
<
小于
&
&
表格
table
tr
td
th
表单
from
action
method
get
数据在请求地址中
post
在请求体中
post提交需要一个
<input type="hidden" name="xxx" value="xxx"/>
post提交需要一个
<input type="hidden" name="xxx" value="xxx"/>
enctype="multipart/form-data"
上传文件必须写
表单标签
input
checked用于设置单选和复选默认选中
type
text
password
date
radio
checkbox
file
reset
submit
button
label
select
textarea
button
type
reset
submit
button
css
css基础语法
css样式
行内样式
内部样式
外部样式
基本选择器
id选择器
#
标签选择器
div
class选择器
.
扩展选择器
层级选择器
,
并集选择器
空格
css常用样式
文字文本
背景
background
显示
display
block
块元素
inline
内联元素
none
隐藏
位置
position
absolute
绝对位置
从0,0点开始计算
relative
相对位置
从第一个点的位置开始计算
浮动
float
left
right
clear清理
清理周围的元素,左边left,右边right,两边both
盒子模型
标准盒模型
box-sizing:content-box
IE盒模型
box-sizing: border-box
组成部分
margin(外边距)
border(边框)
padding(内边距)
content(内容)
js
js概述
JavaScript
网页交互
js组成
ECMAScript
BOM
浏览器对象模型
DOM
文档对象模型
运算符
算数运算符
数值可以与字符串进行数学运算,底层进行了转换
比较运算符
===恒等 先比较类型,然后比较内容
!==恒不等 先比较类型后比较内容
流程控制语句
顺序
代码从上往下,逐行执行
分支
条件语句
if...else if...else
switch..case..default
循环
while
do...while
for...i
for...in
数组的索引index
for...of
数组的元素
常用事件
页面加载完毕事件
window.onload
获取焦点
onfocus
失去焦点
onblur
值改变时
onchange
单击时
onclick
基础语法
HTML引入js
外部
<script src=""></script>
内部
js三种输出方式
alert();
document.write()
console.log()
js变量声明
let
var
ECMA6以后的语法
const
常量
BOM对象
Window对象
三种弹框
alert()
confim()
prompt()
两种定时器
setTimeout(函数,毫秒值)
clearTimeout(定时器)
setInterval(函数,毫秒值)
clearInterval(定时器)
Location对象
Location 对象方法
reload()
重新加载当前文档。
assign()
加载新的文档
replace()
用新的文档替换当前文档
href
可以进行页面的跳转
DOM对象
获取元素
ES5
getElementById
ES6
querySelect(css选择器)
querySelectAll(css选择器)
操作内容
innerHtml
innerText
操作属性
js对象.properties
原生属性
操作样式
js对象.style.样式名
js对象.style.cssText
js对象.className
操作元素
添加元素
js对象.innerHTML +=追加内容
document.createjs对象(标签)
parentNode.appendChild(newNode)
正则表达式
创建
let rege = new RegExp(“正则表达式”);
let regex = /正则表达式/;
验证方法
正则对象.test(字符串)
Jquery
概述
jquery是js轻量级框架
基础语法
html引入jquery
<script src="../js/jquery-3.2.1.min.js"></script>
$(js对象)
jq对象.get(索引)
页面加载事件
window.onload=function(){}
只能定义一次
只能定义一次
只能定义一次
$(function(){})
可以定义多次
选择器
基本选择器
$("标签名")
$("#id选择器)
$(".class选择器")
层级选择器
$("A B")
$("选择器1,选择器2")
$("A > B")
属性选择器
$("A[属性名='值']")
$("A[属性名='值'][]...")
基本过滤选择器
:first
:last
:even
:odd
:eq(index)
对象遍历
jq对象.each(function(index,element){})
jquery的DOM
操作内容
html()
text()
属性
val()
attr()
prop()
removeProp()
checked
selected
样式
jq对象.css()
jq对象.addClass()
jq对象.removeClass()
元素
$("<a></a>")
创建jq标签对象
prepend()
父添加子,放在一个位置
append
父添加子,放在最后一个
remove()
所有删除
empty()
删除所有并且删除所有子标签
jquery事件绑定
js对象.事件属性=function(){}
jq对象.事件函数(function(){})
AJAX
同步概念
当浏览器发送请求之后,就会处于等待状态,此时不能做任何操作,不然会取消当前操作
会影响当前页面的数据
异步概念
ajax是异步请求,用于快速创建动态网页的技术
当浏览器发送请求之后,他不会处于等待状态,还可以做其他的操作,这就是异步操作
异步请求不会影响其他的数据
原生ajax
jquery方式的ajax
1.$.get()
四个参数
请求地址
必须的
请求参数
响应回调函数
响应数据类型
2.$.post()
3.ajax()
建议使用
此方法中的参数是一个json格式的数据,就是有key和value
$.ajax({});
参数以(:)隔断
type
post/get
url
请求地址
data
请求参数
dataType
响应内容的预定义类型(html/text/json/xml)
success
执行成功后的回调函数
contentType
请求正文的MIME类型
Json转换方式
Jackson
new ObjectMapper();
// 将任意对象转json字符串
objectMapper.writeValueAsString(对象/map/list);
objectMapper.writeValueAsString(对象/map/list);
// 将json转对象
objectMapper.readValue(json,User.class);
objectMapper.readValue(json,User.class);
Gson
Fastjson(阿里巴巴)
将对象转为json
JSON.toJSONString(对象);
将json转为java对象
//对象是单个元素
JSON.parseObject(json串,CLAZZ);
//对象包含多个元素
JSON.parseArray(json串,CLAZZ);
JSON.parseObject(json串,CLAZZ);
//对象包含多个元素
JSON.parseArray(json串,CLAZZ);
list-->json
String jsonString = JSON.toJSONString(stringList);
json-->list
List<String> list =JSON.parseArray(jsonString,String.class);
map-->json
String jsonString2 = JSON.toJSONString(map);
json-->map
Map<String,Integer> map2 =JSON.parseObject(jsonString2,Map.class);
JavaBean-->Json
https://www.jianshu.com/p/f20ffefeec4d
vue
Vue概述
Vue的出现是为了简化前端页面的编写
他是一个渐进式框架
一个前端项目,可以使用vue特性,也可以不使用vue特性
使用的步骤
1.引入vue的js类库
<script src="../js/vue-2.6.12.js"></script>
2.创建出vue的视图
<!--2.vue管理视图-->
<div id="app">
<h3>获取input中输入的文字</h3>
<input type="text" v-model="message">
<div style="border:red 1px solid; height: 25px;">{{message}}</div>
</div>
<div id="app">
<h3>获取input中输入的文字</h3>
<input type="text" v-model="message">
<div style="border:red 1px solid; height: 25px;">{{message}}</div>
</div>
3.创建出vue的脚本(js代码)
<script>
// 声明的是常量,相当于java中final关键字
const app = new Vue({
el: '#app', // 用于挂载视图,使用css选择器
data: { // 用于管理数据(模型)
message:'',
},
methods:{ // 方法
}
});
</script>
// 声明的是常量,相当于java中final关键字
const app = new Vue({
el: '#app', // 用于挂载视图,使用css选择器
data: { // 用于管理数据(模型)
message:'',
},
methods:{ // 方法
}
});
</script>
Vue注意方面
视图
脚本
常用指令
文本插值
插值表达式
{{}}
网络不好的情况下会展示{{message}}
解决插值表达式网络不好,展示原内容
v-text:"Vue变量"
v-html:"Vue变量"
绑定属性
v-bind:属性名="Vue变量名"
:属性名:"Vue变量名"
简化语法
列表循环
普通遍历
<li v-for="user in userList">
{{user.id}}----{{user.name}}---{{user.address}}
</li>
{{user.id}}----{{user.name}}---{{user.address}}
</li>
遍历list
<li v-for="(index,user) in userList">
{{user.id}}----{{user.name}}---{{user.address}}
</li>
{{user.id}}----{{user.name}}---{{user.address}}
</li>
遍历map
<li v-for="(index,key,value) in userList">
<br>{{index}}----{{key}}----{{value}}
<br><br></li>
<br>{{index}}----{{key}}----{{value}}
<br><br></li>
条件判断
v-if="条件判断"
他是直接没有
v-show="条件判断"
他的底层是不会删除,会隐藏,不显示
display:none
v-if="布尔表达式"
v-else-if="布尔表达式"
v-else
v-else-if="布尔表达式"
v-else
事件绑定
v-on:事件名="方法"
简化语法
@事件名
如何使用调用方法
<script>
const app = new Vue({
el: '#app',
data: {
num: 1 // 全局变量
},
methods: { // 方法声明
numDiff: function () {
// 局部变量
let num = 1
// this表示当前对象 const app = new Vue()
if (this.num > 1) {
this.num--;
}
}
}
})
</script>
const app = new Vue({
el: '#app',
data: {
num: 1 // 全局变量
},
methods: { // 方法声明
numDiff: function () {
// 局部变量
let num = 1
// this表示当前对象 const app = new Vue()
if (this.num > 1) {
this.num--;
}
}
}
})
</script>
表单绑定
v-model
监视器
类似于onChange(是否发生改变)
他可以获取到变化前后的值。
常用语法
watch: {
被监控的简单变量(newValue, oldValue) {
},
}
watch: {
被监控的简单变量(newValue, oldValue) {
},
}
如果是被监控的对象变量的话
watch: {
被监控的对象变量: {
deep:true,
handler(newValue) {}
}
}
watch: {
被监控的对象变量: {
deep:true,
handler(newValue) {}
}
}
基础语法
bootstrap
ElementUI
Java Web
Tomcat&Servlet
Tomcat
概述
Tomcat是web应用服务器,是Apache软件基金会项目中的一个核心项目,是一个免费开源的web服务器,属于轻量级应用服务器
架构分类
C/S架构
客户端安装专门的软件
B/S架构
浏览器作为客户端
资源分类
静态
html;css;js;jpg
动态
jsp;servlet;php;.net;ruby;python
目录结构
bin
可执行文件
startup.bat
shutdown.bat
conf
配置文件
server.xml可以设置应用服务器的端口,或发布目录文件(不建议修改)
lib
所依赖的jar包
logs
日志信息
temp
零时文件
webapps
发布目录
如何发布
1.将文件打成zip或者直接打成war包
2.把war包复制到webapps目录下,如果是zip格式的话,改一下后缀名改为war
Root目录
默认访问的是Tomcat目录/webapps/ROOT目录
直接可以省略项目的名字/ 表示找到root目录
work
jsp文件被编译后的文件存放目录
在root目录中,并且jsp编译后的文件会变成两个文件,一个.class和一个java文件
session对象被序列化后保存的位置
启动有问题
配置java环境变量
或者是端口占用了
Http协议
概述
在客户端和服务器通信时,为了规范数据传输的格式
他是基于TCP协议来传输的
构成
请求格式
请求行
get
post
请求头
请求体的描述信息
Referer
(防盗链)告诉服务器该网页是从哪个页面链接过来的
User-Agent
会告诉网站服务器
请求体
数据内容
get没有,post有
响应格式
响应行
协议
状态码
200
成功
301
资源(网页等)被永久转移到其它URL
302
该资源原本确实存在,但已经被临时改变了位置
304
未修改
404
访问不到地址
405
请求的资源(网页等)不存在
500
内部服务器错误
响应头
响应描述信息
Location
Content-type
设置MIME类型
Content-Disposition
refresh
表示浏览器应该在多少时间之后刷新文档,以秒计
Last-Modified
文档的最后改动时间。
Content-Encoding
文档的编码
响应体
数据内容
Servlet
概述
servlet是一个运行在服务器端的一个小程序
入门
第一步
在web.xml
<servlet>
<servlet-name>aaa</servlet-name>
<servlet-class>com.itheima01.Demo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>aaa</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
<servlet-name>aaa</servlet-name>
<servlet-class>com.itheima01.Demo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>aaa</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
第二步
public class Demo01 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("方法被访问了");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("方法被访问了");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
生命周期
什么时候创建对象
默认是在Servlet第一次被访问的时候创建对象,创建对象会执行init()方法
什么时候调用方法
访问Servlet类的时候就会执行service()方法
什么时候销毁对象
服务器正常关闭就会自动执行distory()方法
Servlet注解配置
@Servlet("")
Servlet体系结构
顶层接口
Servlet
5个抽象方法
GenericServlet
抽象4个方法
留下了一个抽象方法
HttpServlet
没有抽象方法
doGet()
doPost()
ServletContext
概述
Tomcat在启动时,它会为web项目创建一个ServletContext对象
ServletContext对象可以存放当前项目的一些数据
每个web项目只有一个ServletContext对象
获取
request.getServletContext();
如果继承HttpServlet后,可以直接调用
getServletContext()
作用&使用
域对象可以完成数据的共享
使用
serAttribute("字符串",Object)
getAttribute("字符串",Object)
removeAttribute(String name)
配置全局参数
<!--配置全局参数-->
<context-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</context-param>
<context-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</context-param>
//获取ServletContext
ServletContext context = getServletContext();
//获取全局参数
String encoding = context.getInitParameter("encoding");
//码表
System.out.println(encoding);
ServletContext context = getServletContext();
//获取全局参数
String encoding = context.getInitParameter("encoding");
//码表
System.out.println(encoding);
获取路径
getContextPath()
获取虚拟访问路径
getRealPath("")
获取真实路径
Request
概述
客户端请求
获取请求行
getMethod()
获取请求方式的类型
getRequestURL()
获取客户端发出请求完整URL
getRequestURI()
获取请求行中的资源名部分
getRemoteAddr()
获取客户机IP地址
请求头
request.getHeader("User-agent")
获取浏览器的版本
request.getHeader("Referer");
获取该网页是从哪个页面链接过来的
response.setContentType("text/html;charset=utf-8");
设置中文编码
获取请求参数
getParameter(String name)
根据名称获取数据
getParameterValues(String name)
根据名称获取所有数据
getParameterMap()
获取所有参数的键值对
Response
概述
服务器发送给浏览器端数据
响应行
response.setStatus(200);
设置状态码
响应头
response.setHeader("content-disposition","attachment;filename=文件名");
告诉浏览器下载的方式 来接收数据
response.setHeader("refresh","秒;url=网址");
告诉浏览器在指定的时间之后跳转到指定的路径
响应体
getWriter()
使用字符流
getOutputStream()
使用字节流
设置响应编码规范
response.setContentType("text/html;charset=utf-8");
解决请求乱码问题
get
不需要解决
post
request.setCharacterEncoding("utf-8");
重定向
resp.sendRedirect(req.getContextPath() + "/RouteServlet");
转发
req.getRequestDispatcher("/route_list.jsp").forward(req, resp);
重定向和转发的区别
1.请求转发浏览器地址栏不会发生变化,重定向地址栏会发生变化
2.请求转发是一次请求, 重定向是两次请求
3. 请求转发只能转发到当前项目的资源, 重定向可以到任意服务器的资源
4. 转发可以携带数据
Cookie
概述
客户端;会话技术
浏览器关闭会话结束
如何是用
new Cookie("xxx","xxx");
发送cookie对象
response.addCookie(c);
response.addCookie(c);
获取cookie
request.getCookies();
request.getCookies();
cookie细节
运行一次发送多个cookie,给浏览器保存
可以设置cookie的存活时间
setMaxAge(秒)
设置多长时间就存活多长时间
如果设置-1就代表默认值
如果设置0,就是立马删除
cookie特点
cookie把数据存储在浏览器中
单个cookie有大小限制(4kb)且同一个域名下cookie的数量不能超过50个
作用
1. cookie一般用于存出少量的不太敏感的数据
2. 在不登录的情况下,完成服务器对客户端的身份识别
2. 在不登录的情况下,完成服务器对客户端的身份识别
应用场景
记录最后一次登录时间
Session
概述
服务器会话技术
把数据保存在服务器端的会话技术
快速入门
HttpSession是一个域对象
setAttribute(String name,Object value)
getAttribute(String name)
removeAttribute(String name)
invalidate()
清除会话
session细节
1.客户端关闭,服务器不关闭,数据是否相同
默认情况下,浏览器关闭,再次打开二次获取的session不一样
基于cookie实现(浏览器关闭,cookie销毁)
基于cookie实现(浏览器关闭,cookie销毁)
设置cookie的存活时间(JESSIONID)
这里我们代替服务器,做一个小操作,覆盖这个JSESSIONID,指定持久化时间
这里我们代替服务器,做一个小操作,覆盖这个JSESSIONID,指定持久化时间
2.客户端不关闭,服务器关闭,数据是否相同
当服务器正常关闭,重启后,二次获取的session数据一样
tomcat这哥们实现以下二个功能
钝化(序列化)
当服务器正常关闭时,session中的数据,会序列化到磁盘
活化(反序列化)
当服务器开启后,从磁盘文件中,反序列化到内存中
钝化(序列化)
当服务器正常关闭时,session中的数据,会序列化到磁盘
活化(反序列化)
当服务器开启后,从磁盘文件中,反序列化到内存中
session特点
1. session存储数据在服务器
2. session存储类型任意(Object)
3. session存储大小和数量没有限制(相对于内存)
4. session存储相对安全
2. session存储类型任意(Object)
3. session存储大小和数量没有限制(相对于内存)
4. session存储相对安全
四大域对象
PageContext
PageContext对象是JSP页面中才有的对象
request(请求域)
可以在一次请求范围内进行共享数据
session
域作用范围是当前会话
ServletContext
域的范围是整个web应用
JSP
概述
JSP的本质是Servlet
将Java代码和HTML语句混合在同一个文件中编写,页面动态资源使用java代码,页面静态资源使用html标签。
jsp语法
<% Java代码 %>
编写逻辑java代码
<%! Java代码 %>
定义全局变量和方法
<%= Java代码%>
向页面输出数据
jsp指令
jsp指令的格式
<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>
jsp指令
page
include
tablib
jsp九个内置对象
作用
jsp页面不需要获取和创建,可以直接使用对象
内置对象
pageContext
PageContext
当前页面中共享数据
request
HttpServletRequest
一次请求中共享数据
session
HttpSession
一次会话中共享数据
application
ServletContext
整个web应用共享数据
response
HttpServletResponse
响应对象
page
Object
当前页面(Servlet)对象
out
JSPWiter
输出数据
config
ServletConfig
servlet配置对象
exception
Throwable
异常对象
el表达式
作用
代替JSP里面的运算
域对象的数据获取
语法
${}
格式:
${域名称.键名称}
获取普通值:
${域名称.键名称}
获取对象:
${域对象.键名称.成员变量名}
获取List集合:
${域对象.键名称[索引]}
获取Map集合:
${域对象.键名称.map键名称}
${域对象.键名称["map键名称"]}
${域名称.键名称}
获取普通值:
${域名称.键名称}
获取对象:
${域对象.键名称.成员变量名}
获取List集合:
${域对象.键名称[索引]}
获取Map集合:
${域对象.键名称.map键名称}
${域对象.键名称["map键名称"]}
获取虚拟目录
${pageContext.request.contextPath}
jstl标签
if :相当于java代码的if语句
test 必须写的属性,接受boolean表达式
一般情况下,test属性值会结合el表达式一起使用
jstl里面的判断只有if 没有else
test 必须写的属性,接受boolean表达式
一般情况下,test属性值会结合el表达式一起使用
jstl里面的判断只有if 没有else
foreach:相当于java代码的for语句
begin 代表循环的的开始数字
end 代表循环的结束数字
step 代表步长,相当于以前的i++
var 代表循环的变量
items 代表要遍历的集合
varStatus 保存了循环过程中的信息
begin 代表循环的的开始数字
end 代表循环的结束数字
step 代表步长,相当于以前的i++
var 代表循环的变量
items 代表要遍历的集合
varStatus 保存了循环过程中的信息
MVC模式
M Model
java实体类,JavaBean
V View
视图就是用来给用户显示数据的
C Controller
处理请求和响应,java代码
三层架构
Web层
其实就是Servlet,用来接收请求和处理响应
service层
业务逻辑处理
dao层
操作数据库,操作数据
filter
概述
过滤器,用于登录验证,统一编码处理,或者铭感字符过滤
如何使用
1.定义一个类实现Filter类,重写里面的抽象方法
2. 编写拦截请求
3.设置放行
public class QuickFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 此方法拦截用户请求
* @param servletRequest :请求对象
* @param servletResponse :响应对象
* @param filterChain :过滤器链(是否放行)
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("QuickFilter拦截了请求...");
// 放行
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 此方法拦截用户请求
* @param servletRequest :请求对象
* @param servletResponse :响应对象
* @param filterChain :过滤器链(是否放行)
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("QuickFilter拦截了请求...");
// 放行
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
4.在web.xml文件中配置过滤器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--快速入门-->
<!--注册filter-->
<filter>
<filter-name>QuickFilter</filter-name>
<filter-class>cn.itcast.a_quick.QuickFilter</filter-class>
</filter>
<!--配置filter拦截路径-->
<filter-mapping>
<filter-name>QuickFilter</filter-name>
<url-pattern>/quick.jsp</url-pattern>
</filter-mapping>
</web-app>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--快速入门-->
<!--注册filter-->
<filter>
<filter-name>QuickFilter</filter-name>
<filter-class>cn.itcast.a_quick.QuickFilter</filter-class>
</filter>
<!--配置filter拦截路径-->
<filter-mapping>
<filter-name>QuickFilter</filter-name>
<url-pattern>/quick.jsp</url-pattern>
</filter-mapping>
</web-app>
生命周期
init()初始化
服务器启动项目加载,创建filter对象,执行init方法(只执行一次)
doFilter()拦截
用户访问被拦截目标资源时,执行doFilter方法
destroy销毁
服务器关闭项目卸载时,销毁filter对象,执行destroy方法(只执行一次)
拦截路径
精准匹配
用户访问指定目标资源(/show.jsp)时,过滤器进行拦截
目录匹配
用户访问指定目录下(/user/*)所有资源时,过滤器进行拦截
后缀匹配
用户访问指定后缀名(*.html)的资源时,过滤器进行拦截
匹配所有
用户访问该网站所有资源(/*)时,过滤器进行拦截
listener
概述
监听器用来监听数据
常用监听器
ServletContextListener
可以监听应用是否启动了
ServletRequestListener
监听请求对象的创建和销毁
HttpSessionListener
监听会话对象的创建和销毁
用于用户流量的统计
ServletContextAttributeListener
监听到应用域中的属性存入,更改和移除是分别执行对应方法
ServletRequestAttributeListener
监听到请求域中的属性存入,更改和移除是分别执行对应方法
监听到请求域中的属性存入,更改和移除是分别执行对应方法
HttpSessionAttributeListener
监听到会话域中的属性存入,更改和移除是分别执行对应方法
不常用
HttpSessionBindingListener
有他替代上面的监听器,
用于对象和会话域的绑定
也可以对会话域解绑
用于对象和会话域的绑定
也可以对会话域解绑
HttpSessionActivaionListener
监听会话域中的数据钝化和活化
Java数据库
数据库
MySQL数据库
初级
数据库分类
DDL(数据库定义语言)
数据库操作
创建数据库
CREATE DATABASE 数据库名
切换数据库
USE 数据库名;
删除数据库
DROP DATABASE 数据库名;
查看所有数据库
SHOW DATABASES;
修改数据库字符集
ALTER DATABASE 数据库名 CHARACTER SET UTF8;
查看当前使用的数据库
SELECT DATABASE();
创建数据库并指定字符集
CREATE DATABASE 数据库名 CHARACTER SET UTF8
表操作
创建表
create table 表名(
id INT(11) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20),
english INT,
chinese INT,
math int
);
id INT(11) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20),
english INT,
chinese INT,
math int
);
查看数据库中所有表
SHOW TABLES;
查看表结构
DESC 表名;
表的删除
drop table 表名;
表的修改
添加列
ALTER TABLE 表名 ADD 列名 INT NOT NULL;
修改表的列名
ALTER TABLE exam CHANGE 列名 修改后的列名INT NOT NULL;
修改表名
RENAME TABLE 表名 TO 修改后的表名;
修改表的字符集
ALTER TABLE 表名 CHARACTER SET GBK;
删除列
ALTER TABLE 表名DROP 列名;
DML(数据库操作语言)
插入数据
INSERT INTO 表名(列1,列2,列3) VALUE(值1,值2,值3);
修改数据
全表修改
UPDATE 表名 SET 列名=值;
条件修改数据
UPDATE 表名 SET 修改的列名=值 WHERE 条件;
删除记录
删除全表数据
DELETE FROM 表名;
TRUNCATE TABLE 表名;
按照条件删除
DELETE FROM 表名 WHERE 条件;
DCL(数据控制语言)
登录
mysql -u 用户名-p 密码;
退出登录
exit;
DQL(数据库查询语言)
单表查询
简单查询
查询所有
SELECT * FROM 表名;
查询指定字段的表数据
SELECT 字段1,字段2 FROM 表名;
去重(DISTINCT)
SELECT DISTINCT 列名 FROM 表名;
四则运算
SELECT 列1+列2+列三 FROM 表名;
起别名
SELECT 列名 AS 别名 FROM 表名;
条件查询
简单条件查询
SELECT * FROM 表名 WHERE 列名>值
区间查询
SELECT * FROM 表名 WHERE 列名 BETWEEN 小值 AND 大值;
IN查询
SELECT * FROM 表名 WHERE 列名 IN(值1,值2,值3);
逻辑查询
and &&
or ||
模糊查询
SELECT * FROM 表名 WHERE 列名 LIKE '马%';
空值处理
IFNULL(空值替换)
SELECT 列名,列名+IFNULL(列名,默认值) FROM 表名;
null值判断
SELECT * FROM 表名 WHERE 列名 IS NULL;
not null判断
SELECT * FROM 表名 WHERE 列名 IS NOT NULL;
聚合函数
统计个数
SELECT COUNT(列名) FROM 表名;
最大值
SELECT MAX(age) FROM `user` WHERE sex='女';
最小值
SELECT MIN(math) FROM `user`;
平均数
SELECT AVG(age) FROM `user`;
求和
SELECT SUM(age) FROM `user`;
分组
HAVING和WHERE区别
# 分组之前用where (单独判断的时候使用)
# 分组之后使用having (通常连聚合函数一起使用)
如何使用having和where
# 统计每个地区的人数,小于20岁不参与统计,统计之后只显示人数大于2人的组
SELECT address,COUNT(id) FROM `user` WHERE age>20 GROUP BY address HAVING COUNT(id)>2;
# 分组之后使用having (通常连聚合函数一起使用)
如何使用having和where
# 统计每个地区的人数,小于20岁不参与统计,统计之后只显示人数大于2人的组
SELECT address,COUNT(id) FROM `user` WHERE age>20 GROUP BY address HAVING COUNT(id)>2;
分组查询GROUP BY
SELECT 返回结果,SUM(age) FROM 表名 GROUP BY 列名;
排序
正序排序(默认升序)ASC
SELECT * FROM 表名 WHERE 条件 ORDER BY 列DESC;
降序排序DESC
SELECT * FROM 表名 ORDER BY 排序的列 DASC,如果相同 第二条件的列ASC;
分页
SELECT * FROM `user` limit 0,5;
TCL(事务控制)
语法的分类
92语法
99语法
数据库的数据类型
常用的数据类型
字符类型
varchar(n)
可变的字符长度
常用
数值类型
int/integer
小数(浮点类型)
numerc()
大文本类型(不推荐使用)
text
最大65kb数据
longtext
最大可存储4gb数据
日期类型
year
取值范围1901-2155
1字节
data
1000-01-01到9999-12-31
用来存生日,订单日期
time
用来存储时分秒
一般不使用
datetime
用来存储年月日时分秒
timestamp
用来存储年月日时分秒(推荐使用)
子主题
中级
表关系
一对一
通常是用来拆分表,列太多,会使用一对一的关系,可以提高效率(不常用)
一对多
FOREIGN KEY (本表外键列名) REFERENCES 主键表(主表的主键列名);
多对多
多表查询
自然连接
两张表列同名,可以使用natural join来自动匹配列名相同的列
内连接(空值不显示)
隐式内连接
SELECT 表1.列名,表2.列名
FROM 表1,表2
WHERE 表1.关联列=表2.关联列;
FROM 表1,表2
WHERE 表1.关联列=表2.关联列;
显示内连接
SELECT emp.name,dept.name
FROM 表1
INNER JOIN 表2
ON 表1.关联列=表2.关联列;
FROM 表1
INNER JOIN 表2
ON 表1.关联列=表2.关联列;
外连接(空值,不符合条件的也显示)
左外连接
SELECT emp.name,dept.name
FROM 左表
LEFT JOIN 右表
ON 表1.关联列=表2.关联列;
FROM 左表
LEFT JOIN 右表
ON 表1.关联列=表2.关联列;
右外连接
SELECT emp.name,dept.name
FROM 左表
RIGHT JOIN 右表
ON 表1.关联列=表2.关联列;
FROM 左表
RIGHT JOIN 右表
ON 表1.关联列=表2.关联列;
子查询
单行单列
SELECT * FROM 表名 WHERE 列名=(SELECT MAX(列名) FROM 表名);
单行多列
SELECT * FROM 表名 WHERE 列名>(SELECT AVG(列名) FROM 表名);
多行多列
SELECT 需要查询列 FROM 表名 WHERE 列名=值 || 列名=值;
自连接
SELECT 本表1,本表2
FROM 本表1 别名 LEFT JOIN 本表2 别名
ON e1.mgr=e2.id;
FROM 本表1 别名 LEFT JOIN 本表2 别名
ON e1.mgr=e2.id;
union
将多条查询结果拼接到一起,并且去重
union all
直接累加,不去重(效率高)
等值条件
using(两张表相同的列名)
非等值条件
on条件(between xx and xx)
伪表查询
查询的结果当一张表来使用就是伪表查询
select * from emp join (select dept,age(sal) avg from emp group by dept) da
语法的分类
92语法
SELECT 表1.列名,表2.列名
FROM 表1,表2
WHERE 表1.关联列=表2.关联列;
FROM 表1,表2
WHERE 表1.关联列=表2.关联列;
99语法(推荐使用)
SELECT emp.name,dept.name
FROM 表1
INNER JOIN 表2
ON 表1.关联列=表2.关联列;
FROM 表1
INNER JOIN 表2
ON 表1.关联列=表2.关联列;
高级
MySQL函数
日期函数
获取系统当前日期时间、日期、时间
函数:NOW() | CURDATE() | CURTIME()
描述:获取系统当前日期时间、日期、时间
实例:SELECT NOW();
描述:获取系统当前日期时间、日期、时间
实例:SELECT NOW();
从日期中选择出年、月、日
函数:YEAR(DATE) | MONTH(DATE) | DAY(DATE)
描述:从日期中选择出年、月、日
实例:SELECT YEAR(NOW());
描述:从日期中选择出年、月、日
实例:SELECT YEAR(NOW());
返回月份的最后一天
函数:LAST_DAY(DATE)
描述:返回月份的最后一天
实例:SELECT LAST_DAY('2019-2-1');
描述:返回月份的最后一天
实例:SELECT LAST_DAY('2019-2-1');
计算起始日期 DATE 加(减) n 天的日期
函数:ADDDATE(DATE,n) | SUBDATE(DATE,n)
描述:计算起始日期 DATE 加(减) n 天的日期
实例:SELECT SUBDATE(NOW(),7);
描述:计算起始日期 DATE 加(减) n 天的日期
实例:SELECT SUBDATE(NOW(),7);
返回季度
函数:QUARTER(DATE)
描述:返回日期 DATE 是第几季节,返回 1 到 4
实例:SELECT QUARTER('2020-05-03');
描述:返回日期 DATE 是第几季节,返回 1 到 4
实例:SELECT QUARTER('2020-05-03');
计算相隔天数
函数:DATEDIFF(d1,d2)
描述:计算日期 d1->d2 之间相隔的天数
实例:SELECT DATEDIFF(NOW(),'1999-9-9');
描述:计算日期 d1->d2 之间相隔的天数
实例:SELECT DATEDIFF(NOW(),'1999-9-9');
按照要求显示日期
DATE_FORMAT(d,f)
描述:按表达式 f的要求显示日期 d
实例:SELECT DATE_FORMAT(NOW(),'%Y-%m-%d');
描述:按表达式 f的要求显示日期 d
实例:SELECT DATE_FORMAT(NOW(),'%Y-%m-%d');
字符串函数
拼接字符
函数:CONCAT(s1,s2...sn)
描述:字符串 s1,s2 等多个字符串合并为一个字符串
实例:SELECT CONCAT('传智播客','-','黑马程序员');
描述:字符串 s1,s2 等多个字符串合并为一个字符串
实例:SELECT CONCAT('传智播客','-','黑马程序员');
字节数
函数:CHAR_LENGTH(str)
描述:返回字符串 str 的字符数
实例:SELECT CHAR_LENGTH('传智播客');
描述:返回字符串 str 的字符数
实例:SELECT CHAR_LENGTH('传智播客');
字符数
函数:LENGTH(str)
描述:返回字符串 s 的字节数
编码:UTF8(一个中文字符占3个字节)
实例:SELECT LENGTH('itcast');
描述:返回字符串 s 的字节数
编码:UTF8(一个中文字符占3个字节)
实例:SELECT LENGTH('itcast');
转换大写
函数:UCASE(s) | UPPER(s)
描述:将字符串转换为大写
实例:SELECT UCASE('itcast');
描述:将字符串转换为大写
实例:SELECT UCASE('itcast');
转换小写
函数:LCASE(s) | LOWER(s)
描述:将字符串转换为小写
实例:SELECT LCASE('ITCAST');
描述:将字符串转换为小写
实例:SELECT LCASE('ITCAST');
获取字符开始位置
函数:LOCATE(s1,s)
描述:从字符串 s 中获取 s1 的开始位置
注意:从1开始
实例:SELECT LOCATE('ca','itcast');
描述:从字符串 s 中获取 s1 的开始位置
注意:从1开始
实例:SELECT LOCATE('ca','itcast');
去除空格
函数:TRIM(str) | LTRIM(str) | RTRIM(str)
描述:字符串去空格
实例:SELECT TRIM(' itcast ');
描述:字符串去空格
实例:SELECT TRIM(' itcast ');
替换
函数:REPLACE(s,s1,s2)
描述:将字符串 s2 替代字符串 s 中的字符串 s1
实例:SELECT REPLACE('itcast','ca','bbc');
描述:将字符串 s2 替代字符串 s 中的字符串 s1
实例:SELECT REPLACE('itcast','ca','bbc');
截取函数
函数:SUBSTR(s, start, length)
描述:从字符串 s 的 start 位置截取长度为 length 的子字符串
注意:从1开始
实例:SELECT SUBSTR('itcast',3,10);
描述:从字符串 s 的 start 位置截取长度为 length 的子字符串
注意:从1开始
实例:SELECT SUBSTR('itcast',3,10);
字符串的比较
函数:STRCMP(str1,str2)
描述:比较字符串大小,左大于右时返回1,左等于右时返回0,,左小于于右时返回-1,
实例:SELECT STRCMP('acc','abc');
描述:比较字符串大小,左大于右时返回1,左等于右时返回0,,左小于于右时返回-1,
实例:SELECT STRCMP('acc','abc');
数字函数
绝对值
ABS(x)
向上取整
CEIL(x)
向下取整
FLOOR(x)
取余
MOD(x,y)
随机数
RAND()
四舍五入
ROUND(x)
保留几位小数
TRUNCATE(x,y) 舍尾法
高级函数
case表达式
SELECT
CASE 字段
WHEN 判断条件1
THEN 希望的到的值1
WHEN 判断条件2
THEN 希望的到的值2
ELSE
前面条件都没有满足情况下得到的值
END
FROM
表名;
CASE 字段
WHEN 判断条件1
THEN 希望的到的值1
WHEN 判断条件2
THEN 希望的到的值2
ELSE
前面条件都没有满足情况下得到的值
END
FROM
表名;
-- 查询员工的工资等级
SELECT
emp.ename ,emp.salary ,
CASE s.grade
WHEN 1 THEN "努力赚钱"
WHEN 2 THEN '小康生活'
WHEN 3 THEN '娶媳妇'
ELSE "土豪..."
END AS "等级"
FROM
emp,salarygrade AS s
WHERE
emp.salary BETWEEN s.losalary AND s.hisalary;
SELECT
emp.ename ,emp.salary ,
CASE s.grade
WHEN 1 THEN "努力赚钱"
WHEN 2 THEN '小康生活'
WHEN 3 THEN '娶媳妇'
ELSE "土豪..."
END AS "等级"
FROM
emp,salarygrade AS s
WHERE
emp.salary BETWEEN s.losalary AND s.hisalary;
if表达式
-- 语法
IF(条件,结果1,结果2)
IF(条件,结果1,结果2)
-- 工资+奖金大于20000的员工 显示家有娇妻,否则显示单身狗
SELECT
ename,
salary + IFNULL(bonus,0) AS "收入",
IF(salary + IFNULL(bonus,0)>20000,"家有娇妻","单身狗") AS "现状"
FROM
emp;
SELECT
ename,
salary + IFNULL(bonus,0) AS "收入",
IF(salary + IFNULL(bonus,0)>20000,"家有娇妻","单身狗") AS "现状"
FROM
emp;
加密函数
MD5 加密函数
MD5(值);
INSERT INTO account VALUES(1,"zhangsan",MD5("123456"),9.9);
索引
慢查询日志
查询各个变量(慢查询相关配置)
show variables like '%query%'
打开慢查询日志
set global slow_query_log = on;
设置慢查询日志时间节点
set long_query_time=时间;
慢查询日志路径
D:\mysql-5.7.27-winx64\data\LaoSun-slow.log
索引分类
普通索引
仅加速查询 index
唯一索引
加速查询 + 列值唯一 unique (既是约束也是索引)
主键索引
加速查询 + 列值唯一 + 非空 (既是约束也是索引)
组合索引
多列值组成一个索引
索引
创建索引需要注意的情况
创建索引的原则
1. 字段内数据的辨识度不能低于70%
2. 在经常需要 搜索 的列上建索引
3. 在经常需要 连接 的列上建索引(外键字段)
4. 在经常排序的列上创建索引
5. 用的时候创建索引,不用一开始就创建索引
6. 不是索引越多越好,因为索引的建立和维护都是需要耗时的
索引失效的情况
1. 模糊查询的时候,若在索引列上的左边加上了"%" ,索引失效
2. 使用or查询,其中一个条件上没有索引 也会降低查询效率
3. 在索引列上进行计算,会使索引失效
4. 使用 !=、 <> 、is not null、not 等也会失效 尽量不要出现null
修改表(创建索引)
主键索引
-- 添加一个主键,这意味着索引值必须是唯一的,且不能为NULL
alter table 表名 add primary key(列名)
alter table 表名 add primary key(列名)
唯一索引
-- 添加唯一索引(除了NULL外,NULL可能会出现多次)
alter table 表名 add unique(列名)
alter table 表名 add unique(列名)
普通索引
-- 添加普通索引,索引值可以出现多次。
alter table 表名 add index(列名)
alter table 表名 add index(列名)
删除索引
直接删除
drop index 索引名 on 表名;
修改表时删除(掌握)
alter table 表名 drop index 索引名字;
删除主键
alter table 表名 drop primary key;
数据库优化
数据库存储引擎
MyISAM存储引擎
msyql5.5版本之前的
不支持事务、表锁设计,支持全文搜索
缓冲池只缓存索引文件,不缓存数据文件
MyISAM存储引擎表由MYD(存放数据文件)和MYI(存放索引文件)组成
不支持事务、表锁设计,支持全文搜索
缓冲池只缓存索引文件,不缓存数据文件
MyISAM存储引擎表由MYD(存放数据文件)和MYI(存放索引文件)组成
InnoDB存储引擎
msyql5.5(含)版本之后的使用
支持持事务
行锁设计
支持外键
支持非锁定读
避免幻读现象
支持持事务
行锁设计
支持外键
支持非锁定读
避免幻读现象
Memory(记忆,内存)存储引擎
表中的数据存放在内存,数据库重启或崩溃表中的数据都会消失
适合存储临时数据的临时表,以及数据仓库的纬度表
默认哈希索引
只支持表锁,并发性能差,不支持TEXT和BLOB列类型
存储变长字段时按照定长字段方式,浪费内存(eBay工程师给出了patch解决方案。
适合存储临时数据的临时表,以及数据仓库的纬度表
默认哈希索引
只支持表锁,并发性能差,不支持TEXT和BLOB列类型
存储变长字段时按照定长字段方式,浪费内存(eBay工程师给出了patch解决方案。
sql注入问题
会引发sql注入问题
123') OR ('1=1
触发器
就是一个表中的数据 发生改变是,会触发另一个表中的数据
事件
就是一个“事件调度器”,有点像计划任务(但是他可用精确到每秒执行一个任务)
JDBC
Java 框架
Mybatis框架
mybatis
单表查询
单条件查询
数据库列名与字段名不一样
resultMap
<resultMap id="userResultMap" type="com.laosum.domain.User">
<id column="uid" property="id"></id>
<result column="name" property="username"/>
<result column="bir" property="birthday"/>
<result column="gender" property="sex"/>
<result column="addr" property="address"/>
</resultMap>
<select id="findAll" resultMap="userResultMap">
select id uid,username name,birthday bir,sex gender,address addr from `user`
</select>
<id column="uid" property="id"></id>
<result column="name" property="username"/>
<result column="bir" property="birthday"/>
<result column="gender" property="sex"/>
<result column="addr" property="address"/>
</resultMap>
<select id="findAll" resultMap="userResultMap">
select id uid,username name,birthday bir,sex gender,address addr from `user`
</select>
数据库列名与字段名一样
resultType
多条件查询
第一种方式
使用 `#{arg0}-#{arg1}` 或者 `#{param1}-#{param2}` 获取参数
多个参数parameterType不用写
<select id="findByIdAndUsername1" resultType="com.itheima.domain.User">
select * from user where id = #{param1} and username = #{param2}
</select>
select * from user where id = #{param1} and username = #{param2}
</select>
第二种方式
使用注解`@Param()`注解获取参数
在接口中写@Param("id")
List<User> findByIdAndUsername2(@Param("id") Integer id, @Param("username") String username);
<select id="findByIdAndUsername2" resultType="com.itheima.domain.User">
select * from user where id = #{id} and username = #{username}
</select>
select * from user where id = #{id} and username = #{username}
</select>
第三种方式
使用实体对象传递参数
List<User> findByIdAndUsername3(User user);
@Test
public void test02() throws Exception{
SqlSession sqlSession = MybatisUtils.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(41);
user.setUsername("老王");
List<User> users = mapper.findByIdAndUsername(user);
users.forEach(System.out::println);
//关闭资源
MybatisUtils.release(sqlSession);
}
public void test02() throws Exception{
SqlSession sqlSession = MybatisUtils.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(41);
user.setUsername("老王");
List<User> users = mapper.findByIdAndUsername(user);
users.forEach(System.out::println);
//关闭资源
MybatisUtils.release(sqlSession);
}
模糊查询
List<User> findLikeUsername(String username);
CONCAT(CONCAT('%',#{username}),'%')
<select id="findLikeUsername" resultType="com.itheima.domain.User">
SELECT * FROM `user` WHERE username LIKE CONCAT(CONCAT('%',#{username}),'%')
</select>
SELECT * FROM `user` WHERE username LIKE CONCAT(CONCAT('%',#{username}),'%')
</select>
返回主键id
仅支持自动增长的数据库
<!--用户保存
useGeneratedKeys="true" 开启主键返回功能
keyProperty="id" 指定数据库主键字段返回到实体哪个属性
有局限性,不支持oracle数据库
-->
<insert id="save" useGeneratedKeys="true" keyProperty="id">
INSERT INTO `user` VALUES(NULL,#{username},#{birthday},#{sex},#{address})
</insert>
useGeneratedKeys="true" 开启主键返回功能
keyProperty="id" 指定数据库主键字段返回到实体哪个属性
有局限性,不支持oracle数据库
-->
<insert id="save" useGeneratedKeys="true" keyProperty="id">
INSERT INTO `user` VALUES(NULL,#{username},#{birthday},#{sex},#{address})
</insert>
支持所有类型的数据库
<!--用户保存
SELECT LAST_INSERT_ID() 用于获取上一条新增记录的主键
selectKey 标签
keyColumn:指定数据库主键字段
keyProperty:指定实体主键属性
resultType:指定实体主键类型
order:表示 selectKey 标签 在insert语句之前执行还是之后执行
before :之前
after :之后
-->
<insert id="save">
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO `user` VALUES(NULL,#{username},#{birthday},#{sex},#{address})
</insert>
SELECT LAST_INSERT_ID() 用于获取上一条新增记录的主键
selectKey 标签
keyColumn:指定数据库主键字段
keyProperty:指定实体主键属性
resultType:指定实体主键类型
order:表示 selectKey 标签 在insert语句之前执行还是之后执行
before :之前
after :之后
-->
<insert id="save">
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO `user` VALUES(NULL,#{username},#{birthday},#{sex},#{address})
</insert>
`${}` 与 `#{}` 区别(面试题)
* #的特点:
# 表示占位符,相当于jdbc中的?底层工作的是PrepareadStatement对象,SQL只编译一次,而且没有SQL注入问题
# 当传入的参数为一个简单类型时,#{}内容可以随便写,建议写成接口中方法的参数名称
# 当传入的参数为一个对象类型时,#{}写对象属性
* $的特点:
$ 表示字符串拼接,底层工作的是Statement对象,sql语句每次都会重新编译,而且存在SQL注入问题
$ 当传入的参数为一个简单类型时,${} 只能写 value
补充:TextSqlNode.java 源码可以证明
$ 当传入的参数为一个对象类型时,${} 写对象属性
# 表示占位符,相当于jdbc中的?底层工作的是PrepareadStatement对象,SQL只编译一次,而且没有SQL注入问题
# 当传入的参数为一个简单类型时,#{}内容可以随便写,建议写成接口中方法的参数名称
# 当传入的参数为一个对象类型时,#{}写对象属性
* $的特点:
$ 表示字符串拼接,底层工作的是Statement对象,sql语句每次都会重新编译,而且存在SQL注入问题
$ 当传入的参数为一个简单类型时,${} 只能写 value
补充:TextSqlNode.java 源码可以证明
$ 当传入的参数为一个对象类型时,${} 写对象属性
多表查询
动态sql
where标签
配合if标签使用
if标签
<if test=“条件判断”>
查询条件拼接
</if>
查询条件拼接
</if>
多表查询
一对一
xml文件
resultMap="orderAndUser"
使用的是association标签映射
<id column="uid" property="id"/>
<result column="username" property="username"/>
<!--
column数据库的列名
property实体类的变量
-->
<!--
column数据库的列名
property实体类的变量
-->
一对多
xml文件
使用的是association标签映射
javaType和ofType区别
javatype是POJO类型,包装类型
oftype是list的类型来使用的
多对多
嵌套查询
加载策略
延迟加载
延迟加载
当用户查询订单是,什么时候使用数据的时候,什么时候加载
一对多
多对对
立即加载
查询用户订单的时候立即查出订单
一对一使用
多表查询会直接执行
分页插件
PageHelper
1.Maven依赖
<!--分页插件PageHelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>3.2</version>
</dependency>
2.mybatis中的配置信息
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
<property name="autoRuntimeDialect" value="true"/>
</plugin>
</plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
<property name="autoRuntimeDialect" value="true"/>
</plugin>
</plugins>
3. 如何使用
必须放到一起
// 开启分页插件
PageHelper.startPage(pageNum, pageSize);
// 查询数据
List<Route> list=mapper.findAll();
// 将数据放到分页对象
PageInfo<Route> routePageInfo = new PageInfo<Route>(list);
// 开启分页插件
PageHelper.startPage(pageNum, pageSize);
// 查询数据
List<Route> list=mapper.findAll();
// 将数据放到分页对象
PageInfo<Route> routePageInfo = new PageInfo<Route>(list);
Ipage
Maven
初级
核心功能
依赖管理
项目构建
目录结构
bin
存放了 maven 的命令,比如我们前面用到的 mvn tomcat7:run
boot
存放了一些 maven 本身的引导程序,如类加载器等
conf
存放了 maven 的一些配置文件,如 setting.xml 文件
lib
存放了 maven 本身运行所需的一些 jar 包
常用命令
clean
删除target目录及内容
compile
编译命令,生成target
test
执行 src/test/java 下单元测试类,并编译为class文件
package
打包工具
java工程执行package打成jar包
web工程打成war包
java工程执行package打成jar包
web工程打成war包
install
将maven工程打成jar包或war包,并发布到本地仓库
deploy
将jar或war包部署到私服中
打包方式修改
<packaging>war</packaging>
可以改成jar
常见标签
Scope(作用范围)
compile
所有
有依赖传递
provided
编译期和测试期
没有依赖传递
runtime
运行期和测试期
有依赖传递
test
测试期
没有依赖传递
system
compile, test
有依赖传递
optional
表示其他项目依赖本项目时,是否依赖传递
true不传递
false传递
systemPath
systemPath
当依赖包在本地而非仓库时,sytemPath指出了jar包的路径
高级
依赖传递
依赖冲突
依赖调解原则
1. 第一声明者优先原则
2.路径近者优先原则
锁定版本
1.提取版本号
<properties>
<mysql.version>5.1.47</mysql.version>
</properties>
<mysql.version>5.1.47</mysql.version>
</properties>
2.锁定版本
<!--版本锁定-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
依赖排除
<exclusions>
<exclusion>
<artifactId>tomcat-jdbc</artifactId>
<groupId>org.apache.tomcat</groupId>
</exclusion>
</exclusions>
<exclusion>
<artifactId>tomcat-jdbc</artifactId>
<groupId>org.apache.tomcat</groupId>
</exclusion>
</exclusions>
搭建私服
nexus
用户名密码是amin/admin123
nexus四种仓库
hosted
宿主仓库
自己工程的jar
proxy
代理仓库
第三方下载的jar
group
组仓库
hosted+proxy
virtual
虚拟仓库
不使用了
如何将项目发布到私服
D:\devtools\apache-maven-3.5.2\conf\settings.xml
<server>
<id>releases</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>thirdparty</id>
<username>admin</username>
<password>admin</password>
</server>
<id>releases</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>thirdparty</id>
<username>admin</username>
<password>admin</password>
</server>
配置项目pom.xml
<distributionManagement>
<repository>
<id>releases</id>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
diploy打包发布到私服
如何下载到jar
1.配置setting.xml文件
<profile>
<!--profile的id-->
<id>dev</id>
<repositories>
<repository>
<!--仓库id,repositories可以配置多个仓库,保证id不重复-->
<id>nexus</id>
<!--仓库地址,即nexus仓库组的地址-->
<url>http://localhost:8081/nexus/content/groups/public/</url>
<!--是否下载releases构件-->
<releases>
<enabled>true</enabled>
</releases>
<!--是否下载snapshots构件-->
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<!-- 插件仓库,maven的运行依赖插件,也需要从私服下载插件 -->
<pluginRepository>
<!-- 插件仓库的id不允许重复,如果重复后边配置会覆盖前边 -->
<id>public</id>
<name>Public Repositories</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
</pluginRepository>
</pluginRepositories>
</profile>
<!--profile的id-->
<id>dev</id>
<repositories>
<repository>
<!--仓库id,repositories可以配置多个仓库,保证id不重复-->
<id>nexus</id>
<!--仓库地址,即nexus仓库组的地址-->
<url>http://localhost:8081/nexus/content/groups/public/</url>
<!--是否下载releases构件-->
<releases>
<enabled>true</enabled>
</releases>
<!--是否下载snapshots构件-->
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<!-- 插件仓库,maven的运行依赖插件,也需要从私服下载插件 -->
<pluginRepository>
<!-- 插件仓库的id不允许重复,如果重复后边配置会覆盖前边 -->
<id>public</id>
<name>Public Repositories</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
</pluginRepository>
</pluginRepositories>
</profile>
<activeProfiles>
<activeProfile>dev</activeProfile>
</activeProfiles>
<activeProfile>dev</activeProfile>
</activeProfiles>
本地jar放到maven中
mvn install:install-file -Dfile=c:\xxx-{version}.jar -DgroupId=com.google.code -DartifactId=kaptcha -Dversion={version} -Dpackaging=jar
Redis
面试题
redis是多线程还是多线程的
redis是单线程模型,指的是redis命令的核心模块是单线程的,而不是redis实例就一个线程
redis的瓶颈并不是在cpu,而是在内存和网络,在redis4.0之后就有多线程的概念,比如过redis多线程在后台删除对象
前几天Redis6发布了,他这里的多线程说的是,指的是网络io处理的多线程,执行命令还是单线程的
数据类型
字符串
列表
集合
散列表
有序集合
数据持久化
AOF
默认的持久化机制
RDB
日志文件备份
失效时间(失效后删除)
xx
key存在才能成功
nx
key不存在才能设置过期时间
redis实现分布式锁
git
Spring 框架
概述
三层模型
Controller层
作用:接收Servlet(接收请求,响应数据,地址配置,页面转发)
对应的框架:Spring MVC
Service层
作用:处理业务逻辑的
没有对应的框架
Dao层
作用:对数据库做操作
对应的框架:Mybatis
spring集成第三方框架
MVC框架
SpringMvc
持久层框架
Mybatis
Hibernate
缓存
redis
ehcache
定时任务
spring-task
quartz
校验框架
hibernate validator
Spring Security
spring自带服务
Mail右键发送
定时任务处理
消息处理(异步处理)
Spring模块划分
Test
Spring Code
Beans
Core
Context
SpEL
Spring AOP和监视器
消息传递
数据访问/集成
数据访问/集成层是由JDBC、ORM、OXM、JMS和事务模块组成。
Spring Web
Web层由spring-web、spring-webmvc、spring-websocket和spring-webmvc-portlet模块组成。
常用工具类的使用
BeanUtils
对象封装参数的工具类
IOC(控制反转)
简介
控制
指的是,谁来负责对象的创建和装配工作
反转
之前程序员手动在类中控制对象实例的创建,现在反转到IOC容器去创建实例和装配工作
总结:解决了耦合性,可以让我们不用关注框架的搭建上,而是更多的时间让我们关注在业务代码的实现上
BeanFactory
ApplicationContext
ClassPathXmlApplicationContext
类路径 下加载配置文件
FlieSystemXmlApplicationContext
系统文件路径下查找文件
AnnotationApplicationContext
读取注解配置类
BeanFactory下getBean方法
getBean(String name)
更具名字(id)来获取对象的实例
public <T>getBean(Class<T> requiredType)
更具类型来获取对象的实例
public <T> getBean(String name,Class<T> requiredType)
更具名字和类型来获取对象的实例
如何使用
1.让Spring解析xml配置文件,初始化Ioc容器
new ClassPathXmlApplicationContext("applicationContext.xml")
2. 从Ioc容器中获取service实现
app.getBean("username")
3.测试用户功能
userService.save();
Spring的配置文件
Xml中
<Bean id="userDao" class="com.xxx.xxx.impl.xxx">
id
此对象在Ioc容器中的唯一标识
class
此对象的全限定类名
作用范围和生命周期
scope(范围)
singleton
单例对象
创建:在ioc容器初始化时
销毁:在ioc关闭时
prototype
多例对象
创建:什么时候创建,ioc就什么时候创建
销毁:当对象失去引用的时候也就是GC垃圾回收的时候
DI注入
其实就是给对象属性赋值的过程,通过spring完成依赖注入
Bean依赖注入方式
构造方法注入
<constructor-arg>
name属性:属性名称
value:注入的普通属性值
ref:注入对象引用值
name属性:属性名称
value:注入的普通属性值
ref:注入对象引用值
set方法注入
name:set方法的属性名 setUserDao() -> UserDao -> userDao 【通常情况下与变量的名称一致】
value:传递的简单数据类型(string、int、double)
ref:传递的引用数据类型(必须在ioc容器中)
value:传递的简单数据类型(string、int、double)
ref:传递的引用数据类型(必须在ioc容器中)
P命名空间注入
本质上还是set方法,只不过是简化了xml的配置
Bean依赖注入的数据类型
简单数据类型
直接声明就行
<!--user,交给ioc容器-->
<bean id="user" class="com.itheima.pojo.User">
<property name="id" value="33"/>
<property name="username" value="lucy"></property>
</bean>
<bean id="user" class="com.itheima.pojo.User">
<property name="id" value="33"/>
<property name="username" value="lucy"></property>
</bean>
引用数据类型
list
<property name="list">
<list>
<value>jack</value>
<value>lucy</value>
<ref bean="user"></ref>
</list>
</property>
set
<property name="set">
<set>
<value>呵呵</value>
<value>哈哈</value>
<ref bean="user"></ref>
</set>
</property>
<set>
<value>呵呵</value>
<value>哈哈</value>
<ref bean="user"></ref>
</set>
</property>
array
<property name="array">
<array>
<value>安妮</value>
<value>安其拉</value>
<ref bean="user"></ref>
</array>
</property>
<array>
<value>安妮</value>
<value>安其拉</value>
<ref bean="user"></ref>
</array>
</property>
集合数据类型
map
<property name="map">
<map>
<entry key="k1" value="v1"></entry>
<entry key="k2" value="v2"></entry>
<entry key="user1" value-ref="user"></entry>
</map>
</property>
<map>
<entry key="k1" value="v1"></entry>
<entry key="k2" value="v2"></entry>
<entry key="user1" value-ref="user"></entry>
</map>
</property>
properties
<property name="props">
<props>
<prop key="k3">v3</prop>
<prop key="k4">v4</prop>
</props>
</property>
<props>
<prop key="k3">v3</prop>
<prop key="k4">v4</prop>
</props>
</property>
配置文件模块方法
并列加载
在new的时候,在后面可以多加几个
主从配置
使用Import 中resource加载配置文件
Dbutils
Dao代码的工具类
概述
底层封装了JDBC技术
核心对象
new QueryRunner(DataSource dataSource)
int update(); 执行增。删。改
<T> query(); 执行查询语句
常用注解
注意:
使用注解开发,必须开启组件扫描
@Component
不属于三层模型的使用
@Repository
DAO层
@Service
Service层
@Controller
web层
依赖注入DI
@AutoWired
按照类型注入
@Qualifier
在同类型的基础上,在根据id查找
@Resource
相当于@AutWired+@Qualifier
注解补充
@Scope
作用是:定义这个类是单例,多例对象
在类上写
@Scope("singleton")
单例
@Scope("prototype")
多例
生命周期用的注解
在方法上写
@postConstruct
初始化方法
@PreDestroy
销毁方法
@Value
可以读取配置文件的key
1.配置文件
2.加载配置文件
<context:property-placeholder location="classpath:jdbc.properties">
3.在属性上加上@Value("${jdbc.driver}")
注解类的配置
@Configuration
相当于applicationContext.xml
@Bean
加载第三方类,交给ioc容器
@PropertySource("classpath:xxx.properties")
加载properties文件
@ComponentScan
<context:compont-scan base-package="cn.laosum">
注解扫描
@Import
加载一个配置类
ThreadLocal初步理解
概述
他就是一个线程,但是他是一个线程隔离的,相当于一把锁,其他的线程不能访问
然后我们同过这把锁,然后绑定连接对象,然后实现线程的共享连接对象
AOP(面向切面编程)
概述
AOP的思想是:不用修改源代码的基础上,就对功能进行增强,就是AOP
这种思想的实现技术是:动态代理
Jdk的动态代理
cglab的动态代理
Spring MVC框架
简介
这个框架主要是为了简化web层的开发
SpringMVC
通过对Servlet的封装,解决了Servlet繁琐的代码
通过对Servlet的封装,解决了Servlet繁琐的代码
使用它之后web部分就分为两个部分
前端控制器
主要是负责接收参数
接受请求
返回页面的数据
响应数据
处理器
处理业务和业务层的调用
由程序员来写
如何使用
applicationContext.xml开启mvc的注解支持
xml
<mvc:annotation-driven/>
在web.xml中配置前端控制器
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
创建一个类,将类交给ioc容器,@Controller
编写一个方法用String为返回值
/WEB-INF/page/success.jsp
在方法上加一个注解
@RequestMapper
相当于@WebServlet
SpringMVC的执行流程
1.用户发送请求到前端控制器映射器
2.前端控制器请求获取处理器映射器
3.处理器映射器返回数据给前端控制器
4.前端控制器发送请求执行处理器
5.调用处理器,处理业务逻辑
6.返回数据和逻辑视图给处理器适配器
7.处理器适配器返回数据和逻辑视图返回给前端控制器
8.前端控制器根据逻辑视图寻找物理视图,将数据发送给视图解析器进行解析
9.将解析完成的数据返回给前端控制器
10.将数据渲染到物理视图
11.返回响应给用户
SpringMVC的三大组件
处理器映射器(HandlerMapping)
负责根据URL寻找对应的处理器方法
处理器适配器(HandlerAdpter)
负责真正的去调用某个处理器方法
视图解析器(ViewResolver)
负责将逻辑视图转换成物理视图
常用注解
@RequestMapper
value/path
建立url和方法的映射
一个方法可以写多个地址
params
限定前端必须传递参数
method
限定请求方式:get/post/put/delete
同步交互
接收请求
简单类型
直接传递参数就行,但是传递的参数必须和前端的值一样
例子
<form action="/simpleParam" method="post">
姓名:<input type="text" name="username"> <br>
年龄:<input type="text" name="age"> <br>
<input type="submit" value="简单类型提交">
</form>
姓名:<input type="text" name="username"> <br>
年龄:<input type="text" name="age"> <br>
<input type="submit" value="简单类型提交">
</form>
@RequestMapping("/simpleParam")
public String simpleParam(String username,Integer age){ // request.getParameter("username")
System.out.println(username);
System.out.println(age);
return "success";
}
public String simpleParam(String username,Integer age){ // request.getParameter("username")
System.out.println(username);
System.out.println(age);
return "success";
}
对象类型
原理:
调用:request.getParameterMap()
调用:beanUtils工具类封装User对象
对象类型和传递的参数类型名字必须一样
数组类型
原理
request.getParameterValues("hobbies")
例子
<form action="/arrayParam" method="post">
抽烟:<input type="checkbox" name="hobbies" value="1"> <br>
喝酒:<input type="checkbox" name="hobbies" value="2"> <br>
烫头:<input type="checkbox" name="hobbies" value="3"> <br>
<input type="submit" value="数组类型提交">
</form>
抽烟:<input type="checkbox" name="hobbies" value="1"> <br>
喝酒:<input type="checkbox" name="hobbies" value="2"> <br>
烫头:<input type="checkbox" name="hobbies" value="3"> <br>
<input type="submit" value="数组类型提交">
</form>
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobbies){ // request.getParameterValues("hobbies")
System.out.println(Arrays.toString(hobbies));
return "success";
}
public String arrayParam(String[] hobbies){ // request.getParameterValues("hobbies")
System.out.println(Arrays.toString(hobbies));
return "success";
}
集合类型
@RequestParam
接收集合数据
例子
<form action="/listParam" method="post">
陪吃:<input type="checkbox" name="hobbies" value="1"> <br>
陪喝:<input type="checkbox" name="hobbies" value="2"> <br>
配shui:<input type="checkbox" name="hobbies" value="3"> <br>
<input type="submit" value="集合类型提交">
</form>
陪吃:<input type="checkbox" name="hobbies" value="1"> <br>
陪喝:<input type="checkbox" name="hobbies" value="2"> <br>
配shui:<input type="checkbox" name="hobbies" value="3"> <br>
<input type="submit" value="集合类型提交">
</form>
@RequestMapping("/listParam")
public String listParam(@RequestParam List<String> hobbies){
System.out.println(hobbies);
return "success";
}
public String listParam(@RequestParam List<String> hobbies){
System.out.println(hobbies);
return "success";
}
中文乱码过滤器
<!--乱码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
日期格式
普通日期格式
@DateTimeFormat(pattern="yyyy-MM-dd")
自定义格式转换器
常用注解
@RequestParam
required
前端必须提供参数,否则会报错
defaultValue
给参数提供默认值
name
解决前后端参数名不一致
@RequestHeader
获取请求头信息
写原生Servlet代码
@RequestMapping("/servletApi")
public void servletApi(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws ServletException, IOException {
String useranme = request.getParameter("useranme");
System.out.println(useranme);
String ageStr = request.getParameter("age");
Integer age = Integer.parseInt(ageStr);
System.out.println(age);
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
}
public void servletApi(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws ServletException, IOException {
String useranme = request.getParameter("useranme");
System.out.println(useranme);
String ageStr = request.getParameter("age");
Integer age = Integer.parseInt(ageStr);
System.out.println(age);
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
}
文件上传
文件上传的三要素
请求方式必须是post
表单提交方式为:
entype="multipart/form-data"
entype="multipart/form-data"
必须有一个文件的类型
如何使用
SpringMVC内置了一个文件上传
前提条件是文件类型必须是MultipartFile 参数必须和name的属性名一样
子主题
1.导入坐标
<!--文件上传工具包-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
2.配置
<!--
文件上传解析器
id="multipartResolver" 这个值是固定的
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--
限制文件大小,单位B
1KB = 1024B
1MB = 1024KB
-->
<property name="maxUploadSize" value="1000000"></property>
</bean>
文件上传解析器
id="multipartResolver" 这个值是固定的
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--
限制文件大小,单位B
1KB = 1024B
1MB = 1024KB
-->
<property name="maxUploadSize" value="1000000"></property>
</bean>
3.前端三要素
<form action="/fileUpload" method="post" enctype="multipart/form-data">
姓名:<input type="text" name="username"> <br>
头像:<input type="file" name="picFile"> <br>
<input type="submit" value="提交">
</form>
姓名:<input type="text" name="username"> <br>
头像:<input type="file" name="picFile"> <br>
<input type="submit" value="提交">
</form>
4.方法接收文件
@RequestMapping("/fileUpload")
public String fileUpload(String username, MultipartFile picFile) throws IOException {
System.out.println(username);
System.out.println(picFile.getOriginalFilename()); // 原始文件名
picFile.transferTo(new File("E:\\"+picFile.getOriginalFilename())); // 文件io复制,报错文件
return "success";
}
public String fileUpload(String username, MultipartFile picFile) throws IOException {
System.out.println(username);
System.out.println(picFile.getOriginalFilename()); // 原始文件名
picFile.transferTo(new File("E:\\"+picFile.getOriginalFilename())); // 文件io复制,报错文件
return "success";
}
页面跳转
简单方式
@RequestMapper("/quick")
public String quick(){
sout("xxx");
return "success";
}
public String quick(){
sout("xxx");
return "success";
}
<bean class="InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page"/>
<property name="suffix" value=".jsp"/>
</bean>
<property name="prefix" value="/WEB-INF/page"/>
<property name="suffix" value=".jsp"/>
</bean>
原生Servlet的API
异步交互
通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中@PathVariable(“xxx“)
转发
页面跳转
简单方式
@RequestMapping("/quick")
public String quick() {
System.out.println("quick启动了");
return "success";
}
public String quick() {
System.out.println("quick启动了");
return "success";
}
原生api
@RequestMapping("/servletApi")
public void servletApi(HttpServletRequest req, HttpServletResponse resp, HttpSession session) throws ServletException, IOException {
req.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(req, resp);
}
public void servletApi(HttpServletRequest req, HttpServletResponse resp, HttpSession session) throws ServletException, IOException {
req.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(req, resp);
}
forward
@RequestMapping("/forwardApi")
public String forwardApi() {
return "forward:/WEB-INF/pages/error.jsp";
}
public String forwardApi() {
return "forward:/WEB-INF/pages/error.jsp";
}
携带数据
原生api
@RequestMapping("/requestApi")
public void requestApi(HttpServletRequest req, HttpServletResponse resp, HttpSession session) throws ServletException, IOException {
req.setAttribute("message", "哈哈哈你真好");
req.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(req, resp);
}
public void requestApi(HttpServletRequest req, HttpServletResponse resp, HttpSession session) throws ServletException, IOException {
req.setAttribute("message", "哈哈哈你真好");
req.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(req, resp);
}
ModelAndView
@RequestMapping("/quick")
public ModelAndView quick(ModelAndView andView) {
andView.addObject("message", "你真丑。。。。");
andView.setViewName("success");
return andView;
}
public ModelAndView quick(ModelAndView andView) {
andView.addObject("message", "你真丑。。。。");
andView.setViewName("success");
return andView;
}
Model
@RequestMapping("/quick")
public String quick(Model andView) {
andView.addAttribute("message", "你真丑。。。。");
return "success";
}
public String quick(Model andView) {
andView.addAttribute("message", "你真丑。。。。");
return "success";
}
重定向
关键字
servlet原生 API
redirect关键字
ajax异步交互
@RequestBody
用于接收前端传递的请求体中的json数据, 并可以自动转换封装进指定的对象中。
@ResponseBody
用于将controller方法返回的对象通过转换器转换为指定的格式(通常为json)之后,写入到response对象的响应体中。
通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中@PathVariable(“xxx“)
@PathVariable
resful风格
@GetMapping
查询
@PostMapping
添加
@PutMapping
修改
@DeleteMapping
删除
异常处理
第一种
自定义异常处理器
定义@Component交给IOC容器
实现HandlerExceptionResovler
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView modelAndView = new ModelAndView();
// 将错误信息,写入到日志中
modelAndView.addObject("error", "sorry,服务器繁忙,请稍后重试~~~");
modelAndView.setViewName("forward:/WEB-INF/error.jsp");
return modelAndView;
}
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView modelAndView = new ModelAndView();
// 将错误信息,写入到日志中
modelAndView.addObject("error", "sorry,服务器繁忙,请稍后重试~~~");
modelAndView.setViewName("forward:/WEB-INF/error.jsp");
return modelAndView;
}
第二种
@ControllerAdvice
@ControllerAdvice
public class MyControllerAdvice {
@ExceptionHandler(Exception.class)
public String ExceptionHandler(Exception ex,Model model){
ex.printStackTrace();
model.addAttribute("error", "服务器繁忙...");
return "forward:/WEB-INF/error.jsp";
}
}
public class MyControllerAdvice {
@ExceptionHandler(Exception.class)
public String ExceptionHandler(Exception ex,Model model){
ex.printStackTrace();
model.addAttribute("error", "服务器繁忙...");
return "forward:/WEB-INF/error.jsp";
}
}
第三种(解决页面404问题)
<!--捕获并处理异常-->
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/404.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/404.jsp</location>
</error-page>
拦截器
public class MyIntercepter1 implements HandlerInterceptor {
/*
预处理方法:拦截请求
参数:
request
response
handler:用户访问的目标方法
返回结果:
true:放行
false:拦截
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("preHandle1");
return true;
}
}
/*
预处理方法:拦截请求
参数:
request
response
handler:用户访问的目标方法
返回结果:
true:放行
false:拦截
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("preHandle1");
return true;
}
}
/*
预处理方法:拦截请求
参数:
request
response
handler:用户访问的目标方法
返回结果:
true:放行
false:拦截
*/
预处理方法:拦截请求
参数:
request
response
handler:用户访问的目标方法
返回结果:
true:放行
false:拦截
*/
SSM整合
Spring Boot框架
概述
springboot为我们简化了很多的操作和配置,他的理念是约定大于配置,我们只要按照他的规范,来编写代码就行了
Springboot的功能
版本锁定
起步依赖
自定配置
如果我们想自己配置一些信息
自定义配置文件
SpringBoot的配置文件
SpringBoot启动依次加载:yml、yaml、properties
application*.yml
applicatino*.yaml
application.properties
Mybatis Plus
如何使用
1.继承BaseMapper<类名>
2.在实体类映射对象字段的表名,@TableName("tb_user")
3.但是插入数据后id不会自增,会写入一个随机的数,可以使用@TableId()
分页拦截器
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
Dubbo服务管理
Zookeeper注册中心
Docker
小项目
Java常用缩写单词
HTML
超文本标记语言
Http
超文本传输协议
TCP
传输控制协议
UDP
用户数据报协议
RPC
远程过程调用
OOP
面向对象
OOF
面向函数编程
DOM
文档对象模型
BOM
文档对象模型
MIME
Context-type: "xxx/xxx"
多用途互联网邮件扩展类型(网络传输的文件类型)
多用途互联网邮件扩展类型(网络传输的文件类型)
RBAC
基于角色的权限控制
设计模式
装饰设计模式
作用
对于不够用的 方法进行增强
实现步骤
1.定义一个普通类,然后让其被包装对象具有相同的行为(实现其接口)
2.类中定义一个成员,让其接收其被包装对象
3.定义一个构造函数,用于接收被包装对象
4.对于需要增强的方法,提供需要增强的代码
5.对于不需要增强的方法,调用被包装对象的方法
工厂设计模式
作用
实现步骤
单例 设计模式
懒汉式
类加载的时候就创建对象
饿汉式
使用时,创建对象
Linux
Linux介绍
Linux是一种自由和开放源代码的Unix操作系统
该操作系统的内核是由
林纳斯·托瓦兹
1991年10月5日
任何个人和机构都可以自由地使用Linux的所有底层源代码,也可以自由地修改和再发布。
目录结构
/(根目录)
home
普通用户的家目录,每一个用户的家目录通常默认为/home/USERNAME
~ :代表当前使用者的家目录
/root
管理员工作目录
boot
系统启动相关的文件
etc
配置文件
bin
可执行文件,用户命令
cat,chmod(修改权限), chown, date, mv, mkdir, cp, bash等等常用的指令。
sbin
可执行文件,管理命令
fdisk, fsck, ifconfig, init, mk
/usr
/usr/local:第三方软件
/usr/bin/:用户指令
/usr/lib/:应用软件的函式库、目标文件
/usr/sbin/:
一些网络命令都会放在这里
/usr/include/:
c/c++等程序语言的档头(header)与包含档(include)放置处,当我们以tarball方式 (*.tar.gz 的方式安装软件)安装某些数据时,会使用到里头的许多包含档。
/srv
srv可以视为service的缩写,是一些网路服务启动之后,这些服务所需要取用的资料目录。
/tmp
这是让一般使用者或者是正在执行的程序暂时放置档案的地方。
这个目录是任何人都能够存取的
所以你需要定期的清理一下。当然,重要资料不可放置在此目录啊。
/sys
该文件系统是内核设备树的一个直观反映。
/lib
库文件
静态库:单在程序中的库,其他程序不能使用该库文件
动态库:在内存中,任何用到该库的程序都可以使用
/var
var 是 variable(变量) 的缩写,这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。
/dev
在Linux系统上,任何装置与周边设备都是以档案的型态存在于这个目录当中。
/media
挂载点目录,移动设备
DVD/软碟的挂在目录
/mnt
挂载点目录,额外的临时文件系统
/selinux
这个目录是 Redhat/CentOS 所特有的目录,Selinux 是一个安全机制,类似于 windows 的防火墙,但是这套机制比较复杂,这个目录就是存放selinux相关的文件的。
系统命令
ls
ls -l
以详细形式查询当前目录下所有文件和目录,不包括隐藏文件和目录
-a
-a 以精简形式查询当前目录下所有文件和目录,包括隐藏文件和目录
ll
相当于ls -l
cd
cd 绝对路径 /一级目录/二级目录/...
cd 相对路径
./ 当前目录
../ 上级目录
./ 当前目录
../ 上级目录
cd /目录
切换到/目录下
cd 目录
进入当前子目录
cd ~
当前用户的主目录
cd /
根目录
cd -
上一次访问的目录
cd ..
上一级目录
cd
缺省(默认)当前用户目录
mkdir(创建目录)
mkdir
-p
一次性创建多级目录,如果目录存在不会覆盖
案例
mkdir aaa 在当前目录下创建aaa目录,相对路径
mkdir ./bbb 在当前目录下创建bbb目录,相对路径
mkdir /ccc 在根目录下创建ccc目录,绝对路径
mkdir /ddd/eee 在根目录下创建ddd目录和eee子目录
find(搜索命令)
-name
find / -name 'b'
查询根目录下(包括子目录),名为b的目录和文件
find / -name 'b*'
查询根目录下(包括子目录),名以b开头的目录和文件
mv命令
修改文件名
剪切目录
剪切目录
mv 旧目录 新目录
mv aaa aaaa
修改文件名
mv /aaaa /bbb
将根目录下的aaaa目录,移动到bbb目录下,在bbb目录下也叫aaaa目录
mv bbb usr/bbbb
将当前目录下的bbb目录,移动到usr目录下,且修改名为bbbb
cp复制命令
cp -r
-r 递归处理,将指定目录下的文件与子目录一并处理
cp -r /aaa /bbb
将/目录下的aaa目录复制到/bbb目录下,在/bbb目录下名字为aaa
cp -r /aaa /bbb/aaaa
将/目录下的aaa目录复制到/bbb目录下,且修改名为aaaa
rmdir删除目录
-p 删除目录及其父目录
rmdir bbb/ccc
删除bbb目录下ccc目录
rmdir -p bbb/ccc
删除bbb目录和ccc子目录
查看硬件信息
cpu信息
lscpu
cat /proc/cpuinfo也可看查看到
查看内存大小
free
cat /proc/meminfo
查看硬盘和分区情况
lsblk
cat /proc/partitions
查看内核/操作系统/CPU信息
uname -a
查看发行版本
cat /etc/redhat-release
cat /etc/os-release
显示和设置系统时间
date
查看计算机名
hostname
进程
查看系统进程
ps -ef
ps -ef|grep xxx
查询某个进程
强制杀死某个进程
kill -9 [pid]
检查那个端口被占用
netstat -lnp|grep 端口号
vi
应用命令
防火墙相关
关闭防火墙
systemctl stop firewalld
启动防火墙
systemctl start firewalld
开放端口
firewall-cmd --permanent --zone=public --add-port=3306/tcp
firewall-cmd --permanent --zone=public --add-port=3306/udp
关闭端口
firewall-cmd --remove-port=3306/tcp --permanent
firewall-cmd --remove-port=3306/udp --permanent
重新加载防火墙配置
firewall-cmd --reload
查看端口是否开启
firewall-cmd --query-port=3306/tcp
查看已开启的端口
firewall-cmd --list-ports
查看所有安装的软件包
rpm -qa
列出所有系统服务
列出所有系统服务
chkconfig --list
列出指定的系统服务
chkconfig --list | grep on
项目
sass系统
1.简介
云服务的三种模式
Iass
基础设施即服务
基础硬件(内存,网路,硬盘xxx) 软件
大型公司
pass
软件平台即服务
不关注基础设置(计算机+++软件)
中型公司
sass
软件即服务
都用别人的
小型公司
货代云平台
0 条评论
下一页