docker启动mysql
docker run -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
docker安装Redis
[root@hadoop-104 ~]# mkdir -p /mydata/redis/conf
[root@hadoop-104 ~]# touch /mydata/redis/conf/redis.confdocker run -p 6379:6379 --name redis -v /mydata/redis/data:/data \
-v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf连接到docker的redis
docker exec -it redis redis-cli
数据持久化
设置redis容器在docker启动的时候启动
docker update redis --restart=always
配置中心的应用
1: 引入依赖
可以数据源等文件写到配置中心中读取
ES6的新特性
let 声明变量,const 声明常量(只读变量)
解构表达式
数组解析
对象解构
字符串扩展
几个新的 API
字符串模板
函数优化
函数参数默认值
不定参数
箭头函数
- 一个参数时:
- 多个参数:
练习
![]()
对象优化
- keys(obj):获取对象的所有 key 形成的数组
- values(obj):获取对象的所有 value 形成的数组
- entries(obj):获取对象的所有 key 和 value 形成的二维数组。格式:`[[k1,v1],[k2,v2],...]`
- assign(dest, ...src) :将多个 src 对象的值 拷贝到 dest 中。(第一层为深拷贝,第二层为浅 拷贝)
声明对象简写
对象的函数属性简写
对象的拷贝与合并
数组中新增了 map 和 reduce 方法
map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
reduce 为数组中的每一个元素依次执行回调函数(arr.reduce(callback,[initialValue]),initialValue (作为第一次调用 callback)
Promise(a调用b,b调用c,防止层层嵌套)
新建三个json文件
user.json: { "id": 1, "name": "zhangsan", "sex": "男" } user_corse_1.json: { "id": 10, "name": "chinese" } corse_score_10.json: { "id": 100, "score": 90 }
1:原始方法
2:Promise 语法
处理异步结果
Promise 改造以前嵌套方式
优化处理
export、import
export:一切 JS 变量都可以导出。比如:基本类型变量、函数、数组、 对象。
简写
导入:
Vue
v-bind 指令给 HTML 标签属性绑定值(绑定超链接);
`v-bind:style` 的对象语法十分直观,看着非常像 CSS,但其实是一个 JavaScript 对象。style 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,这种方式记得用单引号括起 来) 来命名。 例如:font-size-->fontSize
v-model
v-text、v-html、v-bind 可以看做是单向绑定,数据影响了视图渲染,但是反过来就不行。
v-model 是双向绑定,视图(View)和模型(Model)之间会互相影响。 既然是双向绑定,一定是在视图中可以修改数据,这样就限定了视图的元素类型。
目前 v-model 的可使用元素有: - input - select - textarea - checkbox - radio - component(Vue 中的自定义组件) 基本上除了最后一项,其它都是表单的输入项。
v-on (v-on:简写@)
语法: v-on:事件名="js片段或函数名"
1:事件修饰符
2:按键修饰符
v-for遍历数组或对象
遍历数组
遍历对象
key用来标识每一个元素的唯一特征,这样 Vue 可以使用“就地复用”策略有效的提高渲染的 效率。
计算属性和侦听器,过滤器(filters)
计算属性
侦听器
过滤器
局部过滤器
全局过滤器
组件化
全局组件
- 组件其实也是一个 Vue 实例,因此它在定义时也会接收:data、methods、生命周期函 数等
- 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有 el 属性。
- 但是组件渲染需要 html 模板,所以增加了 template 属性,值就是 HTML 模板
- 全局组件定义完毕,任何 vue 实例都可以直接在 HTML 中通过组件名称来使用组件了
- data 必须是一个函数,不再是一个对象。
局部组件
生命周期钩子函数
每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模 板等等。Vue 为生命周期中的每个状态都设置了钩子函数(监听函数)。每当 Vue 实例处于 不同的生命周期时,对应的函数就会被触发调用。
vue 模块化开发(安装node.js)
1、npm install webpack -g(全局安装 webpack)
2、npm install -g @vue/cli-init(全局安装 vue 脚手架)
3、初始化 vue 项目(vue init webpack appname:vue 脚手架使用 webpack 模板初始化一个 appname 项目,appname为项目名)
4、启动 vue 项目;
项目的 package.json 中有 scripts,代表我们能运行的命令
npm start = npm run dev:启动项目 (ctrl+c关闭)
npm run build:将项目打包
项目结构
运行流程
进入页面首先加载 index.html 和 main.js 文件。
main.js 导入了一些模块【vue、app、router】,并且创建 vue 实例,关联 index.html 页面的元素。使用了 router,导入了 App 组件。并且使用标签 引用了这个组件
第一次默认显示 App 组件。App 组件有个图片和,所以显示了图片。 但是由于代表路由的视图,默认是访问/#/路径(router 路径默认使用 HASH 模式)。在 router 中配置的/是显示 HelloWorld 组件。
所以第一次访问,显示图片和 HelloWorld 组件。
我们尝试自己写一个组件,并且加入路由。点击跳转。需要使用Go to Foo标签
Vue 单文件组件
导入 element-ui 快速开发
1、安装 element-ui: npm i element-ui
2、在 main.js 中引入 element-ui 就可以全局使用了。
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
3、将 App.vue 改为 element-ui 中的后台布局
4、添加测试路由、组件,测试跳转逻辑
(1) 、参照文档 el-menu 添加 router 属性
(2) 、参照文档 el-menu-item 指定 index 需要跳转的地址
Element 中文帮助文档:Element - The world's most popular Vue UI framework
跨域问题
网关服务配置
package com.wl.gulimall.gateway; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.reactive.CorsWebFilter; import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; @Configuration public class CorsConfig { @Bean public CorsWebFilter corsWebFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration corsConfiguration = new CorsConfiguration(); //1、配置跨域 corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.setAllowCredentials(true); source.registerCorsConfiguration("/**", corsConfiguration); return new CorsWebFilter(source); } }
OSS云存储服务
原始
引入依赖
测试
public class OSSTest { /** * OSS 使用步骤 阿里云 * 1)、引入SDK * 2)、配置好相应的属性 */ public static void main(String[] args)throws IOException { // Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "http://oss-cn-beijing.aliyuncs.com"; // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建。 String accessKeyId = "LTAI4FveggJw1ijp318BifWc"; String accessKeySecret = "epNR5QdCCkvxG167VvbwW4FW8P3UEW"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 上传文件流。 InputStream inputStream = new FileInputStream(new File("D:\\007.jpg")); ossClient.putObject("bucketName", "pic/008.jpg", inputStream); // 关闭OSSClient。 ossClient.shutdown(); System.out.println("测试完成"); } }
整合springcloud alibaba oss
测试
@SpringBootTest class GulimallThirdPartyApplicationTests { @Test void contextLoads() { } @Autowired OSSClient ossClient; @Test public void testUpload() throws FileNotFoundException { // // Endpoint以杭州为例,其它Region请按实际情况填写。 // String endpoint = "oss-cn-beijing.aliyuncs.com"; // // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建。 // String accessKeyId = "LTAI4FwvfjSycd1APnuG9bjj"; // String accessKeySecret = "O6xaxyiWfSIitcOkSuK27ju4hXT5Hl"; // // // 创建OSSClient实例。 // OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 上传文件流。 InputStream inputStream = new FileInputStream("C:\\Users\\lfy\\Pictures\\Camera Roll\\59f2db04139a2.jpg"); ossClient.putObject("gulimall-hello", "hahaha.jpg", inputStream); // 关闭OSSClient。 ossClient.shutdown(); System.out.println("上传完成..."); } }
返回policy直接存储oss
package com.zj.gulimall.third.controller; import com.aliyun.oss.OSS; import com.aliyun.oss.common.utils.BinaryUtil; import com.aliyun.oss.model.MatchMode; import com.aliyun.oss.model.PolicyConditions; import com.zj.gulimall.third.utils.R; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; @RestController public class OssController { @Autowired OSS ossClient; @Value("${spring.cloud.alicloud.oss.endpoint}") private String endpoint; @Value("${spring.cloud.alicloud.oss.bucket}") private String bucket; @Value("${spring.cloud.alicloud.access-key}") private String accessId; @RequestMapping("/oss/policy") public R policy() { //https://gulimall-hello.oss-cn-beijing.aliyuncs.com/hahaha.jpg String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint // callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。 // String callbackUrl = "http://88.88.88.88:8888"; String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); String dir = format + "/"; // 用户上传文件时指定的前缀。 Map<String, String> respMap = null; try { long expireTime = 30; long expireEndTime = System.currentTimeMillis() + expireTime * 1000; Date expiration = new Date(expireEndTime); PolicyConditions policyConds = new PolicyConditions(); policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000); policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir); String postPolicy = ossClient.generatePostPolicy(expiration, policyConds); byte[] binaryData = postPolicy.getBytes("utf-8"); String encodedPolicy = BinaryUtil.toBase64String(binaryData); String postSignature = ossClient.calculatePostSignature(postPolicy); respMap = new LinkedHashMap<String, String>(); respMap.put("accessid", accessId); respMap.put("policy", encodedPolicy); respMap.put("signature", postSignature); respMap.put("dir", dir); respMap.put("host", host); respMap.put("expire", String.valueOf(expireEndTime / 1000)); // respMap.put("expire", formatISO8601Date(expiration)); } catch (Exception e) { // Assert.fail(e.getMessage()); System.out.println(e.getMessage()); } return R.ok().put("data",respMap); } }
JSR303校验
//BindingResult 绑定错误信息 public R save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand,BindingResult result){ if(result.hasErrors()){ Map<String,String> map = new HashMap<>(); //1、获取校验的错误结果 result.getFieldErrors().forEach((item)->{ //FieldError 获取到错误提示 String message = item.getDefaultMessage(); //获取错误的属性的名字 String field = item.getField(); map.put(field,message); }); return R.error(400,"提交的数据不合法").put("data",map); }else { } brandService.save(brand); return R.ok(); }
import com.atguigu.common.exception.BizCodeEnume; import com.atguigu.common.utils.R; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.BindingResult; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.ModelAndView; import java.util.HashMap; import java.util.Map; /** * 集中处理所有异常 */ @Slf4j //@ResponseBody //@ControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller") @RestControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller") public class GulimallExceptionControllerAdvice { @ExceptionHandler(value= MethodArgumentNotValidException.class) public R handleVaildException(MethodArgumentNotValidException e){ log.error("数据校验出现问题{},异常类型:{}",e.getMessage(),e.getClass()); BindingResult bindingResult = e.getBindingResult(); Map<String,String> errorMap = new HashMap<>(); bindingResult.getFieldErrors().forEach((fieldError)->{ errorMap.put(fieldError.getField(),fieldError.getDefaultMessage()); }); return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(),BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",errorMap); } @ExceptionHandler(value = Throwable.class) public R handleException(Throwable throwable){ log.error("错误:",throwable); return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg()); } }
自定义校验
导入依赖
日期格式化
elasticsearch
查看虚拟机内存可用:free -m
docker查看应用日志: docker logs 应用名
1、_cat
GET /_cat/nodes:查看所有节点
GET /_cat/health:查看 es 健康状况
GET /_cat/master:查看主节点
GET /_cat/indices:查看所有索引 show databases;
2、索引一个文档(保存)
3、查询文档
GET customer/external/1 结果: { "_index": "customer", //在哪个索引 "_type": "external", //在哪个类型 "_id": "1", //记录 id "_version": 2, //版本号 "_seq_no": 1, //并发控制字段,每次更新就会+1,用来做乐观锁 "_primary_term": 1, //同上,主分片重新分配,如重启,就会变化 "found": true, "_source": { //真正的内容 "name": "John Doe" } } 更新携带 ?if_seq_no=0&if_primary_term=
4、更新文档
POST customer/external/1/_update { "doc":{ "name": "John Doew" } }
}
不同:POST 操作会对比源文档数据,如果相同不会有什么操作,文档 version 不增加 PUT 操作总会将数据重新保存并增加 version 版本;
带_update 对比元数据如果一样就不进行任何操作。
看场景; 对于大并发更新,不带 update; 对于大并发查询偶尔更新,带 update;对比更新,重新计算分配规则。
全文检索字段用 match,其他非 text 字段匹配用 term。
nginx反向代理