派大星的博客

很多事情不是会了才能做,而是做了才能学会


  • 首页

  • 标签

  • 分类

  • 关于

  • 搜索

Windows下交叉编译Go

发表于 2019-02-23 | 分类于 go

1. Windows下

编译为Linux可运行文件

1
2
3
4
SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build main.go

编译为MAC可运行文件

1
2
3
4
SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build main.go

编译为Window可运行文件

1
2
SET GOOS=windows
go build main.go

2. MAC下

编译为Windows可执行文件

1
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go

编译为Linux可执行文件

1
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go

3. Linux下

编译为Windows可执行文件

1
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go

编译为MAC可执行文件

1
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build main.go

GoLang module操作

发表于 2019-02-23 | 分类于 go

@[toc]

环境

Windows10
GO:1.13

前期设置

不同版本开启GO module

1.11和1.12版本

将下面两个设置添加到系统的环境变量中

1
2
GO111MODULE=on
GOPROXY=https://goproxy.io

1.13版本之后

需要注意的是这种方式并不会覆盖之前的配置,有点坑,你需要先把之前的给删掉再设置

1
2
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct

goLand开启 go mod

go get使用

使用go module之后,go get 拉取依赖的方式就发生了变化

  • 拉取最新的版本(优先择取 tag)

    1
    go get golang.org/x/text@latest
  • 拉取 master 分支的最新 commit

    1
    go get golang.org/x/text@master
  • 拉取 tag 为 v0.3.2 的 commit

    1
    go get golang.org/x/text@v0.3.2
  • 拉取 hash 为 342b231 的 commit,最终会被转换为 v0.3.2:

    1
    go get golang.org/x/text@342b2e
  • 更新

    1
    go get -u

其它基本操作

  1. 初始化一个moudle,模块名为你项目名

    1
    go mod init 模块名
  2. 下载modules到本地cache

    目前所有模块版本数据均缓存在 $GOPATH/pkg/mod和 ​$GOPATH/pkg/sum 下

    1
    go mod download
  3. 编辑go.mod文件
    选项有-json、-require和-exclude,可以使用帮助go help mod edit

    1
    go mod edit
  4. 以文本模式打印模块需求图

    1
    go mod graph
  5. 删除错误或者不使用的modules

    1
    go mod tidy
  6. 生成vendor目录

    1
    go mod vendor
  7. 验证依赖是否正确

    1
    go mod verify
  8. 查找依赖

    1
    go mod why

高级操作

  1. 更新到最新版本
    1
    go get github.com/gogf/gf@version

如果没有指明 version 的情况下,则默认先下载打了 tag 的 release 版本,比如 v0.4.5 或者 v1.2.3;如果没有 release 版本,则下载最新的 pre release 版本,比如 v0.0.1-pre1。如果还没有则下载最新的 commit

  1. 更新到最新的修订版(只改bug的版本)
1
go get -u=patch github.com/gogf/gf
  1. 替代只能翻墙下载的库

    1
    2
    go mod edit -replace=golang.org/x/crypto@v0.0.0=github.com/golang/crypto@latest
    go mod edit -replace=golang.org/x/sys@v0.0.0=github.com/golang/sys@latest
  2. 清理moudle 缓存

    1
    go clean -modcache
  3. 查看可下载版本

    1
    go list -m -versions github.com/gogf/gf

将redis和mongodb服务安装到系统服务中

发表于 2019-02-21 | 分类于 数据库,redis

安装mongodb服务

1
2
3
mongod --logpath E:\MongoDB\logs\mongodb.log --logappend --dbpath E:\MongoDB\data --directoryperdb --

serviceName MongoDB --install

安装redis服务

1
redis-server.exe --service-install redis.windows.conf --loglevel verbose

MySQL中ignore,replace的使用

发表于 2019-02-21 | 分类于 mysql

insert ignore

当出现主键或唯一索引重复之后,插入会失败,但不会报错,会忽略此次插入

用法:

1
2
3
4
#id为主键
insert into user(id,name,age)values(1,"小华",21)
#由于主键冲突,这个插入将会被忽略
insert ignore into user(id,name,age)values(1,"小明",21)

replace to

当出现主键或唯一索引重复之后,会删除原先的数据,并将这个新的记录插入进去

用法:

1
2
# 由于主键冲突,它会删除原先的记录,再把这个记录插入进来
replace into user(id,name,age)values(1,"小花",23);

on duplicate key update

当出现主键或唯一索引重复之后,则执行UPDATE语句

用法:

1
2
# 由于主键冲突,它只会执行 Update语句
insert into user(id,name,age)values(1,'杰克', 22) ON DUPLICATE KEY UPDATE name='杰克',age=22;

下面列举几个常用的场景

获取记录或初始化记录

当记录存在时则获取此条记录,当记录不存在时,则插入记录

1
2
3
4
# 1.先插入数据,如果有记录将会忽略此次插入,如果没有则插入
insert ignore into user(id,name,age)values(1,"小明",21)
# 2. 再获取数据
select * from user where id = 1

插入记录或更新记录

直接使用on duplicate key update语法就OK了

1
insert into user(id,name,age)values(1,'杰克', 22) ON DUPLICATE KEY UPDATE name='杰克',age=22;

新数据更新原始数据

使用replace into语法,当新的数据产生时,用新的去替换老的,这样数据库中关于此主键只会是最新的数据

1
replace into user(id,name,age)values(1,"小花",23);

使用docker安装rabbitmq

发表于 2019-02-21 | 分类于 工具使用,docker

1. 拉取镜像

1
docker pull rabbitmq:management

带有mangement的是包含web管理页面的

2. 启动容器

1
docker run -d --hostname rabbitmq --name rabbitmq -p 5672:5672 -p 15672:15672 -v D://www/rabbitmq:/var/lib/rabbitmq rabbitmq:management
  • -d 后台运行容器;
  • --name 指定容器名;
  • -p 指定服务运行的端口(5672:应用访问端口;15672:控制台Web端口号);
  • -v 映射目录或文件;将D判断 www下的rabbitmq 文件夹映射到docker中
  • --hostname 主机名(RabbitMQ的一个重要注意事项是它根据所谓的 “节点名称” 存储数据,默认为主机名);

注意
如果无法访问web,或rabbitmq容器自动退出,请将映射端口 15672改为 8080尝试一下!
还有,有时候Windows的映射会出现问题,如果上面命令无法打开web页面,请尝试使用下面的命令开启容器:

1
docker run -d --hostname rabbitmq --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management

3. 访问Web页面

打开浏览器: http://localhost:15672 即可看到rabbitmq页面

默认的登录账户和密码都是:guest

使用Node构建桌面GUI

发表于 2019-02-21 | 分类于 nodejs

1. 安装 NVM

它是Node.js的版本管理工具,使用它可以很方便的安装各个版本的Node.js
下载地址: https://github.com/coreybutler/nvm-windows/releases

简单使用:

  1. 安装Node.js

    使用nvm install version arch命令下载需要的版本。arch参数表示系统位数,默认是64位,如果是32位操作系统,需要执行命令:nvm install v10.16.1 32

    1
    nvm install v10.16.1

查看最新版本:https://nodejs.org/en/

  1. 切换版本

    1
    nvm use v10.16.1
  2. 查看本机安装了那些版本

    1
    nvm list
  3. 换源(淘宝镜像)

    1
    npm config set registry https://registry.npm.taobao.org

2. 安装electron

electron 安装文档:https://electronjs.org/docs

1
npm install -g electron

3. 使用electron

  1. 初始化一个Node项目
    1
    npm init

这里输入一些项目基本信息就OK了,可以一路回车,最后会生成一个package.json文件

  1. 添加electron到项目中

    1
    2
    3
    4
    # 将electron添加到项目中
    npm install --save-dev electron
    # 安装
    npm install
  2. 修改package.json

    将 test 那块修改为 "start": "electron ."

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "name": "electron",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "start": "electron ."
    },
    "author": "",
    "license": "ISC",
    "devDependencies": {
    "electron": "^6.0.0"
    }
    }
  3. 新增入口index.js文件

    在项目根目录下新建index.js文件,文件里面的内容直接用electron提供的示例了。点击查看

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    const { app, BrowserWindow } = require('electron')

    function createWindow () {
    // 创建浏览器窗口
    let win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
    nodeIntegration: true
    }
    })
    // 加载index.html文件
    win.loadFile('index.html')
    }
    app.on('ready', createWindow)
  4. 新建index.html文件

    通过上面的js我们可以看到,它其实是加载的index.html文件,我们创建它,简单的写个HelloWorld

1
2
3
4
5
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
  1. 运行程序
    1
    npm start

这时我们就会弹出了一个GUI界面,如下图所示

SpringBoot使用自定义拦截器

发表于 2019-02-21 | 分类于 springboot,SpringBoot技能大全

1. 定义拦截器配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.pibigstar.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer{

/**
* 拦截器配置
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//只拦截 /admin/路径下的请求
registry.addInterceptor(new AdminInterceptor()).addPathPatterns("/admin/**");
WebMvcConfigurer.super.addInterceptors(registry);
}
}

2. 定义拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.pibigstar.config;

import static org.springframework.test.web.client.match.MockRestRequestMatchers.queryParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;

/**
* 管理员拦截器
* 如果不是管理员则不让其访问
* @author pibigstar
*
*/
public class AdminInterceptor implements HandlerInterceptor{

/**
* 在请求处理之前进行调用(controller方法调用之前)
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {

if (request.getAttribute("userId").equals("admin")) {
//放行
return true;
}
//拦截
return false;
}

/**
* 在整个请求结束之后被调用
* 主要用来进行资源清理 ,一些缓存什么的。
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}

SpringBoot导入导出Excel

发表于 2019-02-21 | 分类于 springboot,SpringBoot技能大全

1 下载jar包

1
2
3
4
5
6
<!-- excel导出工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>

2 导出Excel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package com.briup.apps.poll.web.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import com.briup.apps.poll.bean.Answer;
import com.briup.apps.poll.service.IAnswerService;
import com.briup.apps.poll.util.MsgResponse;

@Controller
@RequestMapping("/excel")
public class ExcelController extends BaseController{

@Autowired
private IAnswerService answerService;

/***
* 下载Excel
* @throws IOException
*/
@GetMapping("download")
public void download() throws IOException{

HSSFWorkbook workbook = new HSSFWorkbook();
//创建一个Excel表单,参数为sheet的名字
HSSFSheet sheet = workbook.createSheet("课调答卷表");

//创建表头
setTitle(workbook, sheet);
List<Answer> answers = answerService.findAll();

//新增数据行,并且设置单元格数据
int rowNum = 1;
for (Answer answer:answers) {
HSSFRow row = sheet.createRow(rowNum);
row.createCell(0).setCellValue(answer.getId());
row.createCell(1).setCellValue(answer.getSelections());
row.createCell(2).setCellValue(answer.getCheckes());
row.createCell(3).setCellValue(answer.getContent());
rowNum++;
}
String fileName = "survey-answer.xlsx";
//清空response
response.reset();
//设置response的Header
response.addHeader("Content-Disposition", "attachment;filename="+ fileName);
OutputStream os = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/vnd.ms-excel;charset=gb2312");
//将excel写入到输出流中
workbook.write(os);
os.flush();
os.close();
}

/***
* 设置表头
* @param workbook
* @param sheet
*/
private void setTitle(HSSFWorkbook workbook, HSSFSheet sheet){
HSSFRow row = sheet.createRow(0);
//设置列宽,setColumnWidth的第二个参数要乘以256,这个参数的单位是1/256个字符宽度
sheet.setColumnWidth(0, 10*256);
sheet.setColumnWidth(1, 20*256);
sheet.setColumnWidth(2, 20*256);
sheet.setColumnWidth(3, 100*256);

//设置为居中加粗
HSSFCellStyle style = workbook.createCellStyle();
HSSFFont font = workbook.createFont();
font.setBold(true);
style.setFont(font);

HSSFCell cell;
cell = row.createCell(0);
cell.setCellValue("序号");
cell.setCellStyle(style);

cell = row.createCell(1);
cell.setCellValue("单选");
cell.setCellStyle(style);

cell = row.createCell(2);
cell.setCellValue("多选");
cell.setCellStyle(style);

cell = row.createCell(3);
cell.setCellValue("简答");
cell.setCellStyle(style);
}
}

导出的结果

再将此Excel读取,代码如下:

3 导入Excel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@PostMapping("upload")
public MsgResponse upload(MultipartFile file) {
if (file==null) {
return error("file不能为空");
}
List<Answer> answers = new ArrayList<>();
try {
HSSFWorkbook workbook = new HSSFWorkbook(new POIFSFileSystem(file.getInputStream()));
//有多少个sheet
int sheets = workbook.getNumberOfSheets();
for (int i = 0; i < sheets; i++) {
HSSFSheet sheet = workbook.getSheetAt(i);
//获取多少行
int rows = sheet.getPhysicalNumberOfRows();
Answer answer = null;
//遍历每一行,注意:第 0 行为标题
for (int j = 1; j < rows; j++) {
answer = new Answer();
//获得第 j 行
HSSFRow row = sheet.getRow(j);
answer.setSelections(row.getCell(1).getStringCellValue());//单选
answer.setCheckes(row.getCell(2).getStringCellValue());//多选
answer.setContent(row.getCell(3).getStringCellValue());//简答
answers.add(answer);
}
}

} catch (IOException e) {
logger.error(e.getMessage(),e);
return error(e.getMessage());
}
return success(answers);
}

欢迎关注我的公众号

使用docker部署SpringBoot项目

发表于 2019-02-20 | 分类于 springboot,docker,SpringBoot技能大全

1.新建一个SpringBoot项目

自己写吧。。。。我放个测试的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.pibigstar.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class IndexController {

@RequestMapping("/")
public String toIndex() {
return "index";
}

@RequestMapping("/hello")
@ResponseBody
public String hello() {
return "Hello pibigstar";
}

}

2. 打包SpringBoot项目成jar包

3. 编写Dockerfile文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Docker image for springboot file run
# VERSION 0.0.1
# Author: pibigstar
# 基础镜像使用java
FROM java:8
# 作者
MAINTAINER pibigstar <741047261@qq.com>
# VOLUME 指定了临时文件目录为/tmp。
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为app.jar
ADD onlineSpider-0.0.1-SNAPSHOT.jar app.jar
# 运行jar包
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

如果是第一次打包,它会自动下载java 8的镜像作为基础镜像,以后再制作镜像的时候就不会再下载了。

4. 部署文件

如果不会安装docker的可以看我之前的博客。。。这里就不赘述了

在服务器中新建一个文件夹用来存放我们的项目文件 mkdir docker

将打包好的jar包和Dockerfile文件上传到此文件夹中,然后进入此文件夹cd docker

5. 制作镜像

执行下面命令, 看好,最后面有个 . 点!

1
docker build -t springboot-demo .

-t 参数是指定此镜像的tag名

制作完成后通过下面命令查看我们制作的镜像

1
docker images

5. 启动容器

有很多人搞不定镜像和容器的关系,其他他俩比较像java中的类与实例,镜像就好比类,而容器就是镜像的一个实例

执行下面命令启动容器

1
docker run -d -p 8081:8080 springboot-demo

-d参数是让容器后台运行
-p 是做端口映射,此时将服务器中的8081端口映射到容器中的8080端口

6. 访问

直接浏览器访问: http://你的服务器ip地址:8081/hello 即可查看效果

css随笔记

发表于 2019-02-20 | 分类于 前端

div下加一条分割线

1
border-bottom:1px solid  #D7D8D9;

头像圆角并旋转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.site-author-image {
display: block;
margin: 0 auto;
padding: $site-author-image-padding;
max-width: $site-author-image-width;
height: $site-author-image-height;
border: $site-author-image-border-width solid $site-author-image-border-color;
border-radius: 60%;
transition: 2.5s all;
}

.site-author-image:hover {
transform: rotate(360deg);
}


.site-author-name {
margin: $site-author-name-margin;
text-align: $site-author-name-align;
color: $site-author-name-color;
font-weight: $site-author-name-weight;
}

.site-description {
margin-top: $site-description-margin-top;
text-align: $site-description-align;
font-size: $site-description-font-size;
color: $site-description-color;
}

立体旋转图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<!DOCTYPE html>
<html lang="zh-cn"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>立体滚动图</title>
<style>
.wrap{
width: 120px;
height: 200px;
margin: 20px;
position: fixed;
top: 15px;
right: 15px;
display: table-cell;
vertical-align: middle;
text-align: center;
z-index: 22;
}
.cube {
width: 120px;
height: 120px;
margin: 0 auto;
transform-style: preserve-3d;
transform: rotateX(-30deg) rotateY(-80deg);
animation: rotate linear 20s infinite;
}
@-webkit-keyframes rotate {
from {
transform: rotateX(0deg) rotateY(0deg);
}
to {
transform: rotateX(360deg) rotateY(360deg);
}
}
.cube div {
position: absolute;
width: 120px;
height: 120px;
opacity: 0.8;
transition: all .4s;
}
.cube .out_front {
transform: rotateY(0deg) translateZ(60px);
}

.cube .out_back {
transform: translateZ(-60px) rotateY(180deg);
}

.cube .out_left {
transform: rotateY(-90deg) translateZ(60px);
}

.cube .out_right {
transform: rotateY(90deg) translateZ(60px);
}

.cube .out_top {
transform: rotateX(90deg) translateZ(60px);
}

.cube .out_bottom {
transform: rotateX(-90deg) translateZ(60px);
}
</style>
<body>

<div class="wrap">
<div class="cube">
<div class="out_front"><img src="https://files-cdn.cnblogs.com/files/cjsblog/cube01.bmp" class="pic"></div>
<div class="out_back"><img src="https://files-cdn.cnblogs.com/files/cjsblog/cube02.bmp" class="pic"></div>
<div class="out_left"><img src="https://files-cdn.cnblogs.com/files/cjsblog/cube03.bmp" class="pic"></div>
<div class="out_right"><img src="https://files-cdn.cnblogs.com/files/cjsblog/cube04.bmp" class="pic"></div>
<div class="out_top"><img src="https://files-cdn.cnblogs.com/files/cjsblog/cube05.bmp" class="pic"></div>
<div class="out_bottom"><img src="https://files-cdn.cnblogs.com/files/cjsblog/cube06.bmp" class="pic">
</div>
</div>
</div>
</body>
</html>
1…11121314
派大星

派大星

137 日志
64 分类
230 标签
GitHub CSDN
© 2019 派大星