mysql的学习笔记

干前端好几年了,只会前端总感觉少了条腿,处处不自在,决定今年学习下后端的东西.以前总想着学node会更快,但是实际工作上却用不上.
出来混,总是要还的,该学的javaWeb这一套体系的东西,总是需要学习的.
那就开始啦.

一,在本地电脑mac上安装mysql

这个参考的这篇文章,照着做一次就成功了.
https://zhuanlan.zhihu.com/p/168753680

二,数据库的理解

我们写代码的时候,变量一般存储在设备的内存中,浏览器的缓存中.但是这个是临时状态,一旦初始化或者刷新就会被重置.
于是我们还可以把数据存储在文件中,但是文件读写比较麻烦.并且不能多个客户端共用.
于是就想着有个远程的数据仓库,专门用来存储数据文件,这就是数据库.
请添加图片描述

三,mysql的登录

安装完成后,mysql的登录有三种方式.

mysql -u 用户名 -p 密码
mysql -hip地址 -u 用户名 -p 密码
mysql --host=ip地址 --user=用户名 --password=密码

四,数据库的基本理解

首先要理解数据库服务器-数据库-数据表-数据记录之间的关系.大概可以用下图来理解:
请添加图片描述

五,操作数据库

在sql的语法中,注释是--,一个语句的结束是分号.

5.1,创建数据库

--创建数据库
create database 数据库名;
--判断如果不存在则创建数据库
create database if not exists 数据库名;

5.2,查看数据库

show databases;

5.3,删除数据库

drop database 数据库名;

5.4,使用数据库

--查看正在使用的数据库
select database();
--选择使用某一个数据库
use 数据库名;

六,操作数据表

前提是已经确定使用哪个数据库.

--创建表(常用字段类型有int\double\varchar\date)
create table 表名(字段名1 字段类型1,字段名2 字段类型2
)
--查看数据库中的所有表
show tables;
--查看表结构
desc 表名;
--查看某个表创建该表的SQL语句
show create table 表名;
--快速创建一个表结构相同的表
create table 新表名 like 旧表名;
--直接删除表
drop table 表名;
--判断表是否存在,如果存在则删除表
drop table if exists 表名;
--修改表名
rename table 表名 to 新表名;
--添加表列
alter table 表名 add 列名 类型;
例子:
ALTER TABLE mytable 
ADD COLUMN id INT,
ADD COLUMN age INT,
ADD COLUMN name VARCHAR(255);
--修改列的类型
alter table 表名 modify 列名 新的数据类型;
--修改列名
alter table 表名 change 旧列名 新列名 类型;
--删除列
alter table 表名 drop 列名;
--查看数据的表结构
SHOW COLUMNS FROM table_name;

七,数据表的操作

用于对数据表记录进行增删改查

--插入记录(没有添加数据的字段会填充null)
insert into 表名 (字段1,字段2,字段3) values (1,2,3);
--更新表记录(如果不带筛选,就是修改全部)
update 表名 set 列名1=1,列名2=2 [where 条件表达式]
例如:update student set age=26,address='北京' where id=3;
--删除表记录(没添加表名则全部删除)
delete from 表名 [where 条件表达式]
--查询表中的数据
select 列名 from 表名 [where 条件表达式]
--查询所有列的数据(使用select *)
select * from 表名 [where 条件表达式];
--查询指定列的数据,多个列用逗号隔开
select 字段名1,字段名2,字段名3 from 表名 [where 条件表达式];
--查询制定列并且结果不出现重复数据
select distinct 字段名 from 表名;

有的时候会增加where条件查询,常见的运算符有:

比较运算符:>,<,<=,>=,=,<>
范围运算符:between…and,包含头尾
in(集合):集合表示多个值,使用逗号分隔
like '张%':模糊查询,_表示一个字符,%表示任意多个字符
is null:查询某一列的值是null,:不能写=null
and:与
or:或
not:

例子:

select * from student where id in (1,2,3);

八,mysql的约束与设计

--使用order by来进行排序显示
select 字段名 from 表名 where 筛选条件 order by 字段名 [ASC|DESC];
--asc升序,desc降序
--示例
select * from student order by age desc;

8.1,单列排序

只对其中一个字段进行排序.

select * from student order by age desc;

8.2,组合排序

组合排序主要适用于前面的排序有相等的情况,比如先按年龄排序,年龄相同了在以数学成绩升序排列.

select * from student order by age desc, math asc;

8.3,聚合函数

之前做的查询都是一行一行的查询,聚合函数主要的作用就是一列列合并计算,比如计算所有记录的人数这个字段的总和.聚合函数会忽略空值null,常用的聚合函数有以下几个

max(列名)
min(列名)
avg(列名)
count(列名)
sum(列名)
--示例:年龄总和
select sum(age) as 总年龄 from mytable;

因为null会被忽略,所以需要利用ifnull函数,把null值给个默认值.

select sum(ifnull(age)) from student;

8.4,分组

group by 分组字段是将分组字段中的相同内容作为一组,并且返回每一组的第一条数据,常常和聚合函数一起使用.
例如按照男女性别进行分组,最后分别统计成绩平均数:

select sex,avg(math) from student3 group by sex;

值得注意的是,group by后面不能用where,而是可以使用having,也就是先分组,后过滤数据.

8.5,limit的作用

数据准备,新建表:

create table students(id int,NAME varchar(10),age int,sex varchar(10),address varchar(10),math int,english int)

初始化数据

INSERT INTO students(id,NAME,age,sex,address,math,english) VALUES (9,'唐僧',25,'男','长安',87,78), (10,'孙悟空',18,'男','花果山',100,66), (11,'猪八戒',22,'男','高老庄',58,78), (12,'沙僧',50,'男','流沙河',77,88),(13,'白骨精',22,'女','白虎岭',66,66), (14,'蜘蛛精',23,'女','盘丝洞',88,88);

limit的作用就是限制查询记录的条数.

   SELECT *|字段列表 [as 别名] FROM 表名 [WHERE 子句] [GROUP BY 子句][HAVING 子句][ORDER BY 子 句][LIMIT 子句];

limit的语法:limit offset,length;

--查询学生表中的数据,从第三条开始,显示4.
select * from students limit 2,4;

九,数据库的备份与还原

9.1,备份格式

DOS下,未登录的时候,这是一个可执行文件exe,在bin文件夹:

mysqldump -u root -p 数据库名 >/Users/mac名字/Desktop/test.sql

如果报错可以看这篇博客:https://blog.csdn.net/lxf3887125/article/details/125335957

这样桌面就会生成一个sql文件.

9.2,还原格式

执行上文生成的mysql文件,这个需要登录mysql.

show databases;
use 数据库;
source 导入文件的路径;
--source /Users/huangchuanbiao/Desktop/test.sql

十,数据库表的约束

对表中数据进行约束,用来保证数据的正确性有效性和完整性.约束在创建表的时候添加比较合适.
约束的种类主要有以下几种:

主键:primary key
唯一:unique
非空:not null
外键:foreign key
检查约束:check (mysql不支持)

10.1,主键约束

主键的作用:用来唯一标识数据库中的每一条记录,主键只能有一个
主键的选择:不用业务字段,因为主键是给程序和数据库使用的
主键的创建(将该字段作为主键):
----在创建表的时候给字段添加主键:字段名 字段类型 primary key
----在已有表中添加主键:alter table 表名 add primary key(字段名)
删除主键:alter table 表名 drop primary key;
主键自增:auto_increment-默认的开始值是1
----设置起始值
----create table 表名(字段名 类型 primary key auto_increment
)auto_increment=起始值
创建完毕后修改起始值:alter table 表名 auto_increment=新的起始值
delete和truncate的区别:前者自增长无影响,后者自增长重置

10.2,唯一约束

唯一约束是针对字段名而言的,也就是不允许该表在该字段有多条相同的记录.

字段名 类型 unique
----不许出现同名的学生
create table student(id int,name varchar(5) unique
)

10.3,非空约束

非空约束就是限定该表中的某一字段不能是null值.或者给定一个默认值.

字段名 类型 not null
--创建表,并且设置name不能为null
create table student(id int,name varchar(5) not null
)
字段名 类型 default 默认值
--创建表,并且设置name默认值为:孙悟空
create table student(id int,name varchar(5) default '孙悟空'
)

10.4,外键约束

数据准备,创建一个员工表并添加数据:

CREATE TABLE emp (id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(30),age INT,dep_name VARCHAR(30),dep_location VARCHAR(30)
);
-- 添加数据
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('张三', 20, '研发部', '广州'); INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('李四', 21, '研发部', '广州'); INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('王五', 20, '研发部', '广州');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('老王', 20, '销售部', '深圳'); INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('大王', 22, '销售部', '深圳'); INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('小王', 18, '销售部', '深圳');

可以看到有很多数据是重复的,比如部门都是研发部,地点都是广州.
于是可以考虑创建两张表,一个员工表,一个部门表.员工表用一个dep_id来连接部门表.

-- 解决方案:分成 2 张表
-- 创建部门表(id,dep_name,dep_location)
-- 一方,主表
create table department(id int primary key auto_increment,dep_name varchar(20),dep_location varchar(20)
);
-- 创建员工表(id,name,age,dep_id)
-- 多方,从表
create table employee(
id int primary key auto_increment, name varchar(20),
age int,
dep_id int -- 外键对应主表的主键
)
-- 添加2个部门
insert into department values(null, '研发部','广州'),(null, '销售部', '深圳'); select * from department;
-- 添加员工,dep_id 表示员工所在的部门
INSERT INTO employee (NAME, age, dep_id) VALUES ('张三', 20, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('李四', 21, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('王五', 20, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('老王', 20, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('大王', 22, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('小王', 18, 2);
select * from employee;

在这里插入图片描述
现在新的问题又出现了,employee中的dep_id不应该加入除了12的值,因为否则department中没有对应的部门了.
这时候,就需要引入外键约束,让dep_id和deparment表中的id联系起来.
外键约束的定义:

外键约束:从表中与主表主键对应的那一列
主表:一方,用来约束别人的表
从表/副表:多方,被别人约束的表

在这里插入图片描述
添加外键:

--创建新表时
constraint [外键约束名称(后续指代这个外键)] foreign key (外键字段名,从表中) references 主表名(主键字段名主表中)
--已有的表中新增
alter table 从表 add constraint [外键约束名称(后续指代这个外键)] foreign key (外键字段名) referenecs 主表名(主键字段名);

我们可以新建一个从表:

create table employee2(id int primary key auto_increment,name varchar(20),age int,dep_id int,constraint emp_depid_fk foreign key (dep_id) references department(id)
);

然后正常新增数据,显示正常:

INSERT INTO employee2 (NAME, age, dep_id) VALUES ('张三', 20, 1); 
INSERT INTO employee2 (NAME, age, dep_id) VALUES ('李四', 21, 1); 
INSERT INTO employee2 (NAME, age, dep_id) VALUES ('王五', 20, 1);
INSERT INTO employee2 (NAME, age, dep_id) VALUES ('老王', 20, 2); 
INSERT INTO employee2 (NAME, age, dep_id) VALUES ('大王', 22, 2); 
INSERT INTO employee2 (NAME, age, dep_id) VALUES ('小王', 18, 2);

但是如果新增不正常的数据,则会报错:

INSERT INTO employee2 (NAME, age, dep_id) VALUES ('小王', 18, 6);

请添加图片描述
删除外键

alter table 从表 drop foreign key 外键名称;

例如现在我需要把从表的外键dep_id删除,则如下:

alter table employee2 drop foreign key emp_depid_fk;

于是又出现了新的问题,当我们已经拥有了外键,而主表的主键的值要是发生了变更怎么办?因为这时候从表中的外键还是依赖的这个值,这样贸然变更必然有问题.
也就是说主表的主键不能随意变更或删除(从表的外键还依赖于它)
于是就有了级联操作:在更新或删除主表的主键时,会更新从表的外键值.
级联操作需要在创建表声明外键约束的时候就特别声明,主要有以下两种:

on update cascade:级联更新
on delete cascade:级联删除

于是创建新的从表声明外键就变成:

create table employee(id int primary key auto_increment, name varchar(20),age int,dep_id int, -- 外键对应主表的主键-- 创建外键约束constraint emp_depid_fk foreign key (dep_id) referencesdepartment(id) on update cascade on delete cascade
)

十一,表与表之间的关系

表与表之间常见的有以下三种关系:

一对多:部门和员工
多对多:学生选课表和学生表
一对一:员工表和简历表

11.1,一对多

一对多的建表原则:从表(多方)创建一个字段,该字段作为外键指向主表(一方).
请添加图片描述
示例:一个旅游分类学下有多条线路:

-- 创建旅游线路分类表 tab_category -- cid 旅游线路分类主键,自动增长
-- cname 旅游线路分类名称非空,唯一,字符串 100 create table tab_category (cid int primary key auto_increment,cname varchar(100) not null unique
)
-- 添加旅游线路分类数据:
insert into tab_category (cname) values ('周边游'), ('出境游'), ('国内游'), ('港澳游');
select * from tab_category;
-- 创建旅游线路表 tab_route
/*
rid 旅游线路主键,自动增长
rname 旅游线路名称非空,唯一,字符串 100 price 价格
rdate 上架时间,日期类型 cid 外键,所属分类
*/
create table tab_route(rid int primary key auto_increment,rname varchar(100) not null unique,price double,rdate date,--创建外键cid int,--声明外键foreign key (cid) references tab_category(cid)
)
-- 添加旅游线路数据
INSERT INTO tab_route VALUES
(NULL, '【厦门+鼓浪屿+南普陀寺+曾厝垵 高铁 3 天 惠贵团】尝味友鸭面线 住 1 晚鼓浪屿', 1499, '2018-01-27', 1),
(NULL, '【浪漫桂林 阳朔西街高铁 3 天纯玩 高级团】城徽象鼻山 兴坪漓江 西山公园', 699, '2018-02- 22', 3),
(NULL, '【爆款¥1699 秒杀】泰国 曼谷 芭堤雅 金沙岛 杜拉拉水上市场 双飞六天【含送签费 泰风情 广州 往返 特价团】', 1699, '2018-01-27', 2),
(NULL, '【经典•狮航 ¥2399 秒杀】巴厘岛双飞五天 抵玩【广州往返 特价团】', 2399, '2017-12-23', 2),
(NULL, '香港迪士尼乐园自由行2天【永东跨境巴士广东至迪士尼去程交通+迪士尼一日门票+香港如心海景酒店 暨会议中心标准房1晚住宿】', 799, '2018-04-10', 4);
select * from tab_route;            

11.2,多对多

例如学生和课程表的关系.一门课可以被多名学生选择,一个学生也可以选择多个课程.这时候,就需要一个中间表来记录这种关系.
中间表至少包含两个字段,这两个字段分别作为外键指向各自的主键.

请添加图片描述
示例:一个用户收藏多个线路,一个线路被多个用户收藏

创建用户表 tab_user
uid 用户主键,自增长
username 用户名长度 100,唯一,非空 password 密码长度 30,非空
name 真实姓名长度 100
birthday 生日
sex 性别,定长字符串 1
telephone 手机号,字符串 11
email 邮箱,字符串长度 100
*/
create table tab_user (uid int primary key auto_increment,username varchar(100) unique not null,password varchar(30) not null,name varchar(100),
birthday date,
sex char(1) default '男',telephone varchar(11),email varchar(100)
)
-- 添加用户数据
INSERT INTO tab_user VALUES
(NULL, 'cz110', 123456, '老王', '1977-07-07', '男', '13888888888', '66666@qq.com'), (NULL, 'cz119', 654321, '小王', '1999-09-09', '男', '13999999999', '99999@qq.com');
select * from tab_user;
/*
创建收藏表 tab_favorite rid 旅游线路 id,外键
date 收藏时间 uid 用户 id,外键
rid 和 uid 不能重复,设置复合主键,同一个用户不能收藏同一个线路两次 */
create table tab_favorite (
rid int,
date datetime,
uid int,
-- 创建复合主键
primary key(rid,uid),
foreign key (rid) references tab_route(rid), foreign key(uid) references tab_user(uid)
)
-- 增加收藏表数据
INSERT INTO tab_favorite VALUES(1, '2018-01-01', 1), -- 老王选择厦门 (2, '2018-02-11', 1), -- 老王选择桂林 (3, '2018-03-21', 1), -- 老王选择泰国 (2, '2018-04-21', 2), -- 小王选择桂林 (3, '2018-05-08', 2), -- 小王选择泰国 (5, '2018-06-02', 2); -- 小王选择迪士尼
select * from tab_favorite

11.3,一对一

实际上一对一见的不多,因为可以合并成一个表.
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/282759.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线性顺序表算法库

list.cpp 具体函数实现 #include <stdio.h> #include "list.h" #include <malloc.h>/************************************************** ①函数名: CreateList 功 能: 用数组构建顺序表 参 数: ①SqList *&L:传入的线性表 ②ElemType a[]:使用…

文件上传基础篇

文件上传基础篇 文件上传漏洞原理 ​ 目标网站存在文件上传接口&#xff0c;但是对用户上传的文件没有做仔细甄别&#xff0c;导致黑客可以根据此功能点直接上传木马到网站服务器&#xff0c;造成危害 文件上传存在点 ​ 通常有头像上传&#xff0c;pdf上传 文件上传防护 …

Git浅谈配置文件和免密登录

一、文章内容 简述git三种配置ssh免密登录以及遇见的问题git可忽略文件git remote 相关操作 二、Git三种配置 项目配置文件(局部)&#xff1a;项目路径/.git/config 文件 git config --local user.name name git config --local user.email 123qq.cc全局配置文(所有用户): …

X1 grok-1 开源大语言模型下载

Grok 前言 大型语言模型 Grok-1 的基本模型权重和网络架构。Grok-1 是一个 3140 亿参数的专家混合模型&#xff0c;由 xAI 从头开始训练。 这是 2023 年 10 月结束的 Grok-1 预训练阶段的原始基础模型检查点。这意味着该模型不会针对任何特定应用&#xff08;例如对话&#x…

Linux的学习之路:1、发展史与编译环境的搭建

一、发展史 1991年10月5日&#xff0c;赫尔辛基大学的一名研究生Linus Benedict Torvalds在一个Usenet新闻组 &#xff08;comp.os.minix&#xff09;中宣布他编制出了一种类似UNIX的小操作系统&#xff0c;叫Linux。新的操作系统是受到另一个UNIX的小操作系统——Minix的启发…

【群晖】Docker Compose部署 Emby Server

【群晖】Docker Compose部署 Emby Server 本来群晖上面的 Emby 是用套件安装的&#xff0c;但是不巧的是前两天脑袋一抽装了两个插件&#xff0c;导致 Emby Server被当肉鸡了&#xff0c;还找不到脚本代码在哪儿&#xff0c;一天时间上传了3T的流量。无奈之下&#xff0c;只能尝…

计算机二级大题

题目来源&#xff1a;计算机二级Python半个月抱佛脚大法&#xff08;内呈上真题版&#xff09; - 知乎 1.大题1 注意csv文件读取的处理 ls[] for line in f: ls.append(line.strip(\n).split(,)) 2. 大题2 第一问&#xff1a; #计算有效票张数 fopen("vote.txt",…

LinuxU盘挂载原理,为什么要用到U盘挂载及实现U盘挂载

目录 一、U盘挂载原理 二、为什么要用到U盘挂载 三、实现U盘挂载 一、准备工作 1、安装gcc 2、下载ntfs-3g 3、解压 4、编译准备 5、编译并安装 二、挂载演示 一、U盘挂载原理 Linux的U盘挂载原理涉及以下几个方面&#xff1a; 设备识别&#xff1a;当您将U盘插入Lin…

leetcode刷题(javaScript)——动态规划相关场景题总结

动态规划在 JavaScript 刷题中有一定的难度&#xff0c;但也是非常常见和重要的算法思想。动态规划通常适用于需要求解最优解、最大值、最小值等问题的场景&#xff0c;可以将复杂问题拆分成子问题&#xff0c;通过存储子问题的解来避免重复计算&#xff0c;从而提高效率。 理解…

整数和浮点数在内存中存储

整数在内存中的存储 整数的2进制表⽰⽅法有三种&#xff0c;即原码、反码和补码。 对于整形来说&#xff0c;数据存放内存中的其实是补码。 在计算机系统中&#xff0c;数值一律用补码来表示和存储。原因是&#xff0c;使用补码&#xff0c;可以使符号位和数值域统一处理&am…

【爬虫】专栏文章索引

为了方便 快速定位 和 便于文章间的相互引用等 作为一个快速准确的导航工具 爬虫 目录&#xff1a; &#xff08;一&#xff09;web自动化和接口自动化 &#xff08;二&#xff09;实战-爬取Boss直聘信息数据

构建强大的API:Django中的REST框架探究与实践【第146篇—Django】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 构建强大的API&#xff1a;Django中的REST框架探究与实践 在当今的Web开发中&#xff0c;构…

面试算法-83-不同路径 II

题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上角到…

如何一键下载微信视频号的视频至本地电脑

社交媒体平台上的短视频已经成为我们获取信息和娱乐的重要来源&#xff0c;尤其是微信视频号。这个平台汇聚了丰富多样的内容&#xff0c;从生活分享到专业知识&#xff0c;应有尽有。然而&#xff0c;有时我们可能希望将这些有趣的或有用的视频保存到本地以便离线观看或分享给…

单片机学到什么程度才可以去工作?

单片机学到什么程度才可以去工作? 如果没有名校或学位的加持&#xff0c;你还得再努力一把&#xff0c;才能从激烈的竞争中胜出。以下这些技能可以给你加分&#xff0c;你看情况学&#xff0c;不同行业对这些组件会有取舍: . Cortex-M内核:理解MCU内核各部件的工作机制&#…

如何利用RunnerGo简化性能测试流程

在软件开发过程中&#xff0c;测试是一个重要的环节&#xff0c;需要投入大量时间和精力来确保应用程序或网站的质量和稳定性。但是&#xff0c;随着应用程序变得更加复杂和庞大&#xff0c;传统的测试工具在面对比较繁琐的项目时非常费时费力。这时&#xff0c;一些自动化测试…

学习总结2

解题思路 用bfs进行搜索,标记A罐B罐所保存的水的出现情况,当再次出现的时候停止搜索,然后用数组模拟链表进行保存路径.最后输出. 代码 #include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #in…

Python学习day3

知识&#xff1a; #继承&#xff0c;创建有继承的类 #父类、子类 #class 子类(父类): #调用时找父类的构造函数&#xff0c;如果子类自己有某函数则调用子类的&#xff0c;否则调用父类的 #在子类有构造函数的时候调用父类&#xff0c;可以用super().__init__的方法调用父类函数…

基于springboot的“漫画之家”系统

目录 背景 技术简介 系统简介 界面浏览 背景 随着科技的不断进步&#xff0c;计算机已经变成了人们日常生活和工作不可或缺的工具。在这样的环境下&#xff0c;互联网技术被广泛运用于各个领域&#xff0c;以提升工作和生活的效率&#xff0c;推动了网络信息技术的迅猛发展…

基于Springboot的西安旅游系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的西安旅游系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…