前端

一 、 登录界面

(1)用vite脚手架创建项目

工程化方式,采用脚手架工具创建一个vue工程,然后进行开发;(项目开发广泛使用)

image-20240218233633476

(2)vue项目的工程结构说明

image-20240218234826841image-20240219000847361

image-20240219000858770

image-20240219000912548

image-20240219000919973

(3)启动Vue项目工程

1
2
3
4
5
6
7
//以下是为了修改端口 之前的(老版本)vue端口占了8080,这里
vite,config.js:

server:{
host:'127.0.0.1',
port:8081,
open:true,
1
2
3
4
cd dlyk_front
npm install 或者 npm i
npm run dev

(4)开始Vue的项目开发

  • 最基础的文件

    最基础的就是.vue文件,这个文件的就是vue界面,也成为vue组件,一般来说是分为三个部分:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    1. //<template> 这个里面写了一个html业面要展示的内容

    //</template>

    2. //<script> 这个里面鞋的是javascript的代码

    //</script>

    3. //<style> 这里写的是css的样式
  • vue工程的运行流程分析

    ==项目的运行入口:main.js==

1
2
3
4
5
6
7
8
9
10
11
import { createApp } from 'vue'//createApp是函数
import './style.css'
import App from './App.vue'//从一个单文件组件中导入根组件

createApp(App)
.mount('#app')
//利用导入的函数 创建一个vue应用
//挂载到页面的#app这个id下,id在index.html<div id='app'>
//动态渲染在这个div里
//运行一下,把运行的结果放在这个id的标签下

  • 登录页面使用的技术

    vue – controller - service – manager - mapper ( mysql、redis)

    页面使用了element-plus进行页面开发;

    1. element plus安装

我们的项目,需要使用到一些页面的效果(表单、输入框、表格、按钮、布局、图标等等),我们采用的都是element-plus给我们提供的;

1
2
3
4
5
6
7
1、项目中要安装element-plus:
npm install element-plus --save
npm i element-plus --save
-g 全局安装,安装到D:\course\tool\node-v20.9.0-win-x64\node_global
--save表示安装包信息会写入package.json的dependencies中,在dependencies中,那么项目打包就会依赖到该模块;
--save-dev上线不需要用,如果项目打包时不需要依赖该模块,那么就使用--save-dev,它会在devDependencies下,表示项目开发需要依赖该模块,项目打包发布就不需要它;

2、导入element-plus

1
2
3
4
5
6
7
8
在main.js中

import ElementPlus from 'element-plus'
//css不用 from
import 'element-plus/dist/index.css'

createApp(App).use(ElementPlus).mount('#app')
//挂载一定是最后一步

3. element提供的组件

设计 | Element Plus (gitee.io)

element-plus提供的组件:

1、Basic 基础组件

2、配置组件

3、Form 表单组件

4、Data 数据展示

5、Navigation 导航

6、Feedback 反馈组件

7、Others 其他

image-20240219004142653

4. 布局

这里是利用element实现最简单的左右布局,由于我们不弄前端,这个浅浅了解就行,无需非常深入

step1:创建新vue component

composition api:大项目 、推荐

options api :初学者

创建image-20240219073424268

step2:界面

创建一个view文件夹 ,里面都是要写的一些页面 。

在view文件夹下面 创建LoginView.vue的页面,然后就开始编写。

去element ui的网站里面去复制格局和部件等等。

当要加入表单的时候,就是要从页面获取信息的时候,需要在script里加入一些设置

注意:

要在App.vue处增加内容

1
2
3
4
5
6
7
8
9
10
import { createApp } from 'vue'//createApp这个是一个函数
//import './style.css'
//import App from './App.vue'//从一个单文件组件中导入根组件
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'


import loginView from "./view/LoginView.vue";
createApp(loginView).use(ElementPlus).mount('#app')//创建一个vue对象//挂载到页面的#app这个id下
//上面两句很重要
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
<template>
<el-container>
<!-- 左侧-->
<el-aside width="200px">
<img src="../assets/loginBox.svg">
<p class="imgTitle">
欢迎使用动力云客系统
</p>
</el-aside>
<!-- 右侧-->
<el-main>
<div class="loginTile">欢迎登录</div>
<el-form ref="loginRefForm" :model="user" label-width="120px" :rules="loginRules">
<el-form-item label="账号" prop="loginAct">
<el-input v-model="user.loginAct" />
</el-form-item>

<el-form-item label="密码" prop="loginPwd">
<el-input type="password" v-model="user.loginPwd" />
</el-form-item>

<el-form-item>
<el-button type="primary" @click="login">登 录</el-button>
</el-form-item>

<el-form-item>
<el-checkbox label="记住我" v-model="user.rememberMe" />
</el-form-item>
</el-form>
</el-main>
</el-container>
</template>


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
  //定义页面使用到的变量,定义时初始值都是给个空的
<script>
import {defineComponent} from "vue";

export default defineComponent({
name: "LoginView",

//定义页面使用到的变量,定义时初始值都是给个空的
data() {
return {
//对象变量定义,是{}
user : {},
//字符串变量定义,是''
name : '',
//数字变量定义,是0
age : 0,
//数组变量定义,是[]
arr : [],
//list集合对象(对象数组),是[{}]
userList : [{}],
//定义登录表单的验证规则
loginRules : {
//定义账号的验证规则,规则可以有多个,所以是数组
loginAct : [
{ required: true, message: '请输入登录账号', trigger: 'blur' }
],
//定义密码的验证规则,规则可以有多个,所以是数组
loginPwd : [
{ required: true, message: '请输入登录密码', trigger: 'blur' },
{ min: 6, max: 16, message: '登录密码长度为6-16位', trigger: 'blur' }
]
}
}
},


})
</script>

step3:表单验证

(1)账号字段:loginAct (account)登录账号;

(2)密码字段:loginPwd (password)登录密码;

(3)是否记住我字段:rememberMe

需求:前端非空验证;

1
2
3
1、在<el-form>里面定义一个:rules="rules";
2、在要验证的el-input上的<el-form-item>中定义prop=xx 比如下面的loginAct和pwd,
3、给要验证的字段定义验证规则;

3、给要验证的字段定义验证规则;

  1. 在el-form头标签里面写:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<el-form ref="loginRefForm" :model="user" label-width="120px" :rules="loginRules">
<el-form-item label="账号" prop="loginAct">
<el-input v-model="user.loginAct" />
</el-form-item>

<el-form-item label="密码" prop="loginPwd">
<el-input type="password" v-model="user.loginPwd" />
</el-form-item>
这里是增加了一个点击事件
<el-form-item>
<el-button type="primary" @click="login">登 录</el-button>
</el-form-item>

<el-form-item>
<el-checkbox label="记住我" v-model="user.rememberMe" />
</el-form-item>
</el-form>
  1. 需要在script里面
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
<script>
import {defineComponent} from "vue";

export default defineComponent({
name: "LoginView",

//定义页面使用到的变量,定义时初始值都是给个空的
data() {
return {
//对象变量定义,是{}
user : {},
//字符串变量定义,是''
name : '',
//数字变量定义,是0
age : 0,
//数组变量定义,是[]
arr : [],
//list集合对象(对象数组),是[{}]
userList : [{}],
//定义登录表单的验证规则
loginRules : {
//定义账号的验证规则,规则可以有多个,所以是数组
loginAct : [
{ required: true, message: '请输入登录账号', trigger: 'blur' }
],
//定义密码的验证规则,规则可以有多个,所以是数组
loginPwd : [
{ required: true, message: '请输入登录密码', trigger: 'blur' },
{ min: 6, max: 16, message: '登录密码长度为6-16位', trigger: 'blur' }
]
}
}
},


})
</script>

需要加入这个属性

ref=”loginRefForm”

表示在提交之前 需要执行一下规则

1
<el-form ref="loginRefForm" :model="user" label-width="120px" :rules="loginRules">

image-20240221130953823

1
this.$refs.loginRefForm.validate( (isValid) => {

这个会调用:rules=”loginRules”规则 ,然后得到一个返回值,就是一个验证之后的结果。

如果是true 表示验证通过

​ 验证通过后 ,就表示要提交了。axios 。ajax

反之表示没通过

step4: 使用axios //封装

主要就是封装4个方法;

doGet() 查询

doPost() 新增

doPut() 修改

doDelete() 删除

  1. 创建文件与文件夹

image-20240221140148575

  1. 封装函数

    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
    // 原本这个函数是只有function 但是因为要在别的页面上使用,所以就加上了一个export,这里导出
    //那边导入
    // 从这个框架导入组件
    import axios from "axios";

    export function doGet(url ,params){
    axios({
    method: "get",
    url: url,
    params: params, //{name: "对的", age: 22},
    dataType:"json"
    }).then(function (rep){
    var s ="";
    reo.data.forEach(function (stu){
    s += stu.name + "-------------------"+stu.age+"<br>";
    });
    document.getElementById("mydiv").innerHTML = s;
    })


    }

    export function doPost(url,data ){
    axios({
    method: "post",
    url: url,
    data: data, //{name: "对的", age: 22},
    dataType:"json"
    }).then(function (rep){
    var s ="";
    reo.data.forEach(function (stu){
    s += stu.name + "-------------------"+stu.age+"<br>";
    });
    document.getElementById("mydiv").innerHTML = s;
    })


    }
    export function doPut(url,data ){
    axios({
    method: "put",
    url: url,
    data: data, //{name: "对的", age: 22},
    dataType:"json"
    }).then(function (rep){
    var s ="";
    reo.data.forEach(function (stu){
    s += stu.name + "-------------------"+stu.age+"<br>";
    });
    document.getElementById("mydiv").innerHTML = s;
    })


    }
    export function doDelete(url ,params){
    axios({
    method: "Delete",
    url: url,
    params: params, //{name: "对的", age: 22},
    dataType:"json"
    }).then(function (rep){
    var s ="";
    reo.data.forEach(function (stu){
    s += stu.name + "-------------------"+stu.age+"<br>";
    });
    document.getElementById("mydiv").innerHTML = s;
    })


    }

step4: 使用axios //封装

一般提交是使用一个表单,然后用put提交,也可以用get 但是一般用put

1
2
3
在httpRequest.js开始处
//定义端口的地址,默认地址前缀,
axios.defaults.baseURL = "http://localhost:8089";

(5)动力云客后端项目创建

image-20240221145546841

image-20240221150859764image-20240221150910929

image-20240221150924045

(6)编写yml配置文件

进入image-20240222102204105

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
server:
port: 8089//端口 这里改成了8089
servlet:
context-path: /

#配置数据库连接相关信息
spring:
datasource:
url: jdbc:mysql://localhost:3306/dlyk?useUnicode=true&characterEncoding=utf8&useSSL=false//这里是链接数据库
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
hikari:
#最大连接数,默认是10
maximum-pool-size: 30
#最小空闲连接,默认是10
minimum-idle: 30
#等待连接池分配连接的最大时长,超过该时长还没有可用连接则发生超时异常(单位毫秒)
connection-timeout: 5000
#空闲连接的最大时长,空闲多久就被释放回收,设置为0不让连接回收
idle-timeout: 0
#一个连接的最大生命时间,超过该时间还没有使用就回收掉(单位毫秒),最好不要超过8小时
max-lifetime: 18000000


#配置redis的连接信息
data:
redis:
host: 127.0.0.1//redis的host 要去看redis的配置。
port: 6379
password: 123456
database: 1

#设置jackson返回json数据时,时区和格式
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss

#指定一下mapper.xml文件的位置
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
#在控制台打印sql语句
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

#定义定时任务的调度时间
project:
task:
cron: '* */5 * * * *'
delay: 180000

(7)mysql反向工程生成表

image-20240222102505798

image-20240222102955294

注意:Free Mybatis plugin 直接在setting –> plugin 搜索下载就行,然后选中数据库里面的所有表,点击mybatis generator ,

image-20240222120628352

生成结果

image-20240222120824860

(8)加入mapper包的扫描

image-20240222121147528

加入

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

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

//!!!!!!!!!! 加入这个
@MapperScan(basePackages = {"com.bjpowernode.mapper"})
@SpringBootApplication
public class DlykServerApplication {

public static void main(String[] args) {
SpringApplication.run(DlykServerApplication.class, args);
}

}

此外 ,由于mapper的xml(sql语句文件)与mapper不在一个文件夹下面,所以需要指定一下,在application.yml中指定

1
2
3
4
5
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
#??????sql??
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

一、技术的版本控制

image-20240218015738084

image-20240218015750388

image-20240221152352894

image-20240221152403852

image-20240221152414970

image-20240221152423433

二、动力云客的项目概述

这个项目就是一个商业的集合营销销售为一体的客户关系管理系统,采用信息化、数字化的方式来进行营销和看客户管理。

1.项目数据库:Mysql一个数据库

2.前端项目:

这是一个前后端分离的项目 (前端vue–>(ajax axios) http请求–>后端项目(spring boot)

(1) node.js是一个开源的跨平台的JavaScript运行时环境,类似java的jvm

(2) npm JavaScript依赖包管理器 ,全世界都可以用这个来共享javascript包,负责前端项目的打包,插件的下载 node package manager

(3)Vite 是快速构建前端Vue项目的脚手架,可以理解为开发Spring boot的Spring initializr的快速构建工具。(之前是用vue-cil的)

1
npm create vite@latest//

三、启动之前的项目

用的是jdk17 ;

前端跑起来需要进入package.json 在scripts 处 跑dev

1. admin的密码

1
2
3
4
UPDATE t_user
SET login_pwd = '$2a$10$t1ZZqt3jgYNabcSS1NMZ/uqGALlCF/VH5wSL3CYduABGeVvKFVEi6' -- 这里替换为新密码的哈希值
WHERE id = 1;

哈希代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

public class PasswordEncoderExample {

public static void main(String[] args) {
// 创建 BCryptPasswordEncoder
PasswordEncoder encoder = new BCryptPasswordEncoder();

// 编码密码
String rawPassword = "123456";
String encodedPassword = encoder.encode(rawPassword);

// 打印编码后的密码
System.out.println("Encoded Password: " + encodedPassword);
}
}

2. 端口

前端的端口:8080 在vite.config.js中修改

后端的端口:8088 在application.yml中修改

image-20240218232659713

Java 基础部分

P18

一、基础知识细节

  1. 编译java代码 : javac HelloWorld.java

  2. main方法是JVM规定的,程序就是从这个位置执行的,程序的入口

  3. public class 和class的区别

P19 public class和class的区别

  1. 一个java源文件中可以生成多个源文件 ;

  2. 编译后,一个class对应生成一个class字节码文件

image-20240223111209337
  1. 如果一个类是public的,那么这个类名要和文件名保持一致,如果不一致就会报错。

  2. 一个java文件里,public class可以没有,如果有也只能有一个。

  3. 每个类里面都可以写入口main函数 ,执行只需要 java 类名

    在实际的开发中,入口只能有一个

image-20240223111722726

JAVA基础语法

一、标识符

凡是有权利自己起名的都是标识符,比如类名等

①在Java中,标识符是用来给变量、方法、类和包等命名的字符序列。

②标识符的长度没有限制,但是建议使用有意义的、简洁的标识符,以提高代码的可读性和可维护性。

标识符可以标识什么

①变量名

②方法名

③类名、接口名、枚举名、注解名

④包名

⑤常量名

⑥……

标识符命名规则

①标识符可以由字母、数字、下划线(_)和美元符号($)组成,不能含有其他符号。(java支持全球所有语言,所以这里的 字母 指的是任何一个国家的文字都可以)

②标识符不能以数字开头。

③标识符不能是Java中的关键字,如public、class、void等。

④标识符是区分大小写的,即Foo和foo是两个不同的标识符。

⑤标识符的长度没有限制,但是Java建议使用有意义的、简短的标识符。

标识符命名规范

①见名知意

②驼峰式命名方式

③类名、接口名、枚举、注解:首字母大写,后面每个单词首字母大写。(StudentService,UserService)

④变量名和方法名:首字母小写,后面每个单词首字母大写。(doSome,doOther)

⑤常量名:全部大写,每个单词用下划线连接。(LOGIN_SUCCESS,SYSTEM_ERROR)

⑥包名:全部小写

二、关键字

Java关键字是Java编程语言中预定义的具有特殊含义的单词,这些单词不能被用作标识符,而是在语法中有特定的用法和限制。

Java关键字有哪些

①Java关键字都是小写的。

②abstract, assert, boolean, break, byte, case, catch, char, class, continue, default, do, double, else, enum, extends, final, finally, float, for, if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public, return, short, static, strictfp, super, switch, synchronized, this, throw, throws, transient, try, void, volatile, while(50)

③Java保留字:goto,const(虽然没有在java中用到,但是不能用)

三、字面量

①字面量指的是在程序中直接使用的数据,字面量是Java中最基本的表达式,不需要进行计算或转换,直接使用即可。

就是数据

Java中有哪些字面量

①整数型:10、-5、0、100

②浮点型:3.14、-0.5、1.0

③布尔型:true、false

④字符型:’a’、’b’、’c’、’1’、’2’、’国’

⑤字符串型:”Hello”、”World”、”Java”、”你好呀”

加号运算符 +

①作用1:求和(当加号两边都是数字时进行求和运算)

②作用2:字符串拼接(当加号==两边有任意一边是字符串类型==时会进行字符串拼接,结果还是一个字符串)

image-20240223113100144

image-20240223113232992

image-20240223113303115

四、变量

①变量是内存当中的一块空间。是计算机中存储数据最基本的单元。

②变量三要素:

  • l数据类型(决定空间大小)【int, double, String】
  • l变量名(只要是合法的标识符即可)
  • l变量值(变量中具体存储的数据)

③变量的声明、赋值、访问

  • lint i; // 声明一个整数型的变量,起名i
  • li = 100; // 给变量i赋值100
  • lSystem.out.println(i); // 访问i变量:读操作
  • li = 200; // 访问i变量:改操作【给变量i重新赋值200】

生命周期就是从内存开辟到内存释放

变量分类

①局部变量

在方法体里面定义的变量

②成员变量

在类里面,不是在方法体里面定义的;

==对于成员变量来说,如果没有手动赋值,系统会自动赋默认值。==0.false,null

  1. 静态变量

    ​ //

    1
    static int a;
  2. 实例变量

五、数据类型

image-20240223124717592

image-20240223124824008

关于默认值:Java语言中变量必须先声明,再赋值,才能使用。对于局部变量来说必须手动赋值,而对于成员变量来说,如果没有手动赋值,系统会自动赋默认值。

1.整数型详解

  1. 整数型字面量一般默认是int,所以在定义long的时候,需要在字面量的后面加上“L/l”

image-20240223125508845

2.自动类型转换

小容量的可以转大的,在Java中,对于基本数据类型来说,小容量是可以直接赋值给大容量的,这被称为自动类型转换。

==byte < short < int < long < float < double==

image-20240223134152096

3.强制类型转换

需要大容量转小容量

①Java中大容量是无法直接转换成小容量的。因为这种操作可能会导致精度损失,所以这种行为交给了程序员来决定,当然这种后果自然是程序员自己去承担。因此在代码中需要程序员自己亲手加上强制类型转换符,程序才能编译通过

②强制类型转换时,底层二进制是如何变化的?原则:砍掉左侧多余的二进制。

③强制类型转换时,精度可能会损失,也可能不会损失,这要看具体的数据是否真正的超出了强转后的类型的取值范围。如下图:水可能溢出,也可能不会溢出,这要看真实存放的水有多少

④请推算结果:byte b = (byte)150;

image-20240223134219863

4.byte

当整数字面量没有超出byte的范围

①在Java中有这样一个规定,==当整数型字面量没有超出byte的范围:可以直接赋值给byte类型的变量。==

byte b = 127; // 这是允许的

很显然,这是一种编译优化。同时也是为了方便程序员写代码。

②如果超出了范围,例如:

byte b = 128; // 编译报错

这样就会报错,需要做强制类型转换,例如:

byte b = (byte)128;

它的执行结果你知道吗?可以尝试推算一下

③在整数类型中,除了byte有这个待遇之外,short同样也是支持的。也就是说:如果整数型字面量没有超出short取值范围时,也是支持直接赋值的。

5.数据类型运算

两个int类型做运算:两个int类型的数据做运算,最终的结果还是int类型

多种数据类型混合运算:

a.在Java中,多种数据类型混合运算时,各自先转换成容量最大的类型,再做运算

byte a = 100;

int b = 200;

long c = 300L;

long d = a + b + c;

你可以测试一下,如果d变量是int类型则编译器会报错

b.byte和short混合运算(byte+byte、short+short)的时候,各自先转换成int再做运算,最后的结果是int,不能用short
c.byte a = 10/3 ,这个是在编译的时候就得到结果了

编译后的class文件中直接就是byte a = 3

d.byte a = 10; byte b = 3; byte c = a/b 这个是运行的时候才得到结果的。

编译的阶段只能知道a/b的结果是int类型,不知道最后的结果是多少。

6.浮点型

浮点型字面量默认被当做double

①Java中,浮点型字面量默认被当做double类型,如果要当做float类型,需要在数字后面添加 F 或 f。

image-20240223142425166

==float f = 3.0; // 编译报错==

==报错原因是:3.0默认被当做double类型,大容量无法直接赋值给小容量。如何修改:==

==float f = 3.0F;==

==float f = (double)3.14;==这个是强制类型转换

②另外,可以通过以下程序的输出结果看到,double精度高于float:

double d = 1.5656856894;

System.out.println(d);

float f = 1.5656856894F;

System.out.println(f);

③浮点型数据两种表示形式

第一种形式:十进制

double x = 1.23;

double y = 0.23;

double z = .23;

第二种形式:科学计数法

double x = 0.123E2; // 0.123 * 10的平方

double y = 123.34E-2; // 123.34 / 10的平方

浮点型数据存储原理

①符号位:0表示整数。1表示负数。

②指数位:比如小数0.123E30,其中30就是指数。表示0.123 * 10的30次幂。所以也有把指数位叫做偏移量的。最大偏移量127。

③尾数位:浮点数的小数部分的有效数字。例如:0.00123,那么尾数位存储123对应的二进制。

④从浮点型数据存储原理上可以看到,二进制中的指数位决定了数字呈指数级增大。因此float虽然是4个字节,但却可以表示比long更大的数值。因此float容量比long的容量大。

image-20240223142930629

①一旦有浮点型数据参与运算得出的结果,一定不要使用“==”与其它数字进行“相等比较”

浮点型数据在计算机底层计算的是近似值,

7.字符型

①占用两个字节,0~65535,和short容量相同,但char可以取更大的整数

②单个字符,使用单引号括起来,不能是多个字符

③可以保存一个汉字

④char c = ‘’; 这是不允许的

⑤char c = ‘\u0000’; 这表示一个空字符,也是char的默认值。\u0000是一个Unicode码。

⑥空字符与空格字符是不同的。空字符表示什么也没有。空格字符表示一个空格。****

字符编码

乱码产生的原因在于,在编码和解码的时候没有用同一个码表

一、技术的版本控制

image-20240218015738084

image-20240218015750388

二、动力云客的项目概述

这个项目就是一个商业的集合营销销售为一体的客户关系管理系统,采用信息化、数字化的方式来进行营销和看客户管理。

1.项目数据库:Mysql一个数据库

2.前端项目:

这是一个前后端分离的项目 (前端vue–>(ajax axios) http请求–>后端项目(spring boot)

0%