项目描述:
类似于喜马拉雅听书的项目,普通用户可以根据自己的喜欢选择相应的专辑进行专辑列表的歌曲播放。
Up主(创作者)需要登录(注册) 后才可以上传、录制自己的音频和查看所有音频,并创建新的专辑与音频进 行绑定,上架发布,供普通用户选择使用。
项目背景:
为了更加熟练掌握Servlet相关知识技术,以及熟悉多个技术之间的相互协调运用,并结合自己平时娱乐喜爱方面进行的项目创建学习
项目技术栈:
Java,Maven,HTTP, Servlet,JSON和MySQL的综合使用。
项目主要功能:
普通用户
无需登录,可以查看专辑列表,选择专辑进行音频播放。
创作者页面,
用户管理:登录功能、注册功能和注销功能;
音频管理:上传音频、录制音频和查看音频列表功能;
专辑管理:新建专辑、显示专辑列表(包括各个专辑状态)和专辑与音频关联功能。
项目结构分析
数据库
E-R:
3个实体(Entity):用户,音频,专辑;1个关系(Relation):关系表
实体间关系分析
用户 -> 音频 : 一对多 关系字段在多表(音频表中有uid字段)
用户 -> 专辑 : 一对多 关系字段在多表(专辑表中有uid字段)
音频 <-> 专辑 : 多对多 多对多关系需要借助中间表,变成两个一对多
表结构和表关系
实体表:
用户表 users {uid,用户名,密码(经过加密)}
音频表 tracks {tid,标题,上传用户id,类型,二进制内容}
TODO:使用MySQL进行音频数据以及诸如此类的较大的二进制数据是不合理的
专辑表 albums {aid,uid,专辑标题,专辑封面图URL,专辑状态}
TODO:专辑封面没有上传功能(因为图片也是较大的二进制数据)
关系表
音频专辑关系表 relations {rid,aid,tid}
功能动作语句(SQL)
普通用户
首页 ---- 查询所有公开的专辑
通过联表查询将用户表uid与专辑表uid一样的专辑和用户属性查询出来
select aid,username,title,cover from albums a join users u on a.uid = u.uid where state = 2(已发布) order by aid desc
拓展功能 (未实现): 查询功能
1.只考虑查专辑标题中包含的关键字(*只是代表,具体需要查询的内容可以根据情况实际改变)
select * from albums a join users u on a.uid = u.uid where state = 2 and title like "%关键字%" order by aid desc
2.只考虑查音频标题中包含的关键字
select * from tracks where title like "%关键字%"
select aid from relations where tid in (上条SQL查询结果)
select * from albums a join users u on a.uid = u.uid where state = 2 and aid in (上条SQL查询结果)
专辑播放页
1.先查询当前专辑属性
select aid, username, title, cover from albums a join users u on a.uid = u.uid where aid = (专辑aid)
2.根据专辑aid在关系表中查到专辑下的音频tid
select tid from relations where aid = (专辑aid) order by rid
3.拿到音频tid后,在音频表中获取对应音频
select * from tracks where tid in (上条SQL查询结果) order by tid
Up主(创作者)
用户功能
用户 | 注册
insert into users (username,password) values (注册值);
用户 | 登录
select * from users where username = (输入用户名)
音频功能
音频 | 录制 or 上传
insert into tracks (uid,title,type,content) values (获取到的音频信息属性值);
音频 | 列表
selec * from tracks where uid = (当前用户id) order by tid
添加分页之后
1.先查询当前用户的音频总数
select count(*) from tracks where uid = (当前登录用户)
2.将查询到的音频分页查询
select tid,uid,title,type from tracks where uid = (当前登录用户) order by tid desc limit (每页总数) offset (起始位置)
带上关联专辑数量
通过聚合查询查询关系表中每个tid出现的次数
select tid, count(*) from relations where tid in (上条分页查询到的tid) group by tid order by tid
专辑功能
专辑 | 新建
insert into albums (uid,title,cover) values(用户上输入的属性值)
专辑 | 列表
select * from albums where uid = (当前用户) order by aid desc
加上分页后(思路音频列表类似,不做详解)
select count(*) from albums where uid = (...)
select * from albums where uid = (...) order by aid limit (...) offset (...)
加上关联音频数量
select aid,count(*) from relations where aid in (....) group by aid order by aid desc
专辑 | 已绑定音频
1.查询当前还在专辑信息
select * from albums where aid = ...
2.在关系表中查询当前专辑关联的音频tid
select tid from relations where aid = ...
3.查询专辑下所有音频信息
select *(增减性能不要查询音频二进制数据) from tracks where tid in (上条SQL查询结果) order by tid
专辑 | 添加新音频
1.先查出专辑包含的音频
select tid from relations where aid = ...
2.在音频表中查询所有不在当前专辑下的音频
select * from tracks where uid = (...) and tid not in (上条查询结果) order by tid desc
3.添加新关联
insert into relations (aid,tid) values (专辑aid,音频tid)
专辑 | 发布/下线
发布
update albums set state = 2(已发布) where aid = ...
下线
update albums set state = 0(已下线) where aid = ...
功能对应的web资源
功能
路径
资源
公开页面
首页
/index.html
静
/js/index.js
静
/album-list.json
动
播放页
/play.html?aid=
静
/js/play.js
静
/album-detail.json?aid=
动
创作中心
用户 | 注册
/studio/user/register.html
静
/studio/user/register.do
动
用户 | 登录
/studio/user/login.html
静
/studio/user/login.do
动
用户 | 退出
/studio/user/quit.do
动
音频 | 上传
/studio/track/upload.html
静
/studio/track/upload.do
动
音频 | 录制
/studio/track/record.html
静
/studio/track/js/record.js
静
/studio/track/record.json
动
音频 | 列表
/sudio/track/list.html
静
/sudio/track/js/list.js
静
/sudio/track/list.json
动
专辑 | 新建
/studio/album/create.html
静
/studio/album/create.do
动
专辑 | 列表
/studio/album/list.html
静
/studio/album/js/list.js
静
/studio/album/list.json
动
专辑 | 关联音频 | 已关联情况
/studio/album/bind.html?aid=
静
/studio/album/js/bind.js
静
/studio/album/bind.json?aid=
动
专辑 | 关联音频 | 添加关联
/studio/album/add.html?aid=
静
/studio/album/js/add.js
静
/studio/album/candidate.json?aid=
动
/studio/album/add.do
动
修改专辑状态 | 发布
/sudio/album/publish.do?aid=
动
修改专辑状态 | 下线
/sudio/album/withdraw.do?aid=
动
数据流转流程(以专辑功能为例)
用户->浏览器->网络->Tomcat->MySQL
新建专辑 | 用户填写信息后,点击按钮,专辑发布成功
1.用户点击按钮,按钮输入form表单,所以,点击按钮会触发一个新的HTTP请求
2.该HTTP请求的方法按照form表单的method属性(get/post)确定,路径按照action属性确定,携带的内容按照form包
含的input标签带有name属性的内容确定
3.该HTTP经过网络到达Tomcat,Tomact根据Context Path + Servlet Path 确定有那个Servlet对象对其进行处理(@WebServlet指定的)
4.Tomcat根据HTTP请求方法,调用doGet,doPost....
5.读取参数即用户填写的专辑必要信息,以及必要的参数合法性校验
6.根据读到的参数执行SQL插入语句
7.根据业务,进行重定向或显示创建成功
MySQL->Tomact->浏览器->用户
专辑列表显示
1.在浏览器进入list.html
2.浏览器会发起get请求list.html
3.Tomcat根据相应路径,找到对应的静态资源并响应其内容
4.浏览器解析html内容,发现<script>标签,会发起一个新的请求
5.浏览器发起get请求list.js
6.Tomcat根据相应路径,找到对应资源并响应其内容
7.浏览器执行JS中的语句
8.在js中有发起ajax的语句
9.浏览器发起get请求list.json
10.Tomcat根据资源路径,找到Servlet对象进行处理
Servlet->Service->Repository(DAO)的内部处理
(1).判断当前用户(Servlet)
(2).执行必要SQL(具体到每个dao类)
(3).组合(在Service中将SQL结果整合)
(4).响应(最终Servelt将组合得到的数据发出)
11.浏览器继续执行xhr,onload函数
12.语句根据list.json返回的结果,修改DOM树结构(添加新的列表项)
13.浏览器根据DOM树,渲染出用户看到的结果