在网页的一般开发流程中,我们通常会通过 JS 操作 DOM(对应HTML的描述产生的树),以引起界面的一些变化响应用户的行为。例如,用户点击某个按钮的时候,JS会记录一些状态到JS变量里面,同时通过DOM API操控DOM的属性或行为,进而引起界面一些变化。当项目越来越大的时候,你的代码会充斥着非常多的界面交互逻辑和程序的各种状态变量,这显然不是一个很好的开发模式,因此就有了MVVM的开发模式(例如 React、Vue),提倡把渲染和逻辑分离。简单来说就是不要再让JS直接操控DOM,JS只需管理状态即可,然后再通过一种模板语法来描述状态和界面结构的关系。
常用且特殊的MySQL语句
替换字段中的特殊字符串
1 | -- 将 goods 表字段 title 中的 'AAA' 全部替换成 'BBB' |
2 | UPDATE goods SET title=REPLACE(title, 'AAA', 'BBB') WHERE title LIKE '%AAA%' ; |
日期函数 DATE_FORMAT
DATE_FORMAT(date, format) 将数据库日期按照格式转为字符串
1 | -- 根据时间范围查询 |
2 | DATE_FORMAT(create_time, '%y%m%d') > DATE_FORMAT('2019-03-11', '%y%m%d') |
3 | AND |
4 | DATE_FORMAT(create_time, '%y%m%d') < DATE_FORMAT('2020-03-11', '%y%m%d') |
5 | |
6 | -- 查询生日 |
7 | DATE_FORMAT(birthday, '%m%d') = DATE_FORMAT('12-29', '%m%d') |
INSERT SELECT
1 | -- 给所有女性用户插入一条礼品记录 |
2 | INSERT INTO gift(user_id, name) |
3 | SELECT user_id, '手绳' as name |
4 | FROM user |
5 | WHERE sex='女' ; |
6 | |
7 | -- 将 user 表数据复制到 user_copy 表 |
8 | INSERT INTO user_copy FROM user ; |
UPDATE JOIN
1 | -- 关联user表no字段和customer表的no字段,将user表的其他字段更新到customer表中 |
2 | UPDATE customer c |
3 | JOIN user u |
4 | ON u.no=c.no |
5 | SET c.name=u.name, c.age=u.age; |
Linux中MySQL问题
260-SoftwareEngineering/维护老代码过程中的两难
- 有一份以前程序员写的代码,已经正常运行在生产环境中了,但是代码逻辑规范十分不合理,此时有冲动要动手改这份代码,但又担心修改之后在生产环境中会出错。何时应该修改这类的代码?
230-Web/javascript/工具函数总结
1 | // 获取URL地址参数数组 |
2 | function getQueryFromURL(url) { |
3 | url = url || 'http://qq.com/s?a=b#rd'; |
4 | var tmp = url.split('?'), |
5 | paramStr = (tmp[1] || "").split('#')[0], |
6 | query = paramStr ? paramStr.split('&') : [], |
7 | params = {}; |
8 | for (var i=0; i<query.length; i++) { |
9 | var arg = query[i].split('='); |
10 | params[arg[0]] = arg[1]; |
11 | } |
12 | return params; |
13 | }; |
230-Web/javascript/JavaScript基础数据类型2
数组 Array
定义
1 | var arr1 = ["周一", "周二", "周三"]; |
2 | var arr2 = new Array("2019年", "2020年", "2021年"); |
属性
Array 具有 length 属性,即可获取也可设置。
1 | // 获取数据长度 |
2 | var arrayLength = arr.length; |
3 | // 设置数组长度(超出数组长度的元素将被抛弃) |
4 | arr.length = 2; |
方法
pop();// 取出并删除数组最后一个元素push(element);// 在数组末尾追加元素shifit();// 取出并删除数组第一个元素unshift(element);// 在数组开头添加元素indexOf(element);// 查找元素的第一个位置lastIndexOf(element);// 查找元素的最后一个位置splice(start, length, [e1, ...]);// 从start位置开始删除length个元素,并插入后面的参数元素(相当于替换)
1var arr1 = [2, 4, 6];2arr1.splice(1, 2, 1, 3, 5);3console.log(arr1); // 输出 '[2, 1, 3, 5]'join(char);// 数组元素以字符相连接,并返回字符串sort([fn]);// 默认把元素看做字符串自然排序,也可传入函数自定义排序1var arr2 = [3, 5, 2, 9];2arr2.sort(function(n1, n2) {3return n1 - n2; // 前者大于后者,升序排列4});5console.log(arr2); // 输出 '[2, 3, 5, 9]'
遍历
1 | var arr = ['冰箱', '电视', '手机']; |
2 | // 第1种遍历 |
3 | for (var i=0; i<arr.length; i++) { |
4 | console.log(i, arr[i]); |
5 | } |
6 | |
7 | // 第2种遍历 |
8 | arr.forEach(function(item, index, array){ |
9 | console.log(index, item); |
10 | }) |
扩展
- 查询元素在数组中的位置
对象 Object
函数 function
一个函数应该只返回一种类型的值。
函数中有一个默认的数组变量arguments,存储着传入函数的所有参数。为了使用函数参数方便,建议给参数起个名字。
1 | function fun1(obj, name, value){ |
2 | console.log(arguments); |
3 | console.log(obj); |
4 | console.log(name); |
5 | console.log(value); |
6 | } |
7 | fun1({'id':12}, 'username', '张三'); |
日期 Date
定义
1 | var date1 = new Date(); |
2 | var date2 = new Date(timestamp); // timestamp 毫秒单位的时间戳 |
3 | var date3 = new Date(year, month-1, dayOfMonth, hour, minute, second); |
方法
getFullYear();//获取年份getMonth();//获取月份,月份从0开始,即0表示1月,1表示2月,以此类推getDate();//获取当前月份的第几日getHours();//时getMinutes();//分getSeconds();//秒getTime();// 毫米级时间戳
扩展
1 | /** |
2 | * 扩展Date对象的功能 |
3 | * @param format |
4 | * @returns |
5 | * @example (new Date()).format('yyyy-MM-dd hh:mm:ss') 结果是 2018-08-13 08:42:34 这样的格式 ; |
6 | */ |
7 | Date.prototype.format = function (format) { |
8 | var o = { |
9 | "M+": this.getMonth() + 1, // month |
10 | "d+": this.getDate(), // day |
11 | "h+": this.getHours(), // hour |
12 | "m+": this.getMinutes(), // minute |
13 | "s+": this.getSeconds(), // second |
14 | "q+": Math.floor((this.getMonth() + 3) / 3), // quarter |
15 | "S": this.getMilliseconds() |
16 | // millisecond |
17 | } |
18 | if (/(y+)/.test(format)) { |
19 | format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); |
20 | } |
21 | for (var k in o) { |
22 | if (new RegExp("(" + k + ")").test(format)) { |
23 | format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)); |
24 | } |
25 | } |
26 | return format; |
27 | } |
28 | |
29 | /** |
30 | * 扩展Date对象的功能 |
31 | * 获取上一个月日期对象 |
32 | * @param date |
33 | * @returns {Date} |
34 | */ |
35 | Date.prototype.getPreMonth = function() { |
36 | var year = this.getFullYear(); |
37 | var month = this.getMonth()+1; |
38 | var day = this.getDate(); |
39 | var hour = this.getHours(); |
40 | var minute = this.getMinutes(); |
41 | var second = this.getSeconds(); |
42 | |
43 | var y = year; |
44 | var m = parseInt(month) - 1; |
45 | if (m == 0) { // 如果是一月 |
46 | y = parseInt(y) - 1; |
47 | m = 12; |
48 | } |
49 | |
50 | var monthDays = new Date(y, m, 0).getDate(); //获取 m 月的天数 |
51 | var d = day; |
52 | if (d > monthDays) { |
53 | d = monthDays; |
54 | } |
55 | return new Date(y, m-1, d, hour, minute, second); |
56 | } |
57 | |
58 | |
59 | /** |
60 | * 扩展Date对象的功能 |
61 | * 获取下一个月的日期 |
62 | * @param date |
63 | * @returns {Date} |
64 | */ |
65 | Date.prototype.getNextMonth = function(){ |
66 | var year = date.getFullYear(); |
67 | var month = date.getMonth()+1; |
68 | var day = date.getDate(); |
69 | var hour = date.getHours(); |
70 | var minute = date.getMinutes(); |
71 | var second = date.getSeconds(); |
72 | |
73 | var y = year; |
74 | var m = parseInt(month) + 1; |
75 | if (m == 13) { |
76 | y = parseInt(y) + 1; |
77 | m = 1; |
78 | } |
79 | |
80 | var d = day; |
81 | var monthDays = new Date(y, m, 0).getDate(); // 获取 m 月的天数 |
82 | if (d > monthDays) { |
83 | d = monthDays; |
84 | } |
85 | return new Date(y, m-1, d, hour, minute, second); |
86 | } |
220-Database/MySQL/MySQL问题总结
select count(e.*)
1-- 查询部门gZJiXoCUOo下员工的数量2select count(e.*)3from emp e4join dept d on d.deptno=e.deptno5where d.dname='gZJiXoCUOo';会提示错误:
1mysql> select count(e.*)2-> from emp e3-> join dept d on d.deptno=e.deptno4-> where d.dname='gZJiXoCUOo';5ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '*)6from emp e7join dept d on d.deptno=e.deptno8where d.dname='gZJiXoCUOo'' at line 1正确的SQL语句应该是:
1select count(*)2from emp e3join dept d on d.deptno=e.deptno4where d.dname='gZJiXoCUOo';
MarkDown语法大全
MarkDown 是一种纯文本格式的标记语言。通过简单的标记,使得纯文本具有一定的样式。
比如: # 这是h1标题 这段文本,就可使得 “这是h1标题”文本 具有h1标题的样式了
这是h1标题
优点:
1、因为是纯文本,所以写起来非常简单
2、简单的标记就能实现好看样式,让写作者不用再受样式的困扰,专注于写作
3、目前不论是博客平台,还是云笔记,大部分都支持markdown语法了(不支持就out了)
缺点:
1、需要先学习一些MarkDown的语法(非常建议边写边学)
一、标题
在文字前面加上井号#
语法:#+空格+内容(几个#就表示几级标题)
示例:
1 | # 这是一级标题 |
2 | ## 这是二级标题 |
3 | ### 这是三级标题 |
4 | #### 这是四级标题 |
5 | ##### 这是五级标题 |
6 | ###### 这是六级标题 |
效果:
这是一级标题
这是二级标题
这是三级标题
这是四级标题
这是五级标题
这是六级标题
二、字体
加粗
在文字前后分别加上两个星号*
示例:**粗体**
效果:粗体
斜体
在文字前后分别加上一个星号*
示例:*斜体*
效果:斜体
删除线
在文字前后分别加上两个波浪线~
示例:~~删除线~~
效果:删除线
高亮
在文字前后分别加上两个等号=(有些平台不支持)
示例:==高亮==
效果:==高亮==
上面这几种字体样式可以混用,比如:斜体加粗
示例:***斜体加粗***
效果:斜体加粗
三、列表
无序列表
在文字前面加上减号或加号或星号(- + * 任意一种即可)
示例:
1 | - 中国 |
2 | + 英国 |
3 | * 美国 |
效果:
- 中国
- 英国
- 美国
有序列表
在文字前面加上数字+点+空格
示例:
1 | 1. 打开冰箱 |
2 | 2. 把大象放进冰箱 |
3 | 3. 关上冰箱 |
效果:
- 打开冰箱
- 把大象放进冰箱
- 关上冰箱
列表嵌套
在下级列表前面加上4个空格或者Tab
示例1:
1 | * 中国 |
2 | * 北京 |
3 | * 上海 |
效果:
- 中国
- 北京
- 上海
示例2:
1 | * 炒茄子 |
2 | 1. 洗茄子 |
3 | 2. 撕茄子 |
4 | 3. 炒茄子 |
5 | * 炒番茄 |
6 | 1. 洗番茄 |
7 | 2. 削番茄 |
8 | 3. 炒番茄 |
效果:
- 炒茄子
- 洗茄子
- 撕茄子
- 炒茄子
- 炒番茄
- 洗番茄
- 削番茄
- 炒番茄
四、超链接
语法:[标题](地址)
示例:[LiuChuanV的个人博客](https://liuchuanv.github.io/)
五、图片
语法:
示例:
效果:
六、引用
在文字前面加上大于号>(引用文字要单独一行)
示例:
> 知识就是力量
效果:
知识就是力量
七、分割线
单独一行三个或三个以上的减号或加号或星号或等号
示例:---
效果:
八、代码
行内代码
在代码前后加上一个反引号`
示例:`String a = “行内代码”;`
效果:String a = "行内代码";
代码块
在代码块前后分别加上三个反引号`,这三个反引号各占一行,开头的反引号后可以加上MarkDown支持的语言
示例:
```java
public class HelloWorld{
public static void main(String args[]) {
System.out.print(“Hello Baby!”)
}
}
```
效果:
1 | public class HelloWorld{ |
2 | public static void main(String args[]) { |
3 | System.out.print("Hello Baby!") |
4 | } |
5 | } |
九、表格
单元格之间用竖线|分隔,表头和内容之间用 “栅栏” 分隔
示例:
1 | |姓名|性别|年龄| |
2 | |-|-|-| |
3 | |小明|男|12| |
4 | |小强|男|22| |
5 | |小花|女|20| |
效果:
|姓名|性别|年龄|
|-|-|-|
|小明|男|12|
|小强|男|22|
|小花|女|20|
MarkDown语法大全补充
IDEA创建一个SpringBoot项目
[toc]
看图说话,手把手教你在IDEA中搭建一个SpringBoot项目
点击 File -> New -> Project

选择 Spring Initializr

填写 Group、Artifact 等信息

Tip:Artifact 名称不能包含大写
这和 java 包名的命名规范有相通之处,java 包名不能包含大写字母
选择 Web -> Spring Web

选择项目目录

创建完毕

编写 HelloworldController
1 | package com.liuchuanv.hellworld; |
2 | |
3 | import org.springframework.stereotype.Controller; |
4 | import org.springframework.web.bind.annotation.GetMapping; |
5 | import org.springframework.web.bind.annotation.RequestMapping; |
6 | import org.springframework.web.bind.annotation.ResponseBody; |
7 | |
8 | /** |
9 | * description |
10 | * |
11 | * @author LiuChuanWei |
12 | * @date 2019-11-28 16:00 |
13 | */ |
14 | @Controller |
15 | @RequestMapping("/helloworld") |
16 | public class HelloworldController { |
17 | |
18 | @GetMapping("/sayHello") |
19 | @ResponseBody |
20 | public String sayHello() { |
21 | return "Hello Baby!"; |
22 | } |
23 | } |
Tip:方法 sayHello 的注解 @ResponseBody 作用是将方法返回值写入到response的body里,从而将数据直接返回给浏览器;如果没有加该注解,底层会将方法的返回值封装为ModelAndView对象然后返回。
运行 HelloworldApplication

访问 http://localhost:8080/helloworld/sayHello
