Java后端程序员技术栈
包括前端、后端、数据、其他四个部分,这里仅仅是知识提纲,便于快速复习与查阅,详细治疗下载在<gitee仓库_JavaNote>前端HTML达成对前端的基本认识基本标签基本链接、锚链接、iframe、资源(图片、视频、音乐)、列表、表格表单的编写单选框、多选框、按钮、选择框、文本域、滑块、验证、增强鼠标、文件域表单的属性method、action、name、value、readonly、
Java后端程序员技术栈
- 它可以是知识提纲,便于快速复习与查阅
- 它也可以是你的学习规划,帮助小白快速了解学Java要走的路(当然你也可以选择搭配我的学习路线一起享用!)
相关链接:
- <gitee仓库_JavaNote>
- <学习路线>
学习主要包括四个板块
- Java基础
- Java的一些基本语法(对象的三大特征,集合,注解,反射,IO,多线程,JVM,泛型,枚举)
- Java的多线程的深入
- JVM深入
- JavaWeb
- 前端知识
- HTML、JavaScript、CSS
- Vue、ElementUI
- Nginx
- 数据层
- Mysql
- Redis
- Sharding-JDBC
- MongoDB
- ElasticSearch
- 应用层
也就是我们的框架部分
- Spring
- MyBatis
- SpringMVC
- SpringBoot
- MyBatisPlus
- SpringCloud
- Netty
- 消息队列(Kafka、Rabbit MQ、Rocket MQ……)
- 运维知识
- Git
- Docker
- Linux
- 网站部署
- Excel操作
文章涉及的知识点很细,不想细看的朋友可以直接看目录哟!
前端
HTML
达成对前端的基本认识
-
基本标签
基本链接、锚链接、iframe、资源(图片、视频、音乐)、列表、表格
-
表单的编写
单选框、多选框、按钮、选择框、文本域、滑块、验证、增强鼠标、文件域
-
表单的属性
method、action、name、value、readonly、placeholder、required、disabled、hidden
CSS
达成对前端的基本认识
- 盒子模型
- 导入方式
- 选择器
- 定位
- 美化
- 字体样式
- 超链接及其伪类
- 阴影
- 列表
- 背景渐变
- 圆角边框
- display和浮动
- 父级塌陷问题
JavaScript
**达成对前端的基本认识,Ajax **
-
数据类型
- 两个注意的坑,NaN和浮点数的存储
- 特别注意对象类型,类似于Python的dict
- 多行字符串、模板字符串、字符串不可变
- 数组包含任何类型、push、pop、unshift、shift
-
严格检查模式
strict
-
流程控制,类似java
-
Map,这里的map其实就是一个二维数组,只是为它添加了一些类似于java的方法,注意遍历用of而不是in
-
Set,不能重复
-
面向对象
-
函数,函数本身也可以看作一个数据类型
-
全局变量var都会绑定到Window对象上,我们为了消除这种全局变量的冲突问题,我们可以只定义一个全局变量来解决
//只定义一个全局变量,其他的就在上面添加即可 var all_var{}; //想要创建全局变量,我们就添加即可 all_var.x=1; all_var.y=2; all_var.add =function(a){ return -2*a; }局部变量let
常量const
-
方法,对象里面的函数
-
面向对象的原理
最初解决方案,也是他的底层原理
obj1.__proto__=obj2; -
面向对象的现阶段解决办法
-
-
内置对象
-
Date
-
Json(stringify、parse)
//JSON和对象的区别 let obj = {name:"zxh"}; let json = {"name":"zxh"}; -
Ajax
-
-
BOM
Navigator、screen、location、doucument、history
-
DOM
- 获得,类似于css
- 修改
- 删除
- 插入
- 移动
-
操作表单
-
Jquery
$(selector).action()
Vue
达成对前端的基本认识
-
MVVM模式
-
v-bind,{{}},v-on,v-model
-
组件,props、Template、emit
-
axio
-
计算属性
-
插槽
-
vue-router
-
嵌套路由
-
参数传递的两种方式传递
-
重定向和404页面
-
-
路由钩子
ElementUI
达到会使用的效果
初始化项目
# 创建项目
vue init webpack 项目名
# 安装依赖
npm install
#启动试试
npm run dev
删除多余的
vue-router
# 安装 vue-router
npm install vue-router --save-dev
#安装如下配置
npm run dev
-
新建router文件夹,再新建router.js
-
在main.js中引入上面这个文件
-
改变main.js为
import Vue from "vue" import VueRouter from "vue-router"; Vue.use(VueRouter) import Hello from "../components/Hello"; export default new VueRouter({ routes:[ { path:"/", component:Hello }, ] })
Axios
npm install router --save-dev
npm install vue-router --save-dev
在main.js中进行开启
import Axios from "axios";
import VueAxios from "vue-axios";
Vue.use(VueAxios,Axios)
配置页面
<template>
<div id="axios">
<h1 title="我也可以">这样呢?</h1>
<h1 v-bind:title="bind">悬停查看</h1>
<b v-if="ifBody=='A'">后台数据是A</b>
<b v-else>后台数据不是A</b>
<p v-for="item in items">
{{item.message}}
</p>
<p>
{{info}}
</p>
</div>
</template>
<script>
export default {
name: "AxiosDo",
el:"#axios",
data() {
return {
bind: "这是一个隐藏绑定的title标签",
ifBody: "A",
items: [
{message: "Java"},
{message: "MySql"},
{message: "Python"},
{message: "C"},
{message: "C++"},
{message: "Matlab"}
],
info:{}
}
},
created() {
this.axios({
method:"get",
url:"http://localhost:8080/static/data.json",
}).then(res=>this.info=res.data)
}
}
</script>
<style scoped>
ElementUI
npm install element-ui --save-dev
npm install sass-loader node-sass --save-dev
修改main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from "./router/router";
import Axios from "axios";
import VueAxios from "vue-axios";
import ElementUi from "element-ui"
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(VueAxios,Axios)
Vue.use(ElementUi)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
router,
el: '#app',
render: h => h(App),//ElementUI规定这样使用
})
Nginx
实现对静态网页的部署(负载均衡、反向代理)
- 反向代理
- 负载均衡
- 轮询
- 加权轮询
- IPHash
- 配置文件的书写
Java
JavaSE
基础
多线程
JVM
JavaWeb
学习Servlet的执行原理、ServletContext、Response、Request、Cookie、Session、Filter、Listener、了解jsp、入门MVC架构、以及Ajax的基本使用、文件上传和邮件发送
基础
-
maven环境搭建,环境变量、本地仓库和阿里云镜像
Jar问题到本地仓库去删除掉所有的文件,再次导入
-
web开发基本知识,http、服务器、端口、请求头、pom.xml
Servlet

Servlet原理
-
Servlet体系结构
Request、Response、Servlet(五个方法)、ServletConfig、ServletContext、GenericServlet、HTTPServlet
-
生命周期(Servlet类加载—>实例化—>服务—>销毁)
三种创建方法,销毁的时机
项目启动方式
用maven创建一个简单的web项目,然后创建java文件夹和resource文件夹,然后为它们进行标记
- 添加Java、resources
- 修改web.xml为最新
- 继承
HttpServlet,重写doGet()和doPost()方法 - 编写程序
- 配置Tomcat,设置Deployment(发布)路径
- 启动
Mapping
一对一、一对多、通用映射、指定前缀或者后缀
ServletContext
相当于是Servlet容器的代理人,CEO
- Servlet直接共享数据
- 获得ContextParam
- 请求转发,Servlet没有处理嘛,就让老大分配给别人
- 获得资源输入流
getResourceAsStream
Response
封装了响应头,响应体,状态码
- 设置响应体
- 验证码、文件下载(需要获得权限)、显示的数据
- 重定向
Request
-
获取前端数据
getParameter
getParameterValues
Cookie
一个键值对一个Cookie,客户端,
- addCookie
- getName
- getValue
- SetMaxage
Session
一个会话一个Session,服务端
- setAttribute
- getAttribute
- removeAttribute
- invalidate
- getId
- isNew
- 设置时间
Listener
同样是接口相应的Listener
Filter
和Servlet类似,接口Filter,然后配置映射即可
Jsp
-
JSP原理
-
jsp原理还是Servlet,他会在tomcat容器中配置一个xxx_jsp.java类
-
九大内置对象
out、config、page、pagecontext、response、request、exception、sessionn、application
-
-
基本语法
- <%= %>
- <% %>
- <%! %>
- <%-- --%>
-
指令
- <%@page errorPage="/Error/500.jsp" %>
- 响应头
- <%@page extends %>
- <%@page isErrorPage %>
- <%@ include *** %>页面拼接
-
EL表达式
- 基本运算和empty判断
${域名称.键名}普通使用${键名}范围从小到大自动匹配${域名称.键名.属性名}对象${域名称.键名[索引]}List${域名称.键名.key名称}Map- ${pageContext.request.contextPath} 隐式对象
-
Jsp标签
- <Jsp:include
- <Jsp:forward
-
JSTL标签
文件上传和邮件发送
能使用即可
Ajax
//对象.on(),为对象添加行为,第一个参数可以为"blur"、"focus"
oldpassword.on("blur",function(){
$.ajax({
//通过GET方法以dateType的格式提交data到Url地址中
type:"GET",
url:path+"/jsp/user.do",
//注意传递参数就只有这两个
data:{method:"pwdmodify",oldpassword:oldpassword.val()},
dataType:"json",
//提交成功提供的标记
success:function(data){
if(data.result == "true"){//旧密码正确
validateTip(oldpassword.next(),{"color":"green"},imgYes,true);
}else if(data.result == "false"){//旧密码输入不正确
validateTip(oldpassword.next(),{"color":"red"},imgNo + " 原密码输入不正确",false);
}else if(data.result == "sessionerror"){//当前用户session过期,请重新登录
validateTip(oldpassword.next(),{"color":"red"},imgNo + " 当前用户session过期,请重新登录",false);
}else if(data.result == "error"){//旧密码输入为空
validateTip(oldpassword.next(),{"color":"red"},imgNo + " 请输入旧密码",false);
}
},
//提交失败提供的标记
error:function(data){
validateTip(oldpassword.next(),{"color":"red"},imgNo + " 请求错误",false);
}
});
}).on("focus",function(){
validateTip(oldpassword.next(),{"color":"#666666"},"* 请输入原密码",false);
});
以及data[]
Spring
学习IOC、AOP、分布式事务
入门
- Interface21–>Spring:使现有的技术更加容易–>“配置炼狱”
- 非入侵式、开源、轻量级
- IOC、AOP
- 支持事务
IOC
IOC(Inversion of Control)控制反转
控制反转、解耦
- 没有IOC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方
- 实现
控制反转的是IOC容器,实现IOC容器的是DI注入
1. IOC执行流程
- Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象
- 就是利用Setter方法来进行注入的
2. 两种bean创建方法
-
可以通过无参构造器创建我们的bean在BeanFactory中,然后可以通过Setter方法来注入参数
-
也可以通过有参构造器直接创建有参数的bean到BeanFactory中
3. bean的作用域
- singleton
- prototype
- request、session、application
配置
-
别名
-
导入
DI注入
1. 构造器注入
<constructor-arg name="str" value="Hello Java Designer!"/>
2. Set注入
- String
- 对象
- array、list、set
- map
- null
- properties
3. 拓展方法注入
p命名空间和c命名空间
自动装配
autowire
- byName
- byType
@Autowired
- 默认byType,同类型有多个就会再次byName
- 直接创建并不是在创建之后进行的属性的注入
使用注解开发
一定要开启注解,以及进行Bean扫描
<!--开启注解的支持 --> <context:annotation-config/> <!--自动扫描包 --> <context:component-scan base-package="com.ZhengXinhao.Pojo"/>
@Component(@Service、@Controller、@Repository)
@Value+@Autowired
@Scope
JavaConfig
@Configuration
@Import
@ComponentScan
@Bean
代理模式
1. 静态代理
- 优点:公共方法交给代理对象,方便对公共方法进行管理拓展;而真实对象的操作也更加的纯粹!
- 缺点
- 随着方法的增多,静态代理的代码也随之增多,造成代码的冗余
- 当然也只能代理一个真实对象,而动态代理可以通过实习工具类来实现代理多个真实对象
2. 动态代理
public class ProxyTarget implements InvocationHandler {
private Object target;
public ProxyTarget(Object target) {
this.target = target;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName()+"方法已经执行");
return method.invoke(target, args);
}
}
动态生成代理对象的类
- 在这里你需要明白rent.getClass().getInterfaces(),这里是得到实现类的接口的
- method.invoke(rent, args),这里是调用rent这个实体类里面的方法
- 这里留下一个疑问,invoke方法是什么时候调用的?什么时候生成我们的动态代理类的,代理的执行方法是什么时候执行的
- invoke( )方法是在Proxy代理类生成之后为了使用这个代理类里面的方法,来通过反射执行的!
- 使用那个方法就invoke那个!
- 生成代理类
newProxyInstance----->通过反射执行代理类的方法invoke()
AOP
切面、横切关注点、切入点、通知、代理
五种Advice
- MethodBeforeAdvice
- AfterReturningAdvice
- MethodInterceptor
- ThrowsAdvice
- IntroductionAdvisor
execution表达式
execution(修饰符匹配式? 返回类型匹配式 类名匹配式?方法名匹配式( 参数匹配式 ) 异常匹配式?)
接口实现
开启<aop:aspectj-autoproxy/>
写一个类必须接口上面的Advice,重写方法,后进行配置
<aop:config>
<!-- 配置切入点-->
<aop:pointcut id="LogPointCut" expression="execution(* com.ZhengXinhao.Service.UserServiceImpl.*(..))"/>
<!-- 配置通知advice-->
<aop:advisor advice-ref="after" pointcut-ref="LogPointCut"/>
<aop:advisor advice-ref="before" pointcut-ref="LogPointCut"/>
</aop:config>
自定义实现
开启<aop:aspectj-autoproxy/>
自定义一个类,自定义方法,后进行配置
<aop:config>
<!-- 第二种-->
<!-- 配置切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.ZhengXinhao.Service.UserServiceImpl.*(..))"/>
<aop:aspect ref="diyAspect">
<!-- 配置通知advice-->
<aop:after method="after" pointcut-ref="pointcut"/>
<aop:before method="before" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
上面的表达,第一种切面了两个,第二种只切面了一个,但配置了两个方法
注解实现
@Aspect
@Component
public class AnnotationPointCut {
@Before("execution(* com.ZhengXinhao.Service.UserServiceImpl.*(..))")
public void before(){
System.out.println("====方法执行前====");
}
@After("execution(* com.ZhengXinhao.Service.UserServiceImpl.*(..))")
public void after(){
System.out.println("====方法执行后====");
}
@Around("execution(* com.ZhengXinhao.Service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前");
System.out.println(joinPoint.getSignature());
joinPoint.proceed();
System.out.println("环绕后");
}
}
然后在启动类上面进行开启@EnableAspectJAutoProxy
整合MyBatis
配置
-
配置mybatis-config.xml
- 这里面只需要配置settings、typeAlias(因为properties和environments已经在dataSource在配置,mappers已经在sqlSessionFactory中配置)
-
配置spring-mybatis.xml
- 配置dataSource
- 配置sqlSessionFactory,并且配置mapper.xml和mybatis-config.xml的位置
- 配置sqlSession(当然你也可以不用配置)
-
配置application.xml并且引入spring-mybatis.xml
使用
- 接口Mapper,注入SqlSession到SqlSessionTemplate中,得到Mapper即可
- 接口Mapper,继承SqlSessionDaoSupport,直接getSqlSession( )
声明式事务
其实就是Aop的应用
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 相当于进行配置,Aop的类一样,但这里好像是进行动态代理-->
<tx:advice id="transaction" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="select*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 相当于进行接口实现Aop的配置-->
<aop:config>
<aop:pointcut id="TransactionPointCut" expression="execution(* com.ZhengXinhao.Mapper.BlogMapperImpl.*(..))"/>
<aop:advisor advice-ref="transaction" pointcut-ref="TransactionPointCut"/>
</aop:config>
SpringMVC
拦截器、SpringMvc执行原理为以后的SpringBoot做铺垫、RestFul风格、JSON
MVC
降低耦合性,提高代码的复用率,是一种结构模式
-
Model,模型:提供要展示的数据和行为
-
View,视图:展示模型数据
-
Controller,接受用户请求,处理Model返回给View
SpringMVC
围绕DispatcherServlet [ 调度Servlet ] 设计,基于Java实现MVC的轻量级Web框架
-
中心控制器
- DispatcherServlet,将请求分发到不同的处理器
- 实际上是一个的Servlet (它继承自HttpServlet 基类)
-
SpringMVC的执行原理
](https://i-blog.csdnimg.cn/blog_migrate/54e3c4f424f39f9cacc67185a60709b9.png)
-
SpringMVC程序
- 在
web.xml中配置DisPatcherServlet,并初始化springmvc-servlet.xml - 在springmvc-servlet中配置
- 处理器映射器(默认可以不配置)
- 处理器适配器(默认可以不配置)
- 视图解析器(注意配置视图解析器的前缀和后缀)
- 各个处理器,但注意名字为"/hello"
- 配置各个处理器(Controller)
- 具体跳转的Jsp
- 在
-
注解实现SpringMVC
-
在
web.xml中配置DisPatcherServlet,并初始化springmvc-servlet.xml -
在springmvc-servlet中配置
-
自动扫描包、注解驱动、免除静态资源
<!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 --> <context:component-scan base-package="com.ZhengXinhao.Controller"/> <!-- 让Spring MVC不处理静态资源 --> <mvc:default-servlet-handler /> <!-- 支持mvc注解驱动--> <mvc:annotation-driven /> -
视图解析器(注意配置视图解析器的前缀和后缀)
-
-
配置Controller
- @Controller
- @RequestMapping("/hello")(类)
- @RequestMapping("/test1")(方法)
-
具体跳转页面
-
RestFul风格
资源定位及资源操作的风格
-
不同请求方法不同的处理器
http://127.0.0.1/item/1 查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 删除,DELETE
-
@PathVariable
@Controller
public class WebController2 {
@RequestMapping(value = "/method2/{name}",method = {RequestMethod.POST,RequestMethod.GET})
public String method2(@PathVariable String name, Model model){
model.addAttribute("msg","Method2>>>Hello,Java Designer!"+name);
return "hello";
}
}
结果跳转方式
-
通过视图解析器
-
通过设置ServletAPI
resp.sendRedirect("/index.jsp"); req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp); -
通过SpringMVC
return "forward:/index.jsp"; return "redirect:/index.jsp";
处理数据
- 接收数据
- 前端数据不匹配的情况下可以使用
@RequestParam("username") String name写在方法的接收参数里面 - 前端数据也可以整合为一个对象
- 前端数据不匹配的情况下可以使用
- 发送数据
- Model
- ModeAndView
- ModelMap,
拓展了方法,继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedHashMap(继承HashMap接口Map) 的方法和特性
乱码的处理
配置SpringMvc的CharacterEncoding,配置参数encoding–>utf-8
检查Tomcat
上大佬代码
JSON
@ResponseBody、@RestController
-
Json乱码
你可以在当个RestController里面进行配置
@RequestMapping(value = "/jackjson2",produces = "application/json;charset=utf-8")在注解驱动里面配置如下
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> </bean> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"> <property name="failOnEmptyBeans" value="false"/> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> -
Jackson
new ObjectMapper
- writeValueAsString
-
FastJson
- JSON.toJSONString
- JSON.parseObject
- JSON.toJSON
- JSON.toJavaObject
- JsonObject
拦截器
这里的拦截器是指向接口了HandlerInterceptor的拦截器
-
return true:通过拦截
-
return false:未通过拦截
-
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.ZhengXinhao.Interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors>
文件上传
依然是拿来即用
SpringBoot
SpringBoot自动装配原理、yaml、Web开发常用开发、SpringSecurity、Shiro、分布式、RPC
概述
- 解决企业级应用开发的复杂性而创建的,简化开发
- 约定大于配置
- 集成了大量常用的第三方库配置,开箱即用
- 内嵌容器
- 没有复杂的xml配置
banner.txt
yaml
- 基本使用,对象、List
- 属性赋值,
@ConfigurationProperties(prefix = "person")- 松散绑定
- 占位符,
${random.uuid}、${random.int}、${person.dogname:旺财}
- SpEL,
@PropertySource(value = "classpath:util.properties") - JSR303校验,@Validated
- @NotNul、@Max、@Null、@NotEmpty、NotBlank
- @AssertTrue 、@AssertFalse
- @Size、@Length
- @Past、@Future
- @Pattern
- 配置文件的位置
- ./
- ./config
- classpath:./
- classpath:./config
- 多环境配置
- spring.profiles.active
- — 分隔
web开发
-
静态资源的映射,源码警告
- classpath:./static
- classpath:./resources
- classpath:./public
- classpath:./META-INF/resources
-
首页定制
-
Thymeleaf
- th:text="${msg}"
- th:each=“list:${lists}”
-
mvc的自动配置
@EnableWebMvc全面接管,了解全面接管的原理
如果您希望保留Spring Boot MVC功能,并且希望添加其他MVC配置(拦截器、格式化程序、视图控制器和其他功能),则可以添加自己
的@configuration类,类型为webmvcconfiguer-
视图解析器
- 加载候选视图解析器
- 选择最佳视图解析器
自定义视图解析器—>举一反三
-
首页定制
-
支持静态资源文件夹的路径,以及webjars
-
自动注册了Converter:转换器 1–>int
-
Formatter:格式化器
-
HttpMessageConverters user—>json
-
错误代码生成规则
-
初始化数据绑定器 请求数据—>javabean
-
格式化–>举一反三
-
视图跳转–>举一反三
-
原理
- 启动器,从
spring-boot-dependencies自动导入依赖 - @Import
- @Import(ConfigB.class),相当于xml标签中的,优
- 个性加载
ImportSelector的实现类,@Import(ServiceImportSelector.class),优- 返回要加载的
@Configuation或者具体Bean类的全限定名的String数组 AnnotationMetadata是Import注解所在的类属性- 一般通过@EnableService(name = “B”)来实现
- 返回要加载的
- 个性加载
DeferredImportSelector的实现类,@Import(DefferredServiceImportSelector.class),劣 - 个性加载
ImportBeanDefinitionRegistrar的实现类,@Import(ServiceImportBeanDefinitionRegistrar.class),劣- 优点就在于可以实现属性注入
- .addConstructorArgValue(name);
- 优劣解决办法,
@ConditionalOnMissingBean
- @SpringBootApplication
- @SpringBootConfiguration,表明是JavaConfig
- @ComponentScan,开发者组件扫描
- @EnableAutoConfiguration,自动配置注解
- @AutoConfigurationPackage,开发者组件扫描
- @Import(AutoConfigurationImportSelector.class),自动配置核心
- selectImports(AnnotationMetadata annotationMetadata)
- getAutoConfigurationEntry(annotationMetadata)
- getCandidateConfigurations(annotationMetadata, attributes)
- loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader()) - loadSpringFactories(classLoader)
- FACTORIES_RESOURCE_LOCATION=“META-INF/spring.factories”
- run方法
- 推断应用的类型是普通的项目还是Web项目
- 查找并加载所有可用初始化器 , 设置到initializers属性中
- 找出所有的应用程序监听器,设置到listeners属性中
- 推断并设置main方法的定义类,找到运行的主类
员工管理系统
-
国际化
-
配置不同的语言,login.properties、login_en_US.properties、login_zh_CN.properties
-
在application中进行配置
#设置语言配置文件路径 spring: messages: basename: i18n.login -
Thymeleaf模板html中使用
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1> -
手动切换的提供
设置LocalResolver的自定义实现类来处理请求,并且注册bean为localResolver
-
数据库整合
在SSM中我们需要自己配置dataSource、sqlSessionFactory、sqlSession;但现在在SpringBoot,SpringBoot帮我们自动配置了一切!
- JDBC
- 注入JdbcTemplate
- execute( )
- query( )、queryForLit( )
- update( )、batchUpdate( )
- call( )
- 注入JdbcTemplate
- Druid
- application.yaml的配置
- 注册Servlet和配置过滤
- MyBatis
- @Mapper
- application.yaml的配置
- @Transactional
- 隔离级别
- 传播属性
SpringSecurity
sex:命名空间sec:authorize取布尔值sec:authentication取值
SpringSecurity配置类configure(AuthenticationManagerBuilder auth)configure(HttpSecurity http)- 登录页面
- 退出登录
- 记住我
Shiro
- shiro.ini的配置
- JavaSE中的使用
- session存取
- 是否认证
- 进行认证
- 查看权限
- 查看角色
- Shiro+SpringBoot
- 创建SelfRealm继承AuthorizingRealm,重写方法
- doGetAuthorizationInfo,授权
- doGetAuthenticationInfo,认证
- 配置ShiroConfig
- 注册ShiroDialect
- 注册DefaultWebSecurityManager,manager.setRealm(realm);
- 注册ShiroFilterFactoryBean
- bean.setFilterChainDefinitionMap(map);
- bean.setSecurityManager(manager);
- bean.setLoginUrl("/toLogin");
- bean.setUnauthorizedUrl("/unauth");
- 配置Controller,subject.login(token);
- Thymeleaf整合shiro
- shiro:hasPermission=“user:add”
- shiro:hasRole=“admin”
- 创建SelfRealm继承AuthorizingRealm,重写方法
Swagger
- 优点,为什么使用
- 松耦合–>api交互–>需要及时协商(拟订计划提纲)–>swagger
- 优点
- API文档在线生成
- 在线测试Api
- apiInfo的配置
- docket的配置
- 加入ApiInfo
- 是否开启—>根据环境选择是否显示
- 通过Environment
- SpEL表达式
- 分组
- 过滤
- 实体类model的配置
- 直接Controller返回对象会自动进行匹配!
- @ApiModel(用户)
- @ApiModelParam(“user对象”)
- Controller
- @Api(tags=“Api for Swagger”)
- @ApiOperation(“User方法”)
- @ApiParam(“传递参数”)
- 皮肤
任务
- 异步任务
- @Async
- @EnableAsync
- 邮件任务
- 导入依赖
- application.yaml中进行配置
- 注入JavaMailSenderImpl
- 使用
- 定时任务
- @EnableScheduling
- @Scheduled(cron = “* * * * * ?”)
- cron表达式
Dubbo+ZooKeeper
-
什么是分布式系统
- 通过网络进行通信,为完成某个任务协调工作的计算机结点组成的计算机系统
- 若干个独立计算机的集合
- 用廉价的机器去完成单个计算机无法完成的计算和存储任务,利用更多的机器处理更多的数据
- 建立在网络上的软件系统
- 会映入更多的问题,我们需要引入更多的协议、机制来处理这些问题,所以我们并不是一开始就考虑分布式系统的,而是当前单个的计算机资源无法完成我们的计算任务的时候,或者说在
-
架构的演变
- 单一架构
- 垂直架构
- 分布式架构
- 流式架构
-
RPC
- 允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节
- RPC就是要像调用本地的函数一样去调远程函数
- 底层是通过Socket进行通信的,没必要用到
HTTP这种文本传输的应用层协议
-
Dubbo
- 核心功能
- RPC
- 负载均衡
- 服务注册与发现
- 执行流程
- 核心功能
-
ZooKeeper
-
远程服务调用-Dubbo
-
提供者
-
配置application.properties
dubbo.application.name=hello-server dubbo.registry.address=zookeeper://127.0.0.1:2181 dubbo.scan.base-packages=com.zhengxinhao.previder.service -
在需要提供的服务(类)上添加
@DubboService
-
-
消费者
-
配置application.properties
dubbo.application.name=hello-consumer dubbo.registry.address=zookeeper://127.0.0.1:2181 -
在当前项目创建和服务提供者一样的路径下,创建和提供者一样的接口
-
在需要使用的地方(类),注入这个接口
@DubboReference
-
-
SpringCloud
微服务解决方案之一,Spring Cloud Netflix(Eureka、Ribbon、Feign、Hystrix、Zuul、Config)
常见面试题
- SpringBoot和SpringCloud的区别
- 什么是微服务
- 微服务和微服务架构
- 微服务的优缺点
- 微服务和分布式的区别
- SpringCloud对比Dubbo的解决方案
REST服务调用
- 写一个实体类接口API
- 在服务提供者写一个操作实体类的服务,导入接口类的API
- 在服务消费者写REST服务调用,注意导入接口类的API
- 注意参数传递的两种方式
- 注意,RestTemplate并没有注册Bean
Eureka
- 基于Rset服务调用
- 有了服务注册与发现,只需要使用服务的标识符,就可以访问到服务
- EurekaServer的配置
- EurekaServer的依耐
- application.yaml的配置
- @EnableEurekaServer
- 服务注册
- EurekaClient的依耐
- application.yaml的配置
- @EnableEurekaClient
- 监控信息的配置
- actuator的依耐
- application.yaml的配置
- info下进行配置
- 自我保护机制
- 在短时间内失去了大量的实例心跳,Eureka并不会把它从注册表中删除!
- 可以让整个微服务架构更加的健壮
- 单个微服务只会在服务启动的时候才向注册中心发起微服务的注册,后面只会接受心跳和服务列表请求
- 获取微服务的信息
- 注入DiscoveryClient
- 集群的配置
- eureka.client.server-url.defaultZone配置多个注册中心地址
- CAP原则
- 一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求
- ZooKeeper–>CP,不满足可用性 重选Leader
- Eureka–>AP,不满足一致性 自我保护机制,Eureka各个结点平衡
Ribbon
-
Eureka其实是自带负载均衡的,我们想要自己选择负载均衡算法我们就需要使用Ribbon
-
在RestTemplate上配置@LoadBalanced
-
@RibbonClient(name = "provider-dept",configuration = ZoneAvoidanceRule.class)
Feign
- Feign简介
- 为了解决REST服务调用的复用性
- 声明式调用
- 写远程调用接口
@FeignClient(value = "provider-dept")@ResponseMapping("/dept/list") - 主启动开启,扫描远程调用接口
@EnableFeignClients(basePackages = "com.zheng.springcloud.service") - 使用的时候,直接注入即可
Hystrix
- 服务熔断
- 熔断机制是对应雪崩效应的一种微服务链路保护机制
- 当某个微服务不稳定的时候能够快速失败
- 也能根据一定的算法试探目标微服务是否恢复
- 三种状态的转换(时间窗口)
- 我们只需要导入pom依赖后在主启动类上添加
@EnableHystrix,在我们需要的服务上面(通常是Controller Api)上添加@HystrixCommand(fallbackMethod = "hystrixGet")再编写指定的方法即可,==但在这里我们需要注意的是,我们的参数,返回类型,需要与我们的被服务熔断的服务相匹配!
- 服务降级
- 对系统整体资源的合理分配,来应对压力,是全局性的考量
- 当服务器压力剧增的情况下,我们不得不手动关闭一些微服务,腾出计算机资源服务我们的核心业务,这就叫服务降级
- 服务降级解决策略
- 降级方式
- 指定网页不可访问(无用户特定信息)
- 延迟持久化
- 服务接口拒绝(提示服务器繁忙)
- 随机拒绝服务
- 持久层拒绝,增删改,仅提供查询
- 降级策略
- 直觉管理方式
- 分级管理方式
- 层次分析法
- 架构师拍脑袋
- 台风预警的等级
- 降级权值
- 降级方式
- 代码
- Ribbon
- 每一个方法执行@HystrixCommand(fallbackMethod = “hystrixGet”)
- 启动类@EnableHystrix
- Feign
- 接口中,没办法写回调方法,我们写一一个回调类
- 写一个类接口FallbackFactory
- 在Feign上面进行配置@FeignClient(value = “provider-dept”,fallbackFactory = DeptFallback.class)
- 在application中开启,默认关闭
- Ribbon
- Dashboard
- 监控中心
- 导入依赖
- @EnableHystrixDashBoard
- application.yaml中添加监控的地址
- 被监控的Hystrix
- 必须实现Hystrix
- @EnableHystrixDashBoard
- 添加ServletRegistrationBean映射
/actuator/hystrix.stream
- Turbine
- 导入依耐dashboard和Turbine
- @EnableTurbine和@EnableHystrixDashBoard
- 向Eureka拉取服务,获取指定服务
- 监控中心
Zuul
- 统一管理
- 认证与授权
- 服务屏蔽
- 依耐
- @EnableZuulProxy
- application.yaml
- 拉取服务
- 配置服务屏蔽、服务前缀、服务API……
Config
-
集中式的,动态的配置管理
-
ConfigServer
- 导入依赖
- 配置Git-url
- @EnableConfigServer
-
ConfigClient
-
导入依耐
-
在bootstrap.yaml中进行配置使用
#系统级别配置 spring: cloud: config: #http://localhost:8800/config-client-dev.yaml profile: dev uri: http://localhost:8800/ #分支,mater可以默认不写 label: master #不用添加.yaml name: config-client
-
Netty
暂未学习
数据
MySQL
补充中!
MyBatis
Mybatis的CRUD、掌握resultMap(包含多对一和一对多)、动态Sql、配置文件的配置、其他(日志、缓存)
简介
- 什么是MySQL
- 持久层
- 为什么要使用MyBatis(解耦、简化开发)
生命周期
- SqlSessionFactoryBuilder
- SqlSessionFactory
- SqlSession
CRUD操作
-
注意增删改都需要提交事务
-
#{userCode};只有一个参数会进行智能匹配
-
调用
SqlSession sqlSession = MyBatisUtil.getSqlSession(); DaoUser mapper = sqlSession.getMapper(DaoUser.class); ArrayList<User> users = mapper.selectUser("admin"); for (User user:users){ System.out.println(user); } sqlSession.close();//及时关闭 -
万能Map===>传递多个参数
配置
- properties :读取顺序properties标签—>properties标签指定配置文件–>sqlSessionFactoryBuilder的build方法
- settings :cacheEnabled、lazyLoadingEnabled、logImpl、mapUnderscoreToCamelCase
- typeAliases :单个设置,包设置(默认和@Alias)、内置别名(Date、Map、List、BigDecimal)
- environments :default、id、translationmanamger type、dataSource type
- mappers :xml映射、class映射、包映射
ResultMap,结果集映射
-
配置方法
<resultMap id="userMap" type="com.ZhengXinhao.Pojo.User"> <result property="name" column="userName"></result> </resultMap> <select id="selectUser" resultMap="userMap" parameterType="String"> select * from smbms_user where userCode = #{userCode} </select> -
原理,调用Mapper,原名不再适用
日志
-
STDOUT_LOGGING
-
LOG4J
-
依耐
-
配置
-
使用
Logger logger = Logger.getLogger(DaoUserTest.class); logger.info("进入了查询userCode这个方法"); logger.debug("进入了查询userCode这个方法"); logger.error("进入了查询userCode这个方法");
-
注解开发
- @Select、@Insert、@Update、@Delete
- @Param
一对多、多对一
- association(对象)
- collection(集合)
动态SQL
- if
- where、set---->trim
- choose(when、otherwise)
- foreach
- sql片段
缓存
- 一级缓存默认开启
- 二级缓存需要settings中配置,在Mapper中配置,接口序列化
Mybatis-Plus
Redis
Redis的基本操作,八大数据类型,整合SpringBoot,主从复制,持久化,缓存击穿,缓存雪崩,缓存穿透
持久层前言
- 单机MySql时代
- 数据逐渐增多,数据索引极速增加,一个机器内存就放不下了,同时访问量增加,服务器也支撑不了
- 缓存和读写分离解决读的问题
- 数据结构和索引的优化
- IO文件缓存
- Memcache,缓存解决
- 分库分表和Mysql集群解决写的问题
- 当今时代,各种各样的数据出现,最开始的关系型数据库已经不难满足我们的需要了,NoSql就能轻松解决这些问题
NoSql
-
**NoSQL = Not Only SQL(不仅仅是SQL)**数据存储没有固定的格式
-
特点
- 方便拓展,数据之间没有关系
- 大数据量高性能
- 数据类型的多样性
-
RDBMS对比NoSql
- 存储结构
- 查询语句
- 原则ACID-----CAP和BASE
- 一致性
- 特点
-
三V(多样,海量,实时)和三高(高并发,高性能,高可拓)
-
NoSql四大类型
类型 例子 应用场景 数据模型 优点 缺点 键值对 Redis 内容缓存,日志系统 K-V,Value无结构 块,表结构可变 数据无结构 文档型 MongoDB Web应用(商品描述,评论) K-V,Value是结构化的 表结构可变 性能不高 列存储 Hbase 分布式文件系统 同一列数据放在一起 快,容易进行分布式拓展 功能局限 图关系 Neo4j 社交网络、推荐系统 图结构 方便使用图结构的相关算法 不利于做分布式集群
Redis概述
-
什么是redis
Redis(Remote Dictionary Server ),即远程字典服务;是由C语言编写,支持网络,可基于内存亦可持久化的K-V键值对日志型数据库,同时它提供了多种语言的API
-
对比Memcache
- 可持久化
- 实现了主从复制
-
特性
- 可持久化
- 效率高,可做高速缓存
- 数据类型多样
- 集群
- 事务
-
环境配置
-
启动
-
./redis-server my-config/redis.conf -
./redis.cli -p 6379 -
shutdown
-
-
性能测试
-
./redis-benchmark -h localhost -p 6379 -c 100 -n 100000
-
Redis入门知识
-
一共有16个数据库,默认使用第1个下标[0]
#存 set name zheng #取 get name #切换数据库 select n #查看数据库数据个数 dbsize #查看所有节点 keys * #清空当前数据库 flushdb #清空全部数据库 flushall -
Redis是单线程的,Redis是基于内存操作的
-
为什么使用单线程?
Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了
-
为什么Redis单线程还这么快?
- 纯内存数据库,而且是基本的读写,线程占用时间短,大部分都是在IO上面
- IO是非阻塞IO,多路复用IO
- 保证了每个操作的原子性,也除去了上下文的切换和竞争的时间
- 数据结构上,Redis是采用的Hash结构,同时采用了特殊的数据结构,压缩表、跳表
- 采用自己实现的时间分离器
-
单线程优缺点
- 不用考虑锁的问题
- 不存在上下文的切换和竞争
- 代码更加清晰,处理逻辑更加简单
-
缺点
- 无法发挥多核CPU的性能
-
五种基本数据类型
-
String
1
-
List

-
Set

-
Hash

-
ZSet

三大特殊数据类型
- Geospatial
- geoadd、geopos、geodist
- georadius、georadiusbymember
- Hyperloglog
- pfadd、pfcount
- pfmerge
- Bitmap
- setbit、getbit、bitcount
事务
- ACID原则
- Redis事务,一次性、顺序性、排他性的执行
事务执行命令序列中的命令 - 使用
- multi-----exec
- multi-----discard
- 事务出错
- 编译型异常,全部不执行
- 执行时异常,仅异常的不执行(非原子性)
- 乐观锁
- watch key
Jedis
- new Jedis(“127.0.0.1”,6379)
- jedis.multi( )
- jedis.discard( )
SpringBoot的整合
- 源码
- 已经为我们配置了RedisTemplate和StringRedisTemplate
- 默认序列化为JDK
- Jedis和Lettuce
- 使用
- 导入依耐
- 配置application
- 注入RedisTemplate
- 事务使用记得开启
- 传递对象
- 报错需要对象进行序列化
- 对象进行序列化
- JSON传输
- 接口Serializable
- 默认使用JDK序列化
- JDK序列化,redis中查看Key都不行
- 自定义RedisTemplate
照猫画虎序列化
- 工具类
redis.conf
-
容量单位
-
引入配置文件
-
网络配置
-
保护模式和端口
-
后台运行pid文件位置
-
日志类型,日志位置,日志级别
-
是否显示logo
-
RDB
- save
- 出错处理
- 压缩rdb文件是否
- 错误的检查校验
- 文件位置
-
密码
-
临时密码
config set requirepassword 123456 -
登录
auth 12456
-
-
最大客户端
-
缓存设置
- 最大缓存
- 缓存上限处理模式
-
AOF设置
- 是否开启
- aof文件名字
- aof执行模式
持久化
- RDB
- 在指定条件下,把内存中的数据集写入到RDB快照文件中,在且仅在启动Redis’的时候读取快照文件,进行数据恢复
- dump.rdb为二进制文件,可读性无
- AOF持久化方式恢复优先级高于RDB持久化方式
- 载入RDB是阻塞状态
- 自动检测过期键
- 工作原理
- fork一个子线程
- 先写在一个临时文件中,写完了就替换原来的dump.rdb文件
- 触发机制
- 手动触发
- save,客户端命令被阻塞,但不消耗额外内存
- bgsave,占用额外内存,但不阻塞客户端命令
- 自动触发
- save 900 1
- flushall命令
- 退出redis
- 手动触发
- 优缺点
- 优点
- 压缩二进制文件,占用空间小
- 适用于灾难恢复,可以传输到别的数据中心
- 父进程不阻塞
- 恢复大数据集的时候速度快
- 缺点
- 可读性差
- 数据容易丢失,太频繁可能导致redis宕机
- 数据集大的时候,fork会很耗时
- 太频繁可能会增加redis占用内存,最坏情况会达到两倍
- 优点
- AOF
- Append Only File
- 以日志的方式记录每一个写的操作,只追加不修改
- 执行流程
- 每执行一条写操作,redis就会把该指令记录到server.aof_buf这样的缓存区中,然后根据配置持久化到硬盘中
- 优缺点
- 优点
- 可读性高
- 修正简单
- 多种同步方式
- 缺点
- 更占用内存
- Redis负载高的时候,RDB性能更好
- 健壮性不如RDB,且存在一些bug
- 优点
订阅发布
-
代码
-
subscirbe 订阅频道 unsubscribe 退订频道 psubscribe 订阅指定模式的频道 punsubscribe 退订指定模式的频道 publish 推送消息 pubsub subcommand 订阅情况
-
-
原理
- pubsub.c中可以看到,Redis-server维护了一个字典,key就是频道,value就是订阅者们(链表),推送消息的时候,找到字典指定的键,遍历这个链表推送消息
-
应用
- 消息队列
- 订阅系统
- 实时聊天
-
缺点
- 推送的时候订阅方不在线,就会永远错过这个这个消息
- 若订阅者的读取消息的速度,不够快的话,不断积压的消息会让redis的输出缓存变大,最终导致redis的变慢,甚至崩溃
主从复制
将一台Redis服务器的数据复制到另一台Redis服务器,数据的复杂是单向的
-
作用
- 数据备份,是持久化之外的另一种数据备份方式
- 故障恢复
- 负载均衡,进行读写分离
- 高可用的基石,是哨兵和集群能够实施的基础
- 单机的弊端
- 单机结构上,单点故障,压力大
- 单机容量上,内存容量有限
-
配置
-
修改redis.conf
- 端口号
- pid文件名
- 日志文件名
- RDB文件名
-
slaveof 127.0.0.1 6379追随主节点
或者在文件中配置
replicaof 127.0.0.1 6379 masterauth 123456#有密码需要输入密码
-
-
复制原理
- 从结点连接到主节点后发送sync命令
- 主节点接收到命令。启动后台存盘进程,收集修改命令集,执行完毕后发送到从结点
- 复制类型
- 全量复制:将数据集进行加载到内存中
- 增量复制:继续发送修改命令到从结点
- 每一次连接到主节点就会进行一次全量复制
-
注意
- 从机只能读(默认),不能写,主机可读可写但是多用于写
- 主机断电从机依然追随,从机依然可读,从机断电重新加载,若配置文件中配置了那么它还会追随
- 从机可以手动解除追随,从主机得到的数据也不会删除
- 主机死了,要么从机解除追随,要么是哨兵模式自动在从机选举主机
-
哨兵模式
- 能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
- 通过发送命令,让Redis服务器响应监控其运行状态,包括主服务器和从服务器
- 当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式**通知其他的从服务器,修改配置**,让他们切换主机
- 一个哨兵可能会出现问题,我们可以配置多哨兵模式,各哨兵直接进行监控
- 多哨兵模式下,主机宕机,一个哨兵检测到宕机,并不会立刻执行选举,仅仅是认为主服务器不可用,称之为主观下线
- 当其他哨兵也发现了这个问题,并且,数量达到一定数量,就会进行投票
- 选举成功之后,通过订阅模式,让其他从结点,切换主机,称之为客观下线
- 优点
- 故障转移,主机可以切换
- 缺点
- 配置复杂
- 能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
常见问题
- 缓存穿透
- 大量访问不存在的值,redis查不到,到数据库查询
- 解决方案
- 布隆过滤器
- 缓存空对象
- 需要更多的空间
- 时间窗口不一致,对一致性要求高的业务有影响
- 缓存击穿
- 缓存失效瞬间,高并发直接查询数据库
- 解决方案
- 热点永不过期
- 加互斥锁
- 但增加了锁的压力
- 缓存雪崩
- 缓存集体失效,大量的key失效,访问到数据库后,后添加缓存的时候,缓存崩掉了
- 解决方案
- redis高可用
- 限流降级,不让他们同时进行写缓存
- 数据预热
- 设置不同的过期时间
短信验证码
只会使用即可
ShardingJDBC
主要是对Redis中说讲的持久层架构进行一个巩固,重点在于概念
ShardingSphere
-
ShardingSphere简介
- 当当网 ShardingJDBC
- Apache ShardingSphere
-
ShardingSphere发展流程
- 数据分片
- 数据库治理
- 分布式事务
- Apache项目
-
并非只是框架,而是生态圈
- Sharding-JDBC
- Sharding-Proxy
- Sharding-Sidecar
数据分片
- 相关概念
- 分片
- 数据结点
- 逻辑表
- 真实表
- 分片键
- t_order_id%3
- 分库分表可以看做一种路由机制,而分片算法可以理解成一种路由规则
- 分片算法
- 精准分片算法
- StandardShardingStrategy
- 范围分片算法
- StandardShardingStrategy
- 复合分片算法
- ComplexShardingStrategy
- HInt算法
- 精准分片算法
- 分片策略
- 标准分片策略
- 单分片键
- 精准分片算法(必)+范围分片算法(可选)
- 复合分片策略
- 多分片键
- 行表达式分片策略
- =和>
- Hint分片策略
- 标准分片策略
- 分布式主键
- UUID
- 雪花算法(默认)
- 广播表
- 表结构和表中的数据在每个数据库中均完全一致
- 某个表一旦被配置为广播表,只要修改某个数据库的广播表,所有数据源中广播表的数据都会跟着同步
- 绑定表
- 为了避免 笛卡尔积 关联查询
Sharding-JDBC的实现- JDBC 是一种
Java语言访问关系型数据库的规范,其设计初衷就是要提供一套用于各种数据库的统一标准,不同厂家共同遵守这套标准,并提供各自的实现方案供应用程序调用 - Sharding-JDBC可以认为是JDBC的升级版
- JDBC 是一种
主从复制
读写分离
消息队列
暂未学习
MongoDB
暂未学习
ElasticSearch
暂未学习
其他
获取参数
| 语言 | 格式 | 例子 |
|---|---|---|
| EL表达式 | ${ } | ${pagecontext.request.contextPath} |
| JQuery | $(selector).action( ) | $(’#btn’).click( ) |
| Mybatis的mapper | #{ } | #{user.name} |
| Mybatis的config | ${ } | ${password} |
| Thymeleaf | ${ } | ${list} |
| SpEL | ${ } | ${spring.prefile.active} |
Excel
Git
前言
- 版本控制工具需求的必要性
- 协作开发
- 追踪历史记录
- 常见版本控制工具
- 本地版本控制
- 集中版本控制 SVN
- 分布式版本控制 Git
- SVN和Git的区别
- 拥有中央服务器,对网络的需求极大
- 每个人的电脑就是一个完整的版本库
配置
- global
- system
- 添加global的配置
- user.name ‘zheng’
- user.email ‘8520780228@qq.com’
基本理论
-
三大区域
- 工作目录
- 暂存区
- 资源库
- Git远程仓库
-
常用命令

-
四种状态
- 未跟踪;
git add进行跟踪 - 已跟踪,未修改;
git rm移除选择 - 已跟踪,已修改;
git checkout丢弃修改;git commit上传修改 - 已上传,可看图
- 未跟踪;
-
忽略文件
#为注释 *.txt #忽略所有 .txt结尾的文件,这样的话上传就不会被选中! !lib.txt #但lib.txt除外 /temp #仅忽略项目根目录下的temp文件 build/ #忽略build/目录下的所有子文件 doc/*.txt #会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
Idea整合Git
- 五种颜色
- 个插件位置,和使用
分支
git branch查看分支git branch -r查看远程分支git branch v1.0创建分支git branch -d v1.0删除分支git checkout -b v1.0切换分支git merge v1.0合并分支
Linux
补充中!
Docker
暂未学习
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)