二分算法

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
//
// Created by anska on 2022/3/6.
//
#include <vector>
#include "iostream"
using namespace std;
class Search{
public:
Search(vector<int> &nums,int target){
int left = 0;
int right = nums.size()-1; //闭合区间[a,b]
while(left<right){
int middle = left +((right-left)/2);
if(nums[middle]>target){
right = middle-1; //target在左区间,所以[left,middle-1]
}else if (nums[middle]<target){
left = middle+1; //target在右区间,所以[middle+1,right];
}else{ //找到目标值
std::cout<<middle<<std::endl;
return;
}
}
std::cout<<-1<<std::endl;
return;
}
};
int main() {
std::cout << "Hello, World!" << std::endl;
vector<int> nums = {-1,0,3,5,9,12};
int target = 3;
new Search(nums,target);

return 0;
}

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
class dataCenter {
/**
* 初始化
*/
constructor(fn_list=[],...args) {
this.fn_list = fn_list;
this.data = args
return new Proxy(this.data,this.handler)
}
/**
* handler 数据劫持
*/
handler = () => {
get: function(target, propKey, receiver) {
return Reflect.get(target, propKey, receiver);
},
set: function(target, propKey, value, receiver) {
this.cb(value,receiver)
return Reflect.set(target, propKey, value, receiver);
}
}
/**
* 注册回调->观察者
*/
ob=(fn)=>{
this.fn_list.push(fn)
}
/**
* 发布者
*/
cb=(newvalue,oldValue)=>{
const fn_list = this.fn_list;
for(var i in fn_list){
fn_list[i](newvalue,oldValue)
}
}
remove=(fn)=>{
//在当前回调列表移除该函数
}


}


rust Tcp server

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
use std::net::{TcpListener,TcpStream};
use std::thread;
use std::io::{Read,Write,Error};
/**
Rust 有一套独特的处理异常情况的机制,它并不像其它语言中的 try 机制那样简单。

首先,程序中一般会出现两种错误:可恢复错误和不可恢复错误。

可恢复错误的典型案例是文件访问错误,如果访问一个文件失败,有可能是因为它正在被占用,是正常的,我们可以通过等待来解决。

但还有一种错误是由编程中无法解决的逻辑错误导致的,例如访问数组末尾以外的位置。

大多数编程语言不区分这两种错误,并用 Exception (异常)类来表示错误。在 Rust 中没有 Exception。

对于可恢复错误用 Result<T, E> 类来处理
move 闭包
**/
//handles a single client
fn handle_client(mut stream:TcpStream)->Result<(),Error>{
println!("Incomming connection from :{}",stream.peer_addr()?);
let mut buf=[0;512];
loop {
let bytes_read = stream.read(&mut buf)?;
if bytes_read == 0 { return Ok(()); }
stream.write(&buf[..bytes_read])?;
}
}
fn main() {
let listtener = TcpListener::bind("0.0.0.0:8888").expect("could not bind");
for stream in listtener.incoming(){
match stream {
Err(e)=>{eprintln!("failed:{}",e)}
Ok(stream)=>{
thread::spawn(move||{
handle_client(stream).unwrap_or_else(|error|eprintln!("{:?}",error));
});
}
}
}

}

rust 初步

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
extern crate term;
/**
rust 基础语法
1. 使变量变得"可变"(mutable)只需一个 mut 关键字
2. 重影(Shadowing)重影就是指变量的名称可以被重新使用的机制:
3. Rust的 char 类型大小为 4 个字节,代表 Unicode标量值
复合类型
1.元组用一对( )包括的一组数据,可以包含不同种类的数据:eg:let tup: (i32, f64, u8) = (500, 6.4, 1);
2.数组用一对[ ]包括的同类型数据。
函数
1. fn <函数名> ( <参数> ) <函数体>
加了一个感叹号,说明它不是一个函数,而是一个宏的展开
**/
fn main() {
let mut t=term::stdout().unwrap();
t.fg(term::color::GREEN).unwrap();
write!(t,"hello,").unwrap();
t.fg(term::color::RED).unwrap();
write!(t,"world!").unwrap();
t.reset().unwrap();
}
/**

[dependencies]
term = "0.7.0"

**/

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
use std::net::{TcpListener,TcpStream};
use std::{env, fs, thread};
use std::io::{Read,Write,Error};
use std::ops::Not;
/**
rust socket file server
**/
//handles a single client
fn handle_client(mut stream:TcpStream) ->Result<(),Error>{
let mut args: Vec<String> = env::args().collect();
println!("Incomming connection from :{}",stream.peer_addr()?);
let fileName = args.pop().expect("error");
println!("fileName:{}",fileName);
let mut buf=[0;512];
let mut file = fs::File::open(fileName).unwrap();
while file.read(&mut buf).unwrap()!=0 {
stream.write(&buf);
}
return Ok(());
}
fn main() {
let listtener = TcpListener::bind("0.0.0.0:8888").expect("could not bind");
for stream in listtener.incoming(){
match stream {
Err(e)=>{eprintln!("failed:{}",e)}
Ok((stream))=>{
thread::spawn(move||{
handle_client(stream).unwrap_or_else(|error|eprintln!("{:?}",error));
});
}
}
}
}

linux socket server

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

#include<sys/socket.h>
#include<unistd.h>
#include <netdb.h>
#include<stdlib.h>
#include<netinet/in.h>
#include <sys/types.h>
#include <netinet/in.h>
#include<stdio.h>
#include <arpa/inet.h>
int main(int argc, char const *argv[])
{

int sockfd,client_sockfd;

struct sockaddr_in my_addr,client_addr;

int addr_len;

my_addr.sin_family = AF_INET;

my_addr.sin_port = htons(9000);

my_addr.sin_addr.s_addr=INADDR_ANY;

sockfd = socket(AF_INET,SOCK_STREAM,0);

bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr));


//max queue 10
listen(sockfd,10);

addr_len = sizeof(struct sockaddr);

while (1)
{

printf("server is waiting for client to connect:\n");


socklen_t client_size;

client_sockfd = accept(sockfd, (struct sockaddr *)&client_addr,&client_size);

printf("Client ip address=%s\n",inet_ntoa(client_addr.sin_addr));

char *hello = "hello";

send(client_sockfd,hello,sizeof(hello),0);

printf("disconnect the client request\n");

close(client_sockfd);

}

close(sockfd);

return 0;
}

打完收工

操作步骤
1.生成csr文件(通过OpenSSL命令)
2.生成mobileprovision文件(通过Apple开发者后台)
3.生成cer文件(通过Apple开发者后台)
4.生成P12文件(通过OpenSSL命令)
5.生成csr文件

用到 Windows 或者 Linux 下的 openssl 命令,请自行安装。
1
2
openssl genrsa -out ios.key 2048
openssl req -new -sha256 -key ios.key -out ios.csr
生成mobileprovision文件

比较简单,登录开发者后台,提交信息(需要用到前面生成的csr文件),下载。
https://developer.apple.com/account/ios/profile/

生成cer文件

比较简单,登录开发者后台,提交信息(需要用到前面生成的csr文件),下载。
https://developer.apple.com/account/ios/certificate/

生成P12文件

需要用到第一步生成的 ios.key 文件,以及 Apple 生成的 ios_distribution.cer 和 ios_development.cer 文件。

1
2
3
4
openssl x509 -in ios_distribution.cer -inform DER -outform PEM -out ios_distribution.pem
openssl pkcs12 -export -inkey ios.key -in ios_distribution.pem -out ios_distribution.p12
openssl x509 -in ios_development.cer -inform DER -outform PEM -out ios_development.pem
openssl pkcs12 -export -inkey ios.key -in ios_development.pem -out ios_development.p12

一个webcomponent

index.html

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
 <!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webcomponent</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.14/webcomponents-hi.js"></script>
<link rel="import" href="orderList.html" />
</head>

<body>
<order-list v-for="arr">
<div slot="render">#item</div>
</order-list>
</body>
<script type="text/javascript" src="./store.js"></script>
<script type="text/javascript">
var store = new Store(function data() {
return {
arr: [1, 2, 3, 4, 5]
}
})
window.store = store;

</script>

</html>

Store.js

1
2
3
4
5
6
 class Store {
constructor(data) {
window.data = data()
}
}
window.Store = Store;

orderList.html

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
 <template id="orderList">
<slot name="render" id="render"></slot>
</template>
<script type="text/javascript">
class orderList extends HTMLElement {
constructor() {
super()
// 查找模板内容
const content = document.querySelector('#orderList').content;
// 创建Shadow DOM
const shadowDOM = this.attachShadow({ mode: 'open' });
// 将模板添加到Shadow DOM上
shadowDOM.appendChild(content.cloneNode(true));
var r = this.getAttribute("v-for");
this.renderItem(data[r])
}
renderItem(data) {
var subItem = document.querySelector('div[slot="render"]');
var template = document.querySelector("#orderList")
var strTemplate = ``;
for (var i in data) {
var html = subItem.innerHTML;
console.log("div", subItem.nodeName)
var nodeName = subItem.nodeName.toLocaleLowerCase();
var that = this;
html.replace(/#item/g, function (a) {
console.log("a",a)
var dom = document.createElement(nodeName);
dom.innerHTML = data[i];
subItem.appendChild(dom.cloneNode(true))
})
}
}
//首次插入DOM文档时调用
connectedCallback() {
//在这里发送数据请求(Ajax)
}
//被从文档DOM中删除时调用
disconnectedCallback() {
console.log("n")
}
//被移动到新的文档时调用
adoptedCallback() {
console.log("c")
}
//当增加、删除、修改自身的属性时被调用
attributeChangedCallback() {
console.log("d")
}
}
window.customElements.define('order-list', orderList);
</script>

Makefile规则格式

目标….. : 依赖文件集合…..

命令1

命令2

命令3

更新依赖

比如下面这条规则

1
2
3
4
5

main: main.o input.o calc.o

gcc -o main main.o output.o calc.o

这条规则的目标是main,main.o,input.o和calcu.on是生成main的文件

  • 如果更新目标main,就必须先更新它的所有依赖文件
  • 如果依赖文件中的任何一个有更新,那么目标也必须更新

“更新”就是执行一遍规则中的命令列表

用”tab”无空格

命令列表中的每条命令必须以Tab建开始, 不能使用空格

make命令会为MakeFile中的每个以TAB开始的命令创建一个shell进程去执行

MakeFile执行顺序

示例分析

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
  
main: main.o input.o calcu.o

gcc -o main main.o input.o calcu.o

main.o : main.c

gcc -c main.c

input.o:input.c

gcc -c input.c

calcu.o:calcu.c

clean:

rm *.o

rm main


```

上诉代码一共有5条规则

* 1-2行为第一条规则

* 3-4行为第二条规则

* 5-6行为第三条规则

* 7-8行为第四条规则

* 10-12为第五条规则

make命令在执行这个Makfefile的时候其执行步骤如下

1. 首先更新第一条规则中的main,第一条规则的目标成为默认目标,只要默认目标更新了就认为Makefile的工作完成

2. 在第一次编译的时候由于main还不存在,因此第一条规则会执行,第一条规则依赖于文件main.o,inout.o,和calu.o

3. 这三个.o文件目前都还没有,因此必须先更新这三个文件,make会查找以这三个.o文件为目标的规则并执行。以main.o

文件为例,发现更新main.o是第二条规则,因此会执行第二条规则,第二条规则里面的命令以"gcc -c main.c",这行命令

很熟悉了吧,就是不链接编译main.c,生成main.o,其他两个.o文件同理。

4. 最后一个规则目标是clean,它没有依赖文件,因此会默认依赖文件都是最新的,所以其对应的命令不会执行,当我们

想要执行clean的话可以直接使用命令"make clean",执行以后就会删除当前目录下所有.o文件以及main,因此clean的功能

就是完成工程的清理,"make clean"的执行过程如图所示(当执行"make clean"命令以后,前面编译出的的.o文件和main可

执行文件都被删除了,也就是完成了工程清理工作)


#### make工具就是在makefile中一层一层的查找依赖和关系,并执行相应的命令,编译出最终的可执行文件

Makefile的好处是"自动化编译",一旦写好了makefile文件,以后只需要一个make命令既可完成整个工程的编译,极大的提高了

开发效率。

除了Makefile的"终极目标"所在的规则以外,其他规则的顺序在Makefile中是没有意义的。

"终极目标"就是指在是使用make命令的时候没有指定具体的目标时,make默认的那个目标,它是Makefile文件中的第一个规则的

目标,如果Makefile中的第一个规则有多个目标,那么这些目标中的第一个目标就是make的"终极目标"

#### Makefile变量

跟C语言一样MakeFile也支持变量的,先看一下前面的例子

main: main.o input.o calcu.o

gcc -o main main.o input.o input.o calcu.on

1
2
3
4
5
6
7
8
9

上诉Makefile语句中,main.o input.o和calcu.o的三个依赖文件,我们输入了两遍,我们这个Makefile

比较小,如果Makefile复杂的时候这种重复输入的工作机会非常浪费时间,而且容易输错

为了解决这个问题,Makefile加入了变量的宏,不像C语言中的变量有int,char等各种类型,MakeFile中的变量

都是字符串!,类似C语言中的宏。使用变量将上面的代码修改,修后以后如下所示

#MakeFile 变量的使用

objects = main.o input.o calcu.o

main: ${objects}

gcc -o main ${objects}

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

我们来分析一下上诉Makefile

* 第一行的事注释,Makkefile中可以写注释,注释开头要用符号"#,不能使用C语言中的"//"或者"/**/"

* 第二行中我们定义了一个变量objects,并且给这个变量进行了赋值,其值为字符串“main.o input.o calcu.o ”

* 第三行和第四行用到了变量objects,Makefile中变量的引用方法是"${变量名}",比如本例中"${objects}"就是使用变量

在"示例代码"中我们在定义变量objects的时候使用“=”对其进行了赋值,Makefile变量的赋值符还有其他两个":="和"?="

#### 赋值符"="

使用"="在给变量赋值的时候,不一定要用已定义好的值,也可以使用后面定义的值,比如如下代码

#### 赋值符:":="

因为赋值符":="不会使用后面定义的变量,只能使用前面已经定义好的,这就是"="和":="的两个区别

#### 赋值符: "?="

如果前面的变量没有赋值,那么此变量就赋正在赋予的值

#### Makefile模式规则

模式规则中,至少在规则的目标中定义要包含"%",否则就是一般规则,当"%"出现在目标的时候,目标中"%"

所代表的值决定了依赖中的"%"值

目标中的“%”表示对文件名的匹配,"%"表示长度任意的非空字符串,比如"%.c"就是所有以.c结尾的文件**,

类似于通配符**,类似于通配符**,a.%.c表示以a开头,以c结尾的所有文件

#### MakeFile自动化变量

目标和依赖中都是一系列的文件,每一次对模式规则进行解析的时候都会是不同的目标和依赖文件,而命令只有一行,

如何通过一行命令从不同的依赖文件中生成对应的目标?自动化变量就是完成这个动作的

所谓自动化变量就是这种变量会把模式中所定义的的一系列的文件自动的挨个取出,直至所有的符合模式的文本

都取出,自动化变量只出现在规则的命令中

#### $@ 规则中的目标集合,在模式规则中,如果有多个目标的话,"$@"表示匹配模式中定义的目标集合

#### $% 当目标是库函数的时候表示规则中的目标成员名,如果目标中不是库函数文件,那么其值为空

#### $< 依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%”)定义的,那么"$<"就是符合模式

#### 的一系列的文件集合

#### $^ 所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件,“$^”会去除重复的依赖文件,只保留一份

#### $+ 和"$^"类似,但是当依赖文件存在重复的话不会去除重复的依赖文件

#### $* 这个变量表示目标模式中“%”及其之前的部分,如果目标是test/a.c,目标模式为a.%.c,那么“$”就是test/abbrlink

常用的有三种

```MakeFile

# $@,$<.$^

objects = main.o input.o calcu.o

main: ${objects}

gcc -o main ${objects}

%.o : %.c

gcc -c $<

clean

rm *.o

rm main


Makefile伪目标

Makefile有一种特殊的目标-伪目标,一般的目标名都是要生成的文件,而伪目标不代表真正的目标名,

在执行make命令的时候通过指定这个伪目标来执行其所在规则的定义的命令

而且伪目标主要是避免Makefile的定义的执行命令和工作目录中的目标和工作目录下的实际文件出现名字的冲突

有时候我们需要编写一个规则来执行一些命令,但是这个规则不是用来创建文件的,比如在前面的“示例代码中”有如下

代码用来完成清理工程的功能:

1
2
3
4
5
6
7

clean

rm *.o

rm main

伪目标

当和文件名和Makefile的内置变量有冲突时,使用伪变量,不影响Makefile的内置变量

1
2
3

.PHONY:clean

Makefile条件判断

在C语言中我们通过条件判断语句来根据不同的情况来执行不同的分支,MakeFile也执行条件判断,语法有两种:

1
2
3

<条件关键字><条件为真时执行的语句>

以及

1
2
3
4
5
6
7
8
9

<条件关键字><条件为真时执行的语句>

else

<条件为假时执行的语句>

endif

MakeFile条件控制语句,条件关键字有四个

1
2
3
4
5
6

ifeq (<参数名>,<参数2>)

ifeq '<参数1>','<参数2>'


MakeFile函数使用

MakeFile支持函数,类似C语言一样,MakeFile中的函数是已经定义好的,我们直接使用,不支持我们自定义的函数。

make所支持的函数不多,但是决对够我们使用了,函数的用法如下:

1
2
3
4
5
6
7

$(函数名 参数集合)

或者:

{函数名 参数集合}

  • 调用函数和调用普通变量一样,使用符号”$”来标识

  • 参数集合是函数的多个参数,参数之间以逗号”,”分隔

  • 函数名和参数之间以“空格”分隔开,函数调用以“$”开头

常用函数

subst 字符串替换 $(subst ,,)

此函数的功能是将字符串的中的内容替换成,函数返回被替换以后的字符串,比如如下示例

pathsubst 用来完成模式字符串的字符串替换 $(patsubst ,,)

函数patsubst用来完成模式字符串的替换,此函数查找字符串中的单词是否符合模式,如果匹配就用

来替换,可以使用通配符“%”,表示任意长度的字符串,函数返回值就是替换后的字符串,如果

中也包含“%”,那么中的”%”将是所代表的字符串

dir 函数dir用来获取目录 $(dir <names…>)

此函数用来从文件序列中提取目录的部分,返回值是文件名序列的目录

notdir 从文件名提取非指定目录 $(notdir <names…>)

此函数用于从文件名序列中提取出文件名非目录的部分

foreach $(foreach ,,) 循环

此函数的作用就是把参数中的单词逐一取出来放到参数中中,然后再执行所包含的表达式

每次都会返回一个字符串,循环的过程中,中所包含的每个字符串会以空格隔开,最后当整个循环结束时

所返回的每个字符串组成的每个整个字符串都会是foreach函数的返回值

willdcard (wildacrd pattern) 符合规则的字符串

数据库学习

1.1操作数据库CURD(Mysql不区分大小写)

1.创建数据库

1
create database [IF NOT EXISTS] westos;

2.删除数据库

1
drop database [IF EXISTS] westos;

3.使用数据库

1
use westos;

4.查看数据库

1
show databases;

5.创建表

1
2
3
4
5
6
7
8
9
10
CREATE TABLE `student` (
`id` int(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` varchar(220) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` varchar(220) NOT NULL COMMENT '密码',
`sex` char(2) NOT NULL DEFAULT '女' COMMENT '性别',
`day` datetime DEFAULT NULL COMMENT '出生日期',
`address` varchar(220) NOT NULL DEFAULT '匿地址' COMMENT '地址',
`email` varchar(220) NOT NULL COMMENT '邮箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

6.修改删除表

修改

1
2
3
4
5
6
7
--修改表名称
alter table teacher rename as teacher1;
--增加表字段
alter table teacher add name varchar(220);
--修改表字段 (重命名:修改约束)
alter table teacher modify name varchar(220); --修改约束
alter table teacher change name teacher_name varchar(220); --字段重命名

删除

1
2
---删除表(如果存在再删除)
drop table if exists teacher;

7.插入表数据

INSERT INTO 表名 (id—–) values(id—–)

1
INSERT INTO westos.student (id, name, pwd, sex, day, address, email) VALUES (1, '狗蛋', '12345678', '男', '2021-12-08 13:34:44', '安徽合肥', '5104@sohu.com')

8.修改表数据

Update 表名 SET 字段 =’李四’ where 字段=’***’

1
2
-- 一定要指定条件 where
update student set address ='安徽合肥市' where name='狗蛋';

9.查找表数据

Select 字段名(要什么查什么,全都要就*) from表 where 字段=’ ‘;

1
select id, name, pwd, sex, day, address, email from student where name='狗蛋';

10.删除表数据

DELETE FROM 表 where 字段 =’ ‘

1
DELETE FROM westos.student WHERE id = 2;

所有创建和删除都要添加判断不然会报错

11.逆向语句查询

1
2
show create table student; --查看建表语句
desc student; --查看表结构

12.去重关键字

1
select distinct studentno  from result   --distinct

Where语句

1
2
3
4
5
6
7
8
9
10
--查询考试成绩在90分以上100分一下
select studentno ,studentresult from result where studentresult >= 90 && result.studentresult<=100;
--区间查询
--between a between b and c A在BC之间为true
select studentno,studentresult from result where studentresult between 95 and 100;
--除了1000号之外所有学生的成绩
select studentno ,studentresult from result where result.studentno<>1000;
select studentno ,studentresult from result where result.studentno!=1000;
select studentno ,studentresult from result where not result.studentno =1000;

Like语句

1
2
3
4
5
6
--开头是姓刘的  %(代表0到任意一个字符)  _代表一个字符
select studentno, studentname from student where student.studentname like '刘%';
--后面是一个字符开头是刘的人
select studentno, studentname from student where student.studentname like '刘_';
--左右匹配带刘的都展示
select studentno, studentname from student where student.studentname like '%刘%';

in语句

1
2
--查询某个区间  他是一个或者多个具体的值
select studentno,studentname from student where studentno in (1001,1002,1003);

null not null 语句

1
2
select studentno,studentname from student where address is null;
select studentno,studentname from student where address is not null;

联表查询 join

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
select s.studentno, studentname, subjectno, studentresult
from student s
inner join
result r
where s.studentno = r.studentno;

#左查询
select s.studentno, studentname, subjectno, studentresult
from student s
left join result r
on s.studentno = r.studentno;

#右查询
select s.studentno, studentname, subjectno, studentresult
from student s
right join
result r
on s.studentno = r.studentno;


select s.studentno, studentname, subjectname, studentresult
from student s
right join result r
on r.studentno = s.studentno
inner join subject sub
on r.subjectno = sub.subjectno;

分页limit和排序 orderby

1
2
3
4
5
6
7
8
9
--desc 降序  esc升序
select r.studentno, studentname, subjectname, studentresult
from result r
left join student s
on r.studentno = s.studentno
inner join subject sub
on r.subjectno = sub.subjectno
where sub.subjectname like '%C%'
order by studentresult desc
1
2
3
4
5
6
7
8
9
select s.studentno,studentname,subjectname,studentresult
from student s
inner join result r
on s.studentno = r.studentno
inner join subject sub
on sub.subjectno=r.subjectno
where sub.subjectname like '%C%' && r.studentresult > 30
order by r.studentresult desc
limit 0,10

联表查询 和 子查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
--子查询
select s.studentno,studentname
from student s
inner join result r on s.studentno = r.studentno
where r.studentresult >=30 and subjectno = (
select subjectno from subject where subjectname = 'C语言-1'
);

select s.studentno,studentname
from student s
inner join result r on s.studentno = r.studentno
inner join subject s2 on r.subjectno = s2.subjectno
where r.studentresult>=30 && s2.subjectname='C语言-1'


分组查询

1
2
3
4
5
6
select subjectname,max(studentresult),min(studentresult),avg(studentresult)
from result r
inner join subject s on r.subjectno = s.subjectno
group by r.subjectno ----通过什么来分组
having avg(studentresult)>=70 ----分组过后用having来再次筛选数据 而不是where
;

聚合函数

1
2
3
4
5
6
7
8
9
select count(address)from student; --会去掉null值
select count(1)from student; --不忽略null值
select count(*)from student; --不忽略null值
select count(studentname) from student where studentname ='铁蛋';

select sum(studentresult) 总分 from result;
select avg(studentresult) 平均 from result;
select max(studentresult) 最高 from result;
select min (studentresult) 最低 from result;

事务原则:原子性,一致性,持久性,隔离性(ACID) (脏读幻读)

原子性(Atomicity)

一个事务要么全部提交成功,要么全部失败回滚,不能只执行其中的一部分操作,这就是事务的原子性

一致性(Consistency)

事务前后的数据完整性要保持一致 事务前总金额1000 事务后也是1000

持久性(Durability)

事务一旦被提交 那就持久化到数据库中 不可逆

隔离性(Isolation)

事务的隔离性是指在并发环境中,并发的事务时相互隔离的,一个事务的执行不能不被其他事务干扰。不同的事务并发操作相同的数据时,每个事务都有各自完成的数据空间,即一个事务内部的操作及使用的数据对其他并发事务时隔离的,并发执行的各个事务之间不能相互干扰。

隔离所导致的问题

脏读

指一个事物读取了另一个事务未提交的数据

不可重复读

在一个事务中读取表的某个数据,多次读取不同(不一定是读取错误,可能是某些场合不对)

幻读 虚读

是指在一个事务内读取到了其他事务插入的数据,导致前后读取不一致

0%