谷粒商城笔记1

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.conf

docker 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反向代理

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值