当前位置: 首页 > news >正文

13.音乐管理系统(基于SpringBoot + Vue)

目录

1.系统的受众说明     ​​​​​​​

2 需求分析

2.1用例图及用例分析

2.1.1 用户用例图及用例分析

2.1.2 管理员用例图及用例分析

2.2 系统结构图和流程图

2.2.1 音乐播放器的系统流程图(图2.2.1-1)

2.2.2 系统功能表(表2.2.2-1)和系统功能结构图(图2.2.2-1)

2.3 系统界面需求

2.4 系统性能需求

3 初步设计

3.1 系统的可行性研究

3.1.1 技术可行性

3.1.2 经济可行性

3.1.3 法律可行性

3.2 软件目标

3.3 总体设计路线

4详细设计

4.1 整体概括 

4.1.1 项目目的和目标

4.1.2 软件运转环境

4.2 详细需求

4.2.1 E-R图

4.3 功能需求

4.3.1 播放器的前端

4.3.2 播放器的后端

4.3.3 数据库设计

4.3.3.1 admin表

4.3.3.2 conllect表

4.3.3.3 comment表

4.3.3.4 consumer表

4.3.3.5 list_song表

4.3.3.6 rank表

4.3.3.7 singer表

4.3.3.8 song表

4.3.3.9 song_list表

5 编程实现

5.1 外部接口-前端界面实现

5.1.1 登录页面

5.1.2 播放器

5.1.3 首页

5.1.4 歌词页面

5.1.5 歌单详情页

5.2 内部接口-后端实现

5.2.1 管理员模块

5.2.2 收藏模块

5.2.3 评论区模块

5.2.4 前端用户控制模块

5.2.5 歌单模块

5.2.6 评价模块

5.2.7 歌手模块

5.2.8 歌曲模块

5.3 数据库交互

6 界面展示与测试

6.1 前端界面展示

6.2 后端界面展示

6.3 数据库界面展示


 

1.系统的受众说明
     
 

     1 在校学习的学生,可用于日常学习使用或是毕业设计使用

     2 毕业一到两年的开发人员,用于锻炼自己的独立功能模块设计能力,增强代码编写能力。

     3 亦可以部署为商化项目使用。

     4 需要完整资料及源码,请在文末获取联系方式领取。

2 需求分析

2.1用例图及用例分析

根据项目的目标,我们可获得项目系统的基本需求,以下从不同角度来描述系统的需求,并且使用用例图来描述系统的功能需求,我们分成三部分来概括,即播放器的前端,播放器的后端和数据库。以下分别描述:

2.1.1 用户用例图及用例分析

图2.1.1-1 用户用例

用例名称:播放

参与者:用户

目标:使得用户可以播放在歌单中选中的歌曲

前置条件:播放器正在运行

基本事件流:1. 用户单击“播放”按钮

            2. 播放器将播放列表中的当前歌曲

用例名称:暂停

参与者:用户

目标:使得用户可以暂停在歌单中选中的歌曲

前置条件:歌曲正在播放且未停止和暂停

基本事件流:1. 用户单击“暂停”按钮

            2. 播放器将暂停当前歌曲

用例名称:上一首/下一首

参与者:用户

目标:使得用户可以听上一首或下一首歌曲

前置条件:播放器正在播放或暂停

基本事件流:1. 用户单击“上一首或下一首”按钮

            2. 播放器将播放上一首或下一首歌曲

用例名称:分享

参与者:用户

目标:使得用户可以分享当前歌曲

前置条件:播放器正在运行

基本事件流:1. 用户单击“分享”按钮

            2. 生成并复制分享链接

用例名称:下载

参与者:用户

目标:使得用户可以下载在歌单中选中的歌曲

前置条件:播放器正在运行

基本事件流:1. 用户单击“下载”按钮

            2. 下载当前歌曲到本地

用例名称:评论

参与者:用户

目标:使得用户可以评论在歌单中选中的歌曲

前置条件:播放器正在运行

基本事件流:1. 用户单击“评论”按钮

            2. 在当前歌曲下方输入评论的内容

用例名称:收藏

参与者:用户

目标:使得用户可以收藏喜爱的歌曲

前置条件:播放器正在运行、成功登录系统

基本事件流:1. 用户单击“收藏”按钮

            2. 播放器将播放列表中的当前歌曲

2.1.2 管理员用例图及用例分析

图2.1.2-1 管理员用例

用例名称:修改

参与者:管理员

目标:使得管理员可以修改选中的用户、歌手、歌单,歌曲

前置条件:程序运行在播放菜单选项中

基本事件流:1. 管理员单击“修改”按钮

            2. 管理员将修改选中的用户、歌手、歌单和歌曲

用例名称:删除

参与者:管理员

目标:使得管理员可以删除选中的用户、歌手、歌单,歌曲

前置条件:程序运行在播放菜单选项中

基本事件流:1. 管理员单击“删除”按钮

            2. 管理员将修改选中的用户、歌手、歌单和歌曲

用例名称:歌词显示

参与者:管理员

目标:使得管理员可以修改选中的用户、歌手、歌单,歌曲

前置条件:是的程序进入播放器歌词设置状态

基本事件流:1. 管理员单击“添加歌词”按钮

            2. 歌词文本框中显示歌词

2.2 系统结构图和流程图

2.2.1 音乐播放器的系统流程图(图2.2.1-1)

图2.2.1-1 流程图

2.2.2 系统功能表(表2.2.2-1)和系统功能结构图(图2.2.2-1)

功能类别

子功能

子功能

播放列表

播放列表菜单

退出播放

从歌单寻找歌曲

歌曲菜单

播放->进入播放界面

删除->数据库同步更新

重命名->数据库同步更新

向上、下移动->数据库同步更新

播放

播放歌曲->线程启动->时间更新

暂停

暂停歌曲->线程暂停->时间暂停

播放界面

上一首

播放列表索引变化->寻找上一首歌曲

下一首

播放列表索引发生变化->寻找下一首歌曲

播放界面菜单

返回到播放列表

返回到主菜单

从歌单寻找歌曲

退出播放器

隐藏播放界面

主菜单

退出程序

程序退出

进入播放列表

显示播放列表

2.2.2-1 系统功能表

图2.2.1-1 系统功能图

2.3 系统界面需求

播放器界面要求布局合理,颜色舒适,控制按钮友好,为了减少开发工程量,图片素材多数为本地项目素材(图2.3-1)

图2.3-1 播放器界面

说明:左下角实心三角为暂停按钮,右下角实心爱心为收藏按钮,蓝色条为音轨。

2.4 系统性能需求

根据客户端电脑系统要求无响应时间为5秒,所以就有如下性能需求:

  1. 当要求歌曲播放时,程序响应时间最长不能超过5秒:
  2. 当要求歌曲暂停时,程序响应时间最长不能超过5秒:
  3. 当要求歌曲上/下一首时,程序响应时间最长不能超过5秒:
  4. 当要求收藏歌曲时,程序响应时间最长不能超过5秒:
  5. 当要求分享歌曲时,程序响应时间最长不能超过5秒:
  6. 当要求评论歌曲时,程序响应时间最长不能超过5秒:
  7. 当要求下载歌曲时,程序响应时间最长不能超过5秒。

3 初步设计

3.1 系统的可行性研究

3.1.1 技术可行性

音乐管理系统可以利用现有的技术资源和工具进行开发和实施。现有的硬件和软件设备可以满足系统的需求,例如存储音乐文件、处理用户请求和提供良好的用户体验。同时,系统可以利用现有的数据库和网络技术来实现音乐文件的上传、存储和管理,以及提供高效的搜索和推荐功能。因此,从技术可行性的角度来看,音乐管理系统是可行的。

3.1.2 经济可行性

音乐管理系统的开发和实施可以带来经济效益。系统可以提高音乐版权管理的效率,减少人力成本,并为音乐公司或个人艺术家带来更多的商业机会。此外,系统还可以通过广告、订阅和销售音乐等方式产生收入。通过对系统开发和运营成本与预期收益进行比较,可以得出音乐管理系统在经济上是可行的结论。

3.1.3 法律可行性

音乐管理系统需要遵守相关的法律法规,特别是音乐版权保护和数据隐私方面的要求。系统需要确保音乐版权的合法使用,并保护用户的个人信息安全。通过合规性的评估和合法的授权,可以确保音乐管理系统在法律上是可行的。

综上所述,从技术、经济、法律和操作等方面的考虑,音乐管理系统是可行的。它可以利用现有的技术资源和工具进行开发和实施,带来经济效益,同时遵守相关的法律法规,并具备良好的操作性。因此,音乐管理系统的开发和实施是有前景和潜力的

3.2 软件目标

本系统属于用户常用的音乐播放器。可以方便用户平时对音乐文件的操作。本系统应达以下目标:

  1. 软件采用人机交互的方式,界面美观友好、操作灵活、方便、富有个性化。
  2. 能够对音乐文件进行有效地管理。
  3. 系统应最大限度的实现易维护性和易操作性。

3.3 总体设计路线

在 web开发中界面的设计是很重要的,因为它区别于Android的开发。它的界面大,又要在这么大的界面上尽可能多的不去留白,所以在UI设计上,组件的摆放问题以及屏幕之间滑动跳转问题都是在设计工程中要考虑到的,其次,Web程序主要应用在客户端上,为了方便用户操作,必须考虑到组件摆放的易操作性,所以要考虑到组件摆放的区域问题,初次之外在UI设计的编写上也要考虑到代码的可更改问题,如果单纯的用Vue实现,那么软件的进一步更改开发上可能会遇到很大的问题,所以该系统的大部分界面都是通过Vue和Java代码共同实现的。

在完成音乐播放器界面的设计后就是功能模块的设计了,功能这一块是根据需求来的,有怎么样的需求就对应怎么样的功能设计,该音乐播放器所要实现的功能都是通过各个类之间调用实现的,这样就增加了代码的可读性,对于音乐播放器来说最主要的还是实现音乐播放功能,第一部分就是音乐文件读取、音频文件信息读取,其次是对音乐的操作,然后就是播放器的个性化设置,所以要做好也是一件不简单的事情。

4详细设计

4.1 整体概括 

4.1.1 项目目的和目标

本项目的目的是开发一个能够播放的音乐文本格式的播放器。设计的主要实现功能是播放MP3等格式的音乐文件,而且能控制播放、停止、音量控制、选择上一曲、选择下一曲、收藏、评论、分享、设置头像、歌曲列表文件的管理操作、在线播放、在线下载、等多种功能,界面简洁,操作简单。

4.1.2 软件运转环境

操作系统:Win10

支持环境:JAVA 、SpringBoot、MyBatis、MySQL、Vue、Nodejs等

开发环境:IDEA、Visual studio Code、Navicat等。

4.2 详细需求

依据项目,我们能够获取项目系统的基本需求,从不一样的方面来描述系统的需求

4.2.1 E-R图

4.3 功能需求

系统的功能需求,我们分为三个主要部分,即用户端,管理员端和数据库。以下分别描绘:

4.3.1 播放器的前端

  1. 首页:点击歌单中的音乐播放列表中的歌曲进行播放,播放时跳转播放界面,并显示歌手信息,同时会匹配歌词,把相应的歌词显示在歌词面板中。
  2. 暂停:当歌曲正在播放时,点击歌曲播放界面下方的暂停键,暂停目前播放的歌曲,同时歌曲停止转动。
  3. 上一曲:歌曲正在播放,点击上一曲键,播放列表中上一首歌曲。
  4. 下一曲:歌曲正在播放,点击下一曲键,播放列表中下一首歌曲。
  5. 下载:当歌曲正在播放时,点击歌曲播放界面下方的下载键,会在本地下载当前播放的歌曲。
  6. 收藏:当歌曲正在播放时,点击歌曲播放界面下方的爱心键,会收藏当前播放的歌曲。
  7. 分享:当歌曲正在播放时,点击歌曲播放界面下方的分享键,会自动生成分享链接并复制此链接,可粘贴到聊天框分享当前播放的歌曲。
  8. 评论:当歌曲正在播放时,点击歌曲播放界面下方的评论区,可任意输入文字来评论当前歌曲。
  9. 设置:点击头像进入设置,可修改头像,设置用户基本信息。

4.3.2 播放器的后端

  1. 管理员登录:首页是数据的统计,图表可以分析当前用户的比例,以及歌曲、歌手、国际的比例。

2.用户管理:查询已经注册过系统的用户,并且可以去新增或者删除用户。

3.歌手管理:添加或者删除歌手,添加成功可以更新相应的歌手图片。歌曲管理,点击歌曲管理为歌手添加歌曲

4.歌单管理:输入添加歌单内容可以创建歌单、更新歌单的图片、对某个歌单有评论的管理、还可以对相应的歌单新增歌曲。

4.3.3 数据库设计

4.3.3.1 admin表

数据名称

数据类型

数据描述

id

int

主键

name

varchar(255)

账号

password

varchar(255)

密码

4.3.3.2 conllect表

数据名称

数据类型

数据描述

id

int

主键

user_id

int

用户id

type

tinyint(1)

收藏类型

song_id

int

歌曲id

song_list_id

int

歌单id

create_time

datetime(0)

收藏时间

4.3.3.3 comment表

数据名称

数据类型

数据描述

id

int

主键

user_id

int

用户id

type

tinyint(1)

评论类型

song_id

int

歌曲id

song_list_id

int

歌单id

content

varchar(255)

评论内容

create_time

datetime(0)

收藏时间

up

int

评论点赞数

4.3.3.4 consumer表

数据名称

数据类型

数据描述

id

int

主键

username

varchar(255)

账号

password

varchar(255)

密码

sex

tinyint(1)

性别

phone_num

char(15)

电话

email

char(30)

邮箱

birth

datetime(0)

生日

introduction

varchar(255)

签名

location

varchar(255)

地区

avator

varchar(255)

头像

create_time

datetime(0)

创建时间

update_time

datetime(0)

更新时间

4.3.3.5 list_song表

数据名称

数据类型

数据描述

id

int

主键

song_id

int

歌曲id

song_list_id

int

歌单id

4.3.3.6 rank表

数据名称

数据类型

数据描述

id

int

主键

song_list_id

int

歌单id

consumer_id

int

用户id

score

int

评分

4.3.3.7 singer表

数据名称

数据类型

数据描述

id

int

主键

name

varchar(255)

姓名

sex

tinyint(1)

性别

pic

varchar(255)

头像

birth

datetime(0)

生日

location

varchar(255)

地区

introduction

varchar(1600)

简介

4.3.3.8 song表

数据名称

数据类型

数据描述

id

int

主键

singer_id

int

歌手id

name

varchar(255)

歌名

introduction

varchar(255)

简介

create_time

datetime(0)

创建时间

update_time

datetime(0)

更新时间

pic

varchar(255)

歌曲图片

lyric

text

歌词

url

varchar(255)

歌曲地址

4.3.3.9 song_list表

数据名称

数据类型

数据描述

id

int

主键

title

varchar(255)

标题

pic

varchar(255)

歌单图片

introduction

text

简介

style

varchar(255)

风格

5 编程实现

5.1 外部接口-前端界面实现

5.1.1 登录页面

<div class="signin">

        <div class="signUp-head">

            <span>帐号登录</span>

        </div>

        <el-form :model="loginForm" ref="loginForm" label-width="70px" class="demo-ruleForm" :rules="rules">

            <el-form-item prop="username" label="用户名">

                <el-input v-model="loginForm.username" placeholder="用户名"></el-input>

            </el-form-item>

            <el-form-item prop="password" label="密码">

                <el-input type="password" v-model="loginForm.password" placeholder="密码" @keyup.enter.native="handleLoginIn"></el-input>

            </el-form-item>

            <div class="login-btn">

                <el-button @click="goSignUp">注册</el-button>

                <el-button type="primary" @click="handleLoginIn">登录</el-button>

            </div>

        </el-form>

    </div>

5.1.2 播放器

  <div class="play-bar" :class="{ show: !toggle }">

    <div @click="toggle = !toggle" class="item-up" :class="{ turn: toggle }">

      <svg class="icon">

        <use xlink:href="#icon-jiantou-shang-cuxiantiao"></use>

      </svg>

    </div>

    <div class="kongjian">

      <!-- 上一首 -->

      <div class="item" @click="prev">

        <svg class="icon">

          <use xlink:href="#icon-ziyuanldpi"></use>

        </svg>

      </div>

      <!-- 播放 -->

      <div class="item" @click="togglePlay">

        <svg class="icon">

          <use :xlink:href="playButtonUrl"></use>

        </svg>

      </div>

      <!-- 下一首 -->

      <div class="item" @click="next">

        <svg class="icon">

          <use xlink:href="#icon-ziyuanldpi1"></use>

        </svg>

      </div>

      <!-- 歌曲图片 -->

      <div class="item-img" @click="toLyric">

        <img :src="picUrl" />

      </div>

      <!-- 播放进度 -->

      <div class="playing-speed">

        <!-- 播放开始时间 -->

        <div class="current-time">{{ nowTime }}</div>

        <div class="progress-box">

          <div class="item-song-title">

            <div>{{ this.title }}</div>

            <div>{{ this.artist }}</div>

          </div>

          <div ref="progress" class="progress" @mousemove="mousemove">

            <!-- 进度条 -->

            <div ref="bg" class="bg" @click="updatemove">

              <div

                ref="curProgress"

                class="cur-progress"

                :style="{ width: curLength + '%' }"

              ></div>

            </div>

            <!-- 拖动的点点 -->

            <div

              ref="idot"

              class="idot"

              :style="{ left: curLength + '%' }"

              @mousedown="mousedown"

              @mouseup="mouseup"

            ></div>

          </div>

        </div>

        <!-- 播放结束时间 -->

        <div class="left-time">{{ songTime }}</div>

        <!-- 音量 -->

        <div class="item item-volume">

          <svg v-if="volume == 0" class="icon">

            <use xlink:href="#icon-yinliangjingyinheix"></use>

          </svg>

          <svg v-else class="icon">

            <use xlink:href="#icon-yinliang1"></use>

          </svg>

          <el-slider

            class="volume"

            v-model="volume"

            :vertical="true"

          ></el-slider>

        </div>

        <!-- 收藏 -->

        <div class="item" @click="collection">

          <svg :class="{ active: isActive }" class="icon">

            <use xlink:href="#icon-xihuan-shi"></use>

          </svg>

        </div>

        <!-- 分享 -->

        <div class="item" @click="share" style="padding-bottom: -5px">

          <svg

            width="16"

            height="19"

            xmlns="http://www.w3.org/2000/svg"

            xmlns:svg="http://www.w3.org/2000/svg"

            xmlns:se="http://svg-edit.googlecode.com"

            class="bi bi-share-fill"

            se:nonce="62333"

          >

            <g class="layer">

              <title>Layer 1</title>

              <path

                d="m11,2.5a2.5,2.5 0 1 1 0.6,1.63l-6.72,3.12a2.5,2.5 0 0 1 0,1.5l6.72,3.12a2.5,2.5 0 1 1 -0.48,0.88l-6.72,-3.12a2.5,2.5 0 1 1 0,-3.26l6.72,-3.12a2.5,2.5 0 0 1 -0.12,-0.75z"

                id="svg_62333_1"

              />

            </g>

          </svg>

        </div>

        <!-- 下载 -->

        <div class="item" @click="download">

          <svg class="icon">

            <use xlink:href="#icon-xiazai"></use>

          </svg>

        </div>

        <!-- 当前播放的歌曲列表 -->

        <div class="item" @click="changeAside">

          <svg class="icon">

            <use xlink:href="#icon-liebiao"></use>

          </svg>

        </div>

      </div>

    </div>

  </div>

5.1.3 首页

  <div class="home">

    <swiper />

    <div class="section" v-for="(item,index) in songsList" :key="index">

      <div class="section-title">{{item.name}}</div>

      <content-list :contentList="item.list"></content-list>

    </div>

  </div>

5.1.4 歌词页面

  <div class="song-lyric">

    <h1 class="lyric-title">歌词</h1>

    <!-- 有歌词 -->

    <ul class="has-lyric" v-if="lyr.length" key="index">

      <li v-for="(item, index) in lyr" v-bind:key="index">

        {{ item[1] }}

      </li>

    </ul>

    <!-- 没有歌词 -->

    <div v-else class="no-lyric" key="no-lyric">

      <span>暂无歌词</span>

    </div>

  </div>

5.1.5 歌单详情页

    <div class="song-list-album">

        <div class="album-slide">

            <div class="album-img">

                <img :src="attachImageUrl(tempList.pic)">

            </div>

            <div class="album-info">

                <h2>简介:</h2>

                <span>

                    {{tempList.introduction}}

                </span>

            </div>

        </div>

        <div class="album-content">

            <div class="album-title">

                <p>{{tempList.title}}</p>

            </div>

            <div class="album-score">

                <div>

                    <h3>歌单评分:</h3>

                    <div>

                        <el-rate v-model="average" disabled></el-rate>

                    </div>                    

                </div>

                <span>{{average*2}}</span>

                <div>

                    <h3>评价:</h3>

                    <div @click="setRank">

                        <el-rate v-model="rank" allow-half show-text></el-rate>

                    </div>                    

                </div>

            </div>

            <div class="songs-body">

                <album-content :songList="listOfSongs">

                    <template slot="title">歌单</template>

                </album-content>

                <comment :playId="songListId" :type="1"></comment>

            </div>

        </div>        

    </div>

5.2 内部接口-后端实现

5.2.1 管理员模块

/**
 * 判断是否登录成功
 */
@ApiOperation(value = "登录")
@RequestMapping(value = "/admin/login/status",method = RequestMethod.POST)
public Object loginStatus(HttpServletRequest request, HttpSession session){
    JSONObject jsonObject = new JSONObject();
    String name = request.getParameter("name");
    String password = request.getParameter("password");
    boolean flag = adminService.verifyPassword(name,password);
    if(flag){
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"登录成功");
        session.setAttribute(Consts.NAME,name);
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"用户名或密码错误");
    return jsonObject;
}

/**
 * 打包项目接口
 */
@ApiOperation(value = "后台接口")
@GetMapping(value = "/manage")
public ModelAndView index() {
    return new ModelAndView("/src/main/resources/static/screenIndex/index.html");
}

5.2.2 收藏模块

/**
 * 添加收藏
 */
@ApiOperation(value = "添加收藏")
@RequestMapping(value = "/add",method = RequestMethod.POST)
public Object addCollect(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    String userId = request.getParameter("userId");           //用户id
    String type = request.getParameter("type");               //收藏类型(0歌曲1歌单)
    String songId = request.getParameter("songId");           //歌曲id
    if(songId==null||songId.equals("")){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"收藏歌曲为空");
        return jsonObject;
    }
    if(CollectService.existSongId(Integer.parseInt(userId),Integer.parseInt(songId))){
        jsonObject.put(Consts.CODE,2);
        jsonObject.put(Consts.MSG,"已收藏");
        return jsonObject;
    }

    //保存到收藏的对象中
    Collect Collect = new Collect();
    Collect.setUserId(Integer.parseInt(userId));
    Collect.setType(new Byte(type));
    Collect.setSongId(Integer.parseInt(songId));

    boolean flag = CollectService.insert(Collect);
    if(flag){   //保存成功
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"收藏成功");
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"收藏失败");
    return jsonObject;
}

/**
 * 删除收藏
 */
@ApiOperation(value = "取消收藏")
@RequestMapping(value = "/delete",method = RequestMethod.GET)
public Object deleteCollect(HttpServletRequest request){
    String userId = request.getParameter("userId");           //用户id
    String songId = request.getParameter("songId");           //歌曲id
    boolean flag = CollectService.deleteByUserIdSongId(Integer.parseInt(userId),Integer.parseInt(songId));
    return flag;
}

/**
 * 查询所有收藏
 */
@ApiOperation(value = "查看所有收藏")
@RequestMapping(value = "/allCollect",method = RequestMethod.GET)
public Object allCollect(HttpServletRequest request){
    return CollectService.allCollect();
}

/**
 * 查询某个用户的收藏列表
 */
@ApiOperation(value = "用户的收藏列表")
@RequestMapping(value = "/collectOfUserId",method = RequestMethod.GET)
public Object collectOfUserId(HttpServletRequest request){
    String userId = request.getParameter("userId");          //用户id
    return CollectService.collectOfUserId(Integer.parseInt(userId));
}

5.2.3 评论区模块

/**
 * 添加评论
 */
@ApiOperation(value = "添加评论")
@RequestMapping(value = "/add",method = RequestMethod.POST)
public Object addComment(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    String userId = request.getParameter("userId");           //用户id
    String type = request.getParameter("type");               //评论类型(0歌曲1歌单)
    String songId = request.getParameter("songId");           //歌曲id
    String songListId = request.getParameter("songListId");   //歌单id
    String content = request.getParameter("content").trim();         //评论内容

    //保存到评论的对象中
    Comment comment = new Comment();
    comment.setUserId(Integer.parseInt(userId));
    comment.setType(new Byte(type));
    if(new Byte(type) ==0){
        comment.setSongId(Integer.parseInt(songId));
    }else{
        comment.setSongListId(Integer.parseInt(songListId));
    }
    comment.setContent(content);
    boolean flag = commentService.insert(comment);
    if(flag){   //保存成功
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"评论成功");
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"评论失败");
    return jsonObject;
}

/**
 * 修改评论
 */
@ApiOperation(value = "修改评论")
@RequestMapping(value = "/update",method = RequestMethod.POST)
public Object updateComment(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    String id = request.getParameter("id").trim();                   //主键
    String userId = request.getParameter("userId").trim();           //用户id
    String type = request.getParameter("type").trim();               //评论类型(0歌曲1歌单)
    String songId = request.getParameter("songId").trim();           //歌曲id
    String songListId = request.getParameter("songListId").trim();   //歌单id
    String content = request.getParameter("content").trim();         //评论内容

    //保存到评论的对象中
    Comment comment = new Comment();
    comment.setId(Integer.parseInt(id));
    comment.setUserId(Integer.parseInt(userId));
    comment.setType(new Byte(type));
    if(songId!=null&&songId.equals("")){
        songId = null;
    }else {
        comment.setSongId(Integer.parseInt(songId));
    }
    if(songListId!=null&&songListId.equals("")){
        songListId = null;
    }else {
        comment.setSongListId(Integer.parseInt(songListId));
    }
    comment.setContent(content);

    boolean flag = commentService.update(comment);
    if(flag){   //保存成功
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"修改成功");
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"修改失败");
    return jsonObject;
}

/**
 * 删除评论
 */
@ApiOperation(value = "删除评论")
@RequestMapping(value = "/delete",method = RequestMethod.GET)
public Object deleteComment(HttpServletRequest request){
    String id = request.getParameter("id").trim();          //主键
    boolean flag = commentService.delete(Integer.parseInt(id));
    return flag;
}

/**
 * 根据主键查询整个对象
 */
@ApiOperation(value = "根据主键查询整个对象")
@RequestMapping(value = "/selectByPrimaryKey",method = RequestMethod.GET)
public Object selectByPrimaryKey(HttpServletRequest request){
    String id = request.getParameter("id").trim();          //主键
    return commentService.selectByPrimaryKey(Integer.parseInt(id));
}

/**
 * 查询所有评论
 */
@ApiOperation(value = "查询所有评论")
@RequestMapping(value = "/allComment",method = RequestMethod.GET)
public Object allComment(HttpServletRequest request){
    return commentService.allComment();
}

/**
 * 查询某个歌曲下的所有评论
 */
@ApiOperation(value = "查询某个歌曲下的所有评论")
@RequestMapping(value = "/commentOfSongId",method = RequestMethod.GET)
public Object commentOfSongId(HttpServletRequest request){
    String songId = request.getParameter("songId");          //歌曲id
    return commentService.commentOfSongId(Integer.parseInt(songId));
}

/**
 * 查询某个歌单下的所有评论
 */
@ApiOperation(value = "查询某个歌单下的所有评论")
@RequestMapping(value = "/commentOfSongListId",method = RequestMethod.GET)
public Object commentOfSongListId(HttpServletRequest request){
    String songListId = request.getParameter("songListId");          //歌曲id
    return commentService.commentOfSongListId(Integer.parseInt(songListId));
}

/**
 * 给某个评论点赞
 */
@ApiOperation(value = "给某个评论点赞")
@RequestMapping(value = "/like",method = RequestMethod.POST)
public Object like(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    String id = request.getParameter("id").trim();           //主键
    String up = request.getParameter("up").trim();           //用户id

    //保存到评论的对象中
    Comment comment = new Comment();
    comment.setId(Integer.parseInt(id));
    comment.setUp(Integer.parseInt(up));

    boolean flag = commentService.update(comment);
    if(flag){   //保存成功
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"点赞成功");
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"点赞失败");
    return jsonObject;
}

5.2.4 前端用户控制模块

/**
 * 添加前端用户
 */
@ApiOperation(value = "注册、添加前端用户")
@RequestMapping(value = "/add",method = RequestMethod.POST)
public Object addConsumer(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    String username = request.getParameter("username").trim();     //账号
    String password = request.getParameter("password").trim();     //密码
    String sex = request.getParameter("sex").trim();               //性别
    String phoneNum = request.getParameter("phoneNum").trim();     //手机号
    String email = request.getParameter("email").trim();           //电子邮箱
    String birth = request.getParameter("birth").trim();           //生日
    String introduction = request.getParameter("introduction").trim();//签名
    String location = request.getParameter("location").trim();      //地区
    String avator = request.getParameter("avator").trim();          //头像地址

    if(username==null||username.equals("")){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"用户名不能为空");
        return jsonObject;
    }

    Consumer consumer1 = consumerService.getByUsername(username);
    if(consumer1!=null){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"用户名已存在");
        return jsonObject;
    }

    if(password==null||password.equals("")){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"密码不能为空");
        return jsonObject;
    }

    //把生日转换成Date格式
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    Date birthDate = new Date();
    try {
        birthDate = dateFormat.parse(birth);
    } catch (ParseException e) {
        e.printStackTrace();
    }

    //保存到前端用户的对象中
    Consumer consumer = new Consumer();
    consumer.setUsername(username);
    consumer.setPassword(password);
    consumer.setSex(new Byte(sex));
    consumer.setPhoneNum(phoneNum);
    consumer.setEmail(email);
    consumer.setBirth(birthDate);
    consumer.setIntroduction(introduction);
    consumer.setLocation(location);
    consumer.setAvator(avator);
    boolean flag = consumerService.insert(consumer);
    if(flag){   //保存成功
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"添加成功");
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"添加失败");
    return jsonObject;
}

/**
 * 修改前端用户
 */
@ApiOperation(value = "修改前端用户")
@RequestMapping(value = "/update",method = RequestMethod.POST)
public Object updateConsumer(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    String id = request.getParameter("id").trim();          //主键
    String username = request.getParameter("username").trim();     //账号
    String password = request.getParameter("password").trim();     //密码
    String sex = request.getParameter("sex").trim();               //性别
    String phoneNum = request.getParameter("phoneNum").trim();     //手机号
    String email = request.getParameter("email").trim();           //电子邮箱
    String birth = request.getParameter("birth").trim();           //生日
    String introduction = request.getParameter("introduction").trim();//签名
    String location = request.getParameter("location").trim();      //地区

    if(username==null||username.equals("")){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"用户名不能为空");
        return jsonObject;
    }
    if(password==null||password.equals("")){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"密码不能为空");
        return jsonObject;
    }
    //把生日转换成Date格式
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    Date birthDate = new Date();
    try {
        birthDate = dateFormat.parse(birth);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    //保存到前端用户的对象中
    Consumer consumer = new Consumer();
    consumer.setId(Integer.parseInt(id));
    consumer.setUsername(username);
    consumer.setPassword(password);
    consumer.setSex(new Byte(sex));
    consumer.setPhoneNum(phoneNum);
    consumer.setEmail(email);
    consumer.setBirth(birthDate);
    consumer.setIntroduction(introduction);
    consumer.setLocation(location);
    boolean flag = consumerService.update(consumer);
    if(flag){   //保存成功
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"修改成功");
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"修改失败");
    return jsonObject;
}


/**
 * 删除前端用户
 */
@ApiOperation(value = "删除前端用户")
@RequestMapping(value = "/delete",method = RequestMethod.GET)
public Object deleteConsumer(HttpServletRequest request){
    String id = request.getParameter("id").trim();          //主键
    boolean flag = consumerService.delete(Integer.parseInt(id));
    return flag;
}

/**
 * 根据主键查询整个对象
 */
@ApiOperation(value = "根据主键查询整个对象")
@RequestMapping(value = "/selectByPrimaryKey",method = RequestMethod.GET)
public Object selectByPrimaryKey(HttpServletRequest request){
    String id = request.getParameter("id").trim();          //主键
    return consumerService.selectByPrimaryKey(Integer.parseInt(id));
}

/**
 * 查询所有前端用户
 */
@ApiOperation(value = "查询所有前端用户")
@RequestMapping(value = "/allConsumer",method = RequestMethod.GET)
public Object allConsumer(HttpServletRequest request){
    return consumerService.allConsumer();
}

/**
 * 更新前端用户图片
 */
@ApiOperation(value = "更新前端用户图片")
@RequestMapping(value = "/updateConsumerPic",method = RequestMethod.POST)
public Object updateConsumerPic(@RequestParam("file") MultipartFile avatorFile, @RequestParam("id")int id){
    JSONObject jsonObject = new JSONObject();
    if(avatorFile.isEmpty()){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"文件上传失败");
        return jsonObject;
    }
    //文件名=当前时间到毫秒+原来的文件名
    String fileName = System.currentTimeMillis()+avatorFile.getOriginalFilename();
    //文件路径
    String filePath = System.getProperty("user.dir")+System.getProperty("file.separator")+"userImages";
    //如果文件路径不存在,新增该路径
    File file1 = new File(filePath);
    if(!file1.exists()){
        file1.mkdir();
    }
    //实际的文件地址
    File dest = new File(filePath+System.getProperty("file.separator")+fileName);
    //存储到数据库里的相对文件地址
    String storeAvatorPath = "/userImages/"+fileName;
    try {
        avatorFile.transferTo(dest);
        Consumer consumer = new Consumer();
        consumer.setId(id);
        consumer.setAvator(storeAvatorPath);
        boolean flag = consumerService.update(consumer);
        if(flag){
            jsonObject.put(Consts.CODE,1);
            jsonObject.put(Consts.MSG,"上传成功");
            jsonObject.put("avator",storeAvatorPath);
            return jsonObject;
        }
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"上传失败");
        return jsonObject;
    } catch (IOException e) {
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"上传失败"+e.getMessage());
    }finally {
        return jsonObject;
    }
}

/**
 * 前端用户登录
 */
@ApiOperation(value = "前端用户登录")
@RequestMapping(value = "/login",method = RequestMethod.POST)
public Object login(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    String username = request.getParameter("username").trim();     //账号
    String password = request.getParameter("password").trim();     //密码
    if(username==null||username.equals("")){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"用户名不能为空");
        return jsonObject;
    }
    if(password==null||password.equals("")){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"密码不能为空");
        return jsonObject;
    }

    //保存到前端用户的对象中
    Consumer consumer = new Consumer();
    consumer.setUsername(username);
    consumer.setPassword(password);
    boolean flag = consumerService.verifyPassword(username,password);
    if(flag){   //验证成功
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"登录成功");
        jsonObject.put("userMsg",consumerService.getByUsername(username));
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"用户名或密码错误");
    return jsonObject;
}

5.2.5 歌单模块

/**
 * 给歌单添加歌曲
 */
@ApiOperation(value = "给歌单添加歌曲")
@RequestMapping(value = "/add",method = RequestMethod.POST)
public Object addListSong(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    //获取前端传来的参数
    String songId = request.getParameter("songId").trim();  //歌曲id
    String songListId = request.getParameter("songListId").trim(); //歌单id
    ListSong listSong = new ListSong();
    listSong.setSongId(Integer.parseInt(songId));
    listSong.setSongListId(Integer.parseInt(songListId));
    boolean flag = listSongService.insert(listSong);
    if(flag){
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"保存成功");
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"保存失败");
    return jsonObject;

}

/**
 * 根据歌单id查询歌曲
 */
@ApiOperation(value = "根据歌单id查询歌曲")
@RequestMapping(value = "/detail",method = RequestMethod.GET)
public Object detail(HttpServletRequest request){
    String songListId = request.getParameter("songListId");
    return listSongService.listSongOfSongListId(Integer.parseInt(songListId));
}

/**
 * 删除歌单里的歌曲
 */
@ApiOperation(value = "删除歌单里的歌曲")
@RequestMapping(value = "/delete",method = RequestMethod.GET)
public Object delete(HttpServletRequest request){
    String songId = request.getParameter("songId").trim();                 //歌曲id
    String songListId = request.getParameter("songListId").trim();        //歌单id
    boolean flag = listSongService.deleteBySongIdAndSongListId(Integer.parseInt(songId),Integer.parseInt(songListId));
    return flag;
}

5.2.6 评价模块

/**
 * 新增评价
 */
@ApiOperation(value = "新增评价")
@RequestMapping(value = "/rank/add",method = RequestMethod.POST)
public Object add(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    String songListId = request.getParameter("songListId");
    String consumerId = request.getParameter("consumerId");
    String score = request.getParameter("score");

    Rank rank = new Rank();
    rank.setSongListId(Integer.parseInt(songListId));
    rank.setConsumerId(Integer.parseInt(consumerId));
    rank.setScore(Integer.parseInt(score));
    boolean flag = rankService.insert(rank);
    if(flag){
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"评价成功");
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"评价失败");
    return jsonObject;
}

/**
 * 计算平均分
 */
@ApiOperation(value = "计算平均分")
@RequestMapping(value = "/rank",method = RequestMethod.GET)
public Object rankOfSongListId(HttpServletRequest request){
    String songListId = request.getParameter("songListId");
    return rankService.rankOfSongListId(Integer.parseInt(songListId));
}

5.2.7 歌手模块

/**
 * 添加歌手
 */
@ApiOperation(value = "添加歌手")
@RequestMapping(value = "/add",method = RequestMethod.POST)
public Object addSinger(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    String name = request.getParameter("name").trim();      //姓名
    String sex = request.getParameter("sex").trim();        //性别
    String pic = request.getParameter("pic").trim();        //头像
    String birth = request.getParameter("birth").trim();    //生日
    String location = request.getParameter("location").trim();//地区
    String introduction = request.getParameter("introduction").trim();//简介
    //把生日转换成Date格式
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    Date birthDate = new Date();
    try {
        birthDate = dateFormat.parse(birth);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    //保存到歌手的对象中
    Singer singer = new Singer();
    singer.setName(name);
    singer.setSex(new Byte(sex));
    singer.setPic(pic);
    singer.setBirth(birthDate);
    singer.setLocation(location);
    singer.setIntroduction(introduction);
    boolean flag = singerService.insert(singer);
    if(flag){   //保存成功
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"添加成功");
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"添加失败");
    return jsonObject;
}

/**
 * 修改歌手
 */
@ApiOperation(value = "修改歌手")
@RequestMapping(value = "/update",method = RequestMethod.POST)
public Object updateSinger(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    String id = request.getParameter("id").trim();          //主键
    String name = request.getParameter("name").trim();      //姓名
    String sex = request.getParameter("sex").trim();        //性别
    String birth = request.getParameter("birth").trim();    //生日
    String location = request.getParameter("location").trim();//地区
    String introduction = request.getParameter("introduction").trim();//简介
    //把生日转换成Date格式
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    Date birthDate = new Date();
    try {
        birthDate = dateFormat.parse(birth);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    //保存到歌手的对象中
    Singer singer = new Singer();
    singer.setId(Integer.parseInt(id));
    singer.setName(name);
    singer.setSex(new Byte(sex));
    singer.setBirth(birthDate);
    singer.setLocation(location);
    singer.setIntroduction(introduction);
    boolean flag = singerService.update(singer);
    if(flag){   //保存成功
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"修改成功");
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"修改失败");
    return jsonObject;
}


/**
 * 删除歌手
 */
@ApiOperation(value = "删除歌手")
@RequestMapping(value = "/delete",method = RequestMethod.GET)
public Object deleteSinger(HttpServletRequest request){
    String id = request.getParameter("id").trim();          //主键
    boolean flag = singerService.delete(Integer.parseInt(id));
    return flag;
}

/**
 * 根据主键查询整个对象
 */
@ApiOperation(value = "根据主键查询整个对象")
@RequestMapping(value = "/selectByPrimaryKey",method = RequestMethod.GET)
public Object selectByPrimaryKey(HttpServletRequest request){
    String id = request.getParameter("id").trim();          //主键
    return singerService.selectByPrimaryKey(Integer.parseInt(id));
}

/**
 * 查询所有歌手
 */
@ApiOperation(value = "查询所有歌手")
@RequestMapping(value = "/allSinger",method = RequestMethod.GET)
public Object allSinger(HttpServletRequest request){
    return singerService.allSinger();
}

/**
 * 根据歌手名字模糊查询列表
 */
@ApiOperation(value = "根据歌手名字模糊查询列表")
@RequestMapping(value = "/singerOfName",method = RequestMethod.GET)
public Object singerOfName(HttpServletRequest request){
    String name = request.getParameter("name").trim();          //歌手名字
    return singerService.singerOfName("%"+name+"%");
}

/**
 * 根据性别查询
 */
@ApiOperation(value = "根据性别查询")
@RequestMapping(value = "/singerOfSex",method = RequestMethod.GET)
public Object singerOfSex(HttpServletRequest request){
    String sex = request.getParameter("sex").trim();          //性别
    return singerService.singerOfSex(Integer.parseInt(sex));
}

/**
 * 更新歌手图片
 */
@ApiOperation(value = "更新歌手图片")
@RequestMapping(value = "/updateSingerPic",method = RequestMethod.POST)
public Object updateSingerPic(@RequestParam("file") MultipartFile avatorFile, @RequestParam("id")int id){
    JSONObject jsonObject = new JSONObject();
    if(avatorFile.isEmpty()){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"文件上传失败");
        return jsonObject;
    }
    //文件名=当前时间到毫秒+原来的文件名
    String fileName = System.currentTimeMillis()+avatorFile.getOriginalFilename();
    //文件路径
    String filePath = System.getProperty("user.dir")+System.getProperty("file.separator")+"img"
            +System.getProperty("file.separator")+"singerPic";
    //如果文件路径不存在,新增该路径
    File file1 = new File(filePath);
    if(!file1.exists()){
        file1.mkdir();
    }
    //实际的文件地址
    File dest = new File(filePath+System.getProperty("file.separator")+fileName);
    //存储到数据库里的相对文件地址
    String storeAvatorPath = "/img/singerPic/"+fileName;
    try {
        avatorFile.transferTo(dest);
        Singer singer = new Singer();
        singer.setId(id);
        singer.setPic(storeAvatorPath);
        boolean flag = singerService.update(singer);
        if(flag){
            jsonObject.put(Consts.CODE,1);
            jsonObject.put(Consts.MSG,"上传成功");
            jsonObject.put("pic",storeAvatorPath);
            return jsonObject;
        }
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"上传失败");
        return jsonObject;
    } catch (IOException e) {
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"上传失败"+e.getMessage());
    }finally {
        return jsonObject;
    }
}

5.2.8 歌曲模块

/**
 * 添加歌曲
 */
@ApiOperation(value = "添加歌曲")
@RequestMapping(value = "/add",method = RequestMethod.POST)
public Object addSong(HttpServletRequest request, @RequestParam("file")MultipartFile mpFile){
    JSONObject jsonObject = new JSONObject();
    //获取前端传来的参数
    String singerId = request.getParameter("singerId").trim();  //所属歌手id
    String name = request.getParameter("name").trim();          //歌名
    String introduction = request.getParameter("introduction").trim();          //简介
    String pic = "/img/songPic/tubiao.jpg";                     //默认图片
    String lyric = request.getParameter("lyric").trim();     //歌词
    //上传歌曲文件
    if(mpFile.isEmpty()){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"歌曲上传失败");
        return jsonObject;
    }
    //文件名=当前时间到毫秒+原来的文件名
    String fileName = System.currentTimeMillis()+mpFile.getOriginalFilename();
    //文件路径
    String filePath = System.getProperty("user.dir")+System.getProperty("file.separator")+"song";
    //如果文件路径不存在,新增该路径
    File file1 = new File(filePath);
    if(!file1.exists()){
        file1.mkdir();
    }
    //实际的文件地址
    File dest = new File(filePath+System.getProperty("file.separator")+fileName);
    //存储到数据库里的相对文件地址
    String storeUrlPath = "/song/"+fileName;
    try {
        mpFile.transferTo(dest);
        Song song = new Song();
        song.setSingerId(Integer.parseInt(singerId));
        song.setName(name);
        song.setIntroduction(introduction);
        song.setPic(pic);
        song.setLyric(lyric);
        song.setUrl(storeUrlPath);
        boolean flag = songService.insert(song);
        if(flag){
            jsonObject.put(Consts.CODE,1);
            jsonObject.put(Consts.MSG,"保存成功");
            jsonObject.put("avator",storeUrlPath);
            return jsonObject;
        }
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"保存失败");
        return jsonObject;
    } catch (IOException e) {
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"保存失败"+e.getMessage());
    }finally {
        return jsonObject;
    }
}

/**
 * 根据歌手id查询歌曲
 */
@ApiOperation(value = "根据歌手id查询歌曲")
@RequestMapping(value = "/singer/detail",method = RequestMethod.GET)
public Object songOfSingerId(HttpServletRequest request){
    String singerId = request.getParameter("singerId");
    return songService.songOfSingerId(Integer.parseInt(singerId));
}

/**
 * 修改歌曲
 */
@ApiOperation(value = "修改歌曲")
@RequestMapping(value = "/update",method = RequestMethod.POST)
public Object updateSong(HttpServletRequest request){
    JSONObject jsonObject = new JSONObject();
    String id = request.getParameter("id").trim();          //主键
    String name = request.getParameter("name").trim();      //歌名
    String introduction = request.getParameter("introduction").trim();//专辑
    String lyric = request.getParameter("lyric").trim();    //歌词

    //保存到歌手的对象中
    Song song = new Song();
    song.setId(Integer.parseInt(id));
    song.setName(name);
    song.setIntroduction(introduction);
    song.setLyric(lyric);
    boolean flag = songService.update(song);
    if(flag){   //保存成功
        jsonObject.put(Consts.CODE,1);
        jsonObject.put(Consts.MSG,"修改成功");
        return jsonObject;
    }
    jsonObject.put(Consts.CODE,0);
    jsonObject.put(Consts.MSG,"修改失败");
    return jsonObject;
}

/**
 * 删除歌曲
 */
@ApiOperation(value = "删除歌曲")
@RequestMapping(value = "/delete",method = RequestMethod.GET)
public Object deleteSinger(HttpServletRequest request){
    //-TODO 先查询到数据库中对应的文件地址,删除掉它再进行下面的代码
    String id = request.getParameter("id").trim();          //主键
    boolean flag = songService.delete(Integer.parseInt(id));
    return flag;
}

/**
 * 更新歌曲图片
 */
@ApiOperation(value = "更新歌曲图片")
@RequestMapping(value = "/updateSongPic",method = RequestMethod.POST)
public Object updateSongPic(@RequestParam("file") MultipartFile avatorFile, @RequestParam("id")int id){
    JSONObject jsonObject = new JSONObject();
    if(avatorFile.isEmpty()){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"文件上传失败");
        return jsonObject;
    }
    //文件名=当前时间到毫秒+原来的文件名
    String fileName = System.currentTimeMillis()+avatorFile.getOriginalFilename();
    //文件路径
    String filePath = System.getProperty("user.dir")+System.getProperty("file.separator")+"img"
            +System.getProperty("file.separator")+"songPic";
    //如果文件路径不存在,新增该路径
    File file1 = new File(filePath);
    if(!file1.exists()){
        file1.mkdir();
    }
    //实际的文件地址
    File dest = new File(filePath+System.getProperty("file.separator")+fileName);
    //存储到数据库里的相对文件地址
    String storeAvatorPath = "/img/songPic/"+fileName;
    try {
        avatorFile.transferTo(dest);
        Song song = new Song();
        song.setId(id);
        song.setPic(storeAvatorPath);
        boolean flag = songService.update(song);
        if(flag){
            jsonObject.put(Consts.CODE,1);
            jsonObject.put(Consts.MSG,"上传成功");
            jsonObject.put("pic",storeAvatorPath);
            return jsonObject;
        }
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"上传失败");
        return jsonObject;
    } catch (IOException e) {
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"上传失败"+e.getMessage());
    }finally {
        return jsonObject;
    }
}


/**
 * 更新歌曲
 */
@ApiOperation(value = "更新歌曲")
@RequestMapping(value = "/updateSongUrl",method = RequestMethod.POST)
public Object updateSongUrl(@RequestParam("file") MultipartFile avatorFile, @RequestParam("id")int id){
    JSONObject jsonObject = new JSONObject();
    if(avatorFile.isEmpty()){
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"文件上传失败");
        return jsonObject;
    }
    //文件名=当前时间到毫秒+原来的文件名
    String fileName = System.currentTimeMillis()+avatorFile.getOriginalFilename();
    //文件路径
    String filePath = System.getProperty("user.dir")+System.getProperty("file.separator")+"song";
    //如果文件路径不存在,新增该路径
    File file1 = new File(filePath);
    if(!file1.exists()){
        file1.mkdir();
    }
    //实际的文件地址
    File dest = new File(filePath+System.getProperty("file.separator")+fileName);
    //存储到数据库里的相对文件地址
    String storeAvatorPath = "/song/"+fileName;
    try {
        avatorFile.transferTo(dest);
        Song song = new Song();
        song.setId(id);
        song.setUrl(storeAvatorPath);
        boolean flag = songService.update(song);
        if(flag){
            jsonObject.put(Consts.CODE,1);
            jsonObject.put(Consts.MSG,"上传成功");
            jsonObject.put("avator",storeAvatorPath);
            return jsonObject;
        }
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"上传失败");
        return jsonObject;
    } catch (IOException e) {
        jsonObject.put(Consts.CODE,0);
        jsonObject.put(Consts.MSG,"上传失败"+e.getMessage());
    }finally {
        return jsonObject;
    }
}

/**
 * 根据歌曲id查询歌曲对象
 */
@ApiOperation(value = "根据歌曲id查询歌曲对象")
@RequestMapping(value = "/detail",method = RequestMethod.GET)
public Object detail(HttpServletRequest request){
    String songId = request.getParameter("songId");
    return songService.selectByPrimaryKey(Integer.parseInt(songId));
}

/**
 * 根据歌手名字精确查询歌曲
 */
@ApiOperation(value = "根据歌手名字精确查询歌曲")
@RequestMapping(value = "/songOfSongName",method = RequestMethod.GET)
public Object songOfSongName(HttpServletRequest request){
    String songName = request.getParameter("songName");
    return songService.songOfName(songName);
}

/**
 * 根据歌手名字模糊查询歌曲
 */
@ApiOperation(value = "根据歌手名字模糊查询歌曲")
@RequestMapping(value = "/likeSongOfName",method = RequestMethod.GET)
public Object likeSongOfName(HttpServletRequest request){
    String songName = request.getParameter("songName");
    return songService.likeSongOfName(songName);
}

/**
 * 查询所有歌曲
 */
@ApiOperation(value = "查询所有歌曲")
@RequestMapping(value = "/allSong",method = RequestMethod.GET)
public Object allSong(HttpServletRequest request){
    return songService.allSong();
}

5.3 数据库交互

<select id="verifyPassword" resultType="java.lang.Integer">
    select count(*) from admin where name=#{username} and password=#{password}
</select>

<resultMap id="BaseResultMap" type="com.rabbiter.music.pojo.Collect" >
    <id column="id" jdbcType="INTEGER" property="id"/>
    <result column="user_id" jdbcType="INTEGER" property="userId"/>
    <result column="type" jdbcType="TINYINT" property="type"/>
    <result column="song_id" jdbcType="INTEGER" property="songId"/>
    <result column="song_list_id" jdbcType="INTEGER" property="songListId"/>
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
</resultMap>

<sql id="Base_Column_List">
    id,user_id,type,song_id,song_list_id,create_time
</sql>

<insert id="insert" parameterType="com.rabbiter.music.pojo.Collect">
    insert into collect
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null">
            id,
        </if>
        <if test="userId != null">
            user_id,
        </if>
        <if test="type != null">
            type,
        </if>
        <if test="songId != null">
            song_id,
        </if>
        <if test="songListId != null">
            song_list_id,
        </if>
        create_time,
    </trim>
    <trim prefix=" values (" suffix=")" suffixOverrides=",">
        <if test="id != null">
            #{id},
        </if>
        <if test="userId != null">
            #{userId},
        </if>
        <if test="type != null">
            #{type},
        </if>
        <if test="songId != null">
            #{songId},
        </if>
        <if test="songListId != null">
            #{songListId},
        </if>
        now(),
    </trim>        
</insert>

<delete id="delete">
    delete from collect
    where id=#{id}
</delete>

<delete id="deleteByUserIdSongId" parameterType="java.lang.Integer">
    delete from collect
    where user_id = #{userId} and song_id = #{songId}
</delete>

<select id="allCollect" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from collect
</select>

<select id="collectOfUserId" resultMap="BaseResultMap" parameterType="java.lang.Integer">
    select
    <include refid="Base_Column_List"/>
    from collect
    where user_id = #{userId}
</select>

<select id="existSongId" resultType="java.lang.Integer">
    select count(*)
    from collect
    where user_id = #{userId} and song_id = #{songId}
</select>

<resultMap id="BaseResultMap" type="com.rabbiter.music.pojo.Comment" >
    <id column="id" jdbcType="INTEGER" property="id"/>
    <result column="user_id" jdbcType="INTEGER" property="userId"/>
    <result column="type" jdbcType="TINYINT" property="type"/>
    <result column="song_id" jdbcType="INTEGER" property="songId"/>
    <result column="song_list_id" jdbcType="INTEGER" property="songListId"/>
    <result column="content" jdbcType="VARCHAR" property="content"/>
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
    <result column="up" jdbcType="INTEGER" property="up"/>
</resultMap>

<sql id="Base_Column_List">
    id,user_id,type,song_id,song_list_id,content,create_time,up
</sql>

<insert id="insert" parameterType="com.rabbiter.music.pojo.Comment">
    insert into comment
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null">
            id,
        </if>
        <if test="userId != null">
            user_id,
        </if>
        <if test="type != null">
            type,
        </if>
        <if test="songId != null">
            song_id,
        </if>
        <if test="songListId != null">
            song_list_id,
        </if>
        <if test="content != null">
            content,
        </if>
        create_time,
        <if test="up != null">
            up,
        </if>
    </trim>
    <trim prefix=" values (" suffix=")" suffixOverrides=",">
        <if test="id != null">
            #{id},
        </if>
        <if test="userId != null">
            #{userId},
        </if>
        <if test="type != null">
            #{type},
        </if>
        <if test="songId != null">
            #{songId},
        </if>
        <if test="songListId != null">
            #{songListId},
        </if>
        <if test="content != null">
            #{content},
        </if>
        now(),
        <if test="up != null">
            #{up},
        </if>
    </trim>        
</insert>

<update id="update" parameterType="com.rabbiter.music.pojo.Comment">
    update comment
    <set>
        <if test="userId != null">
            user_id = #{userId},
        </if>
        <if test="type != null">
            type = #{type},
        </if>
        <if test="songId != null">
            song_id = #{songId},
        </if>
        <if test="songListId != null">
            song_list_id = #{songListId},
        </if>
        <if test="content != null">
            content = #{content},
        </if>
        <if test="up != null">
            up = #{up},
        </if>
    </set>
    where id = #{id}
</update>

<delete id="delete" parameterType="java.lang.Integer">
    delete from comment
    where id=#{id}
</delete>

<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
    select
    <include refid="Base_Column_List"/>
    from comment
    where id=#{id}
</select>

<select id="allComment" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from comment
</select>

<select id="commentOfSongId" resultMap="BaseResultMap" parameterType="java.lang.Integer">
    select
    <include refid="Base_Column_List"/>
    from comment
    where song_id = #{songId}
</select>

<select id="commentOfSongListId" resultMap="BaseResultMap" parameterType="java.lang.Integer">
    select
    <include refid="Base_Column_List"/>
    from comment
    where song_list_id = #{songListId}
</select>

<resultMap id="BaseResultMap" type="com.rabbiter.music.pojo.Consumer" >
    <id column="id" jdbcType="INTEGER" property="id"/>
    <result column="username" jdbcType="VARCHAR" property="username"/>
    <result column="password" jdbcType="VARCHAR" property="password"/>
    <result column="sex" jdbcType="TINYINT" property="sex"/>
    <result column="phone_num" jdbcType="CHAR" property="phoneNum"/>
    <result column="email" jdbcType="CHAR" property="email"/>
    <result column="birth" jdbcType="TIMESTAMP" property="birth"/>
    <result column="introduction" jdbcType="VARCHAR" property="introduction"/>
    <result column="location" jdbcType="VARCHAR" property="location"/>
    <result column="avator" jdbcType="VARCHAR" property="avator"/>
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
</resultMap>

<sql id="Base_Column_List">
    id,username,password,sex,phone_num,email,birth,introduction,location,avator,create_time,update_time
</sql>

<insert id="insert" parameterType="com.rabbiter.music.pojo.Consumer">
    insert into consumer
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null">
            id,
        </if>
        <if test="username != null">
            username,
        </if>
        <if test="password != null">
            password,
        </if>
        <if test="sex != null">
            sex,
        </if>
        <if test="phoneNum != null">
            phone_num,
        </if>
        <if test="email != null">
            email,
        </if>
        <if test="birth != null">
            birth,
        </if>
        <if test="introduction != null">
            introduction,
        </if>
        <if test="location != null">
            location,
        </if>
        <if test="avator != null">
            avator,
        </if>
        create_time,update_time,
    </trim>
    <trim prefix=" values (" suffix=")" suffixOverrides=",">
        <if test="id != null">
            #{id},
        </if>
        <if test="username != null">
            #{username},
        </if>
        <if test="password != null">
            #{password},
        </if>
        <if test="sex != null">
            #{sex},
        </if>
        <if test="phoneNum != null">
            #{phoneNum},
        </if>
        <if test="email != null">
            #{email},
        </if>
        <if test="birth != null">
            #{birth},
        </if>
        <if test="introduction != null">
            #{introduction},
        </if>
        <if test="location != null">
            #{location},
        </if>
        <if test="avator != null">
            #{avator},
        </if>
        now(),now(),
    </trim>        
</insert>

<update id="update" parameterType="com.rabbiter.music.pojo.Consumer">
    update consumer
    <set>
        <if test="username != null">
            username = #{username},
        </if>
        <if test="password != null">
            password = #{password},
        </if>
        <if test="sex != null">
            sex = #{sex},
        </if>
        <if test="phoneNum != null">
            phone_num = #{phoneNum},
        </if>
        <if test="email != null">
            email = #{email},
        </if>
        <if test="birth != null">
            birth = #{birth},
        </if>
        <if test="introduction != null">
            introduction = #{introduction},
        </if>
        <if test="location != null">
            location = #{location},
        </if>
        <if test="avator != null">
            avator = #{avator},
        </if>
        update_time = now(),
    </set>
    where id = #{id}
</update>

<delete id="delete" parameterType="java.lang.Integer">
    delete from consumer
    where id=#{id}
</delete>

<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
    select
    <include refid="Base_Column_List"/>
    from consumer
    where id=#{id}
</select>

<select id="allConsumer" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from consumer
</select>

<select id="verifyPassword" resultType="java.lang.Integer" parameterType="java.util.HashMap">
    select count(*)
    from consumer
    where username = #{username} and password = #{password}
</select>

<select id="getByUsername" resultMap="BaseResultMap" parameterType="java.lang.String">
    select
    <include refid="Base_Column_List"/>
    from consumer
    where username = #{username}
</select>

<resultMap id="BaseResultMap" type="com.rabbiter.music.pojo.ListSong" >
    <id column="id" jdbcType="INTEGER" property="id"/>
    <result column="song_id" jdbcType="INTEGER" property="songId"/>
    <result column="song_list_id" jdbcType="INTEGER" property="songListId"/>
</resultMap>

<sql id="Base_Column_List">
    id,song_id,song_list_id
</sql>

<insert id="insert" parameterType="com.rabbiter.music.pojo.ListSong">
    insert into list_song
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null">
            id,
        </if>
        <if test="songId != null">
            song_id,
        </if>
        <if test="songListId != null">
            song_list_id,
        </if>
    </trim>
    <trim prefix=" values (" suffix=")" suffixOverrides=",">
        <if test="id != null">
            #{id},
        </if>
        <if test="songId != null">
            #{songId},
        </if>
        <if test="songListId != null">
            #{songListId},
        </if>
    </trim>        
</insert>

<update id="update" parameterType="com.rabbiter.music.pojo.ListSong">
    update list_song
    <set>
        <if test="songId != null">
            song_id = #{songId},
        </if>
        <if test="songListId != null">
            song_list_id = #{songListId},
        </if>
    </set>
    where id = #{id}
</update>

<delete id="delete" parameterType="java.lang.Integer">
    delete from list_song
    where id=#{id}
</delete>

<delete id="deleteBySongIdAndSongListId" parameterType="java.util.HashMap">
    delete from list_song
    where song_id=#{songId} and song_list_id=#{songListId}
</delete>

<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
    select
    <include refid="Base_Column_List"/>
    from list_song
    where id=#{id}
</select>

<select id="allListSong" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from list_song
</select>

<select id="listSongOfSongListId" resultMap="BaseResultMap" parameterType="java.lang.Integer">
    select
    <include refid="Base_Column_List"/>
    from list_song
    where song_list_id=#{songListId}
</select>

<resultMap id="BaseResultMap" type="com.rabbiter.music.pojo.Rank" >
    <id column="id" jdbcType="INTEGER" property="id"/>
    <result column="song_list_id" jdbcType="INTEGER" property="songListId"/>
    <result column="consumer_id" jdbcType="INTEGER" property="consumerId"/>
    <result column="score" jdbcType="INTEGER" property="score"/>
</resultMap>

<insert id="insert" parameterType="com.rabbiter.music.pojo.Rank">
    insert into `rank`
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null">
            id,
        </if>
        <if test="songListId != null">
            song_list_id,
        </if>
        <if test="consumerId != null">
            consumer_id,
        </if>
        <if test="score != null">
            score,
        </if>
    </trim>
    <trim prefix=" values (" suffix=")" suffixOverrides=",">
        <if test="id != null">
            #{id},
        </if>
        <if test="songListId != null">
            #{songListId},
        </if>
        <if test="consumerId != null">
            #{consumerId},
        </if>
        <if test="score != null">
            #{score},
        </if>
    </trim>        
</insert>

<select id="selectScoreSum" resultType="java.lang.Integer" parameterType="java.lang.Integer">
    select COALESCE(sum(score),0) as score
    from `rank`
    where song_list_id = #{songListId}
</select>

<select id="selectRankNum" resultType="java.lang.Integer" parameterType="java.lang.Integer">
    select COALESCE(count(id),0) as num
    from `rank`
    where song_list_id = #{songListId}
</select>

<resultMap id="BaseResultMap" type="com.rabbiter.music.pojo.Singer" >
    <id column="id" jdbcType="INTEGER" property="id"/>
    <result column="name" jdbcType="VARCHAR" property="name"/>
    <result column="sex" jdbcType="TINYINT" property="sex"/>
    <result column="pic" jdbcType="VARCHAR" property="pic"/>
    <result column="birth" jdbcType="TIMESTAMP" property="birth"/>
    <result column="location" jdbcType="VARCHAR" property="location"/>
    <result column="introduction" jdbcType="VARCHAR" property="introduction"/>
</resultMap>

<sql id="Base_Column_List">
    id,name,sex,pic,birth,location,introduction
</sql>

<insert id="insert" parameterType="com.rabbiter.music.pojo.Singer">
    insert into singer
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null">
            id,
        </if>
        <if test="name != null">
            name,
        </if>
        <if test="sex != null">
            sex,
        </if>
        <if test="pic != null">
            pic,
        </if>
        <if test="birth != null">
            birth,
        </if>
        <if test="location != null">
            location,
        </if>
        <if test="introduction != null">
            introduction,
        </if>
    </trim>
    <trim prefix=" values (" suffix=")" suffixOverrides=",">
        <if test="id != null">
            #{id},
        </if>
        <if test="name != null">
            #{name},
        </if>
        <if test="sex != null">
            #{sex},
        </if>
        <if test="pic != null">
            #{pic},
        </if>
        <if test="birth != null">
            #{birth},
        </if>
        <if test="location != null">
            #{location},
        </if>
        <if test="introduction != null">
            #{introduction},
        </if>
    </trim>        
</insert>

<update id="update" parameterType="com.rabbiter.music.pojo.Singer">
    update singer
    <set>
        <if test="name != null">
            name = #{name},
        </if>
        <if test="sex != null">
            sex = #{sex},
        </if>
        <if test="pic != null">
            pic = #{pic},
        </if>
        <if test="birth != null">
            birth = #{birth},
        </if>
        <if test="location != null">
            location = #{location},
        </if>
        <if test="introduction != null">
            introduction = #{introduction},
        </if>
    </set>
    where id = #{id}
</update>

<delete id="delete" parameterType="java.lang.Integer">
    delete from singer
    where id=#{id}
</delete>

<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
    select
    <include refid="Base_Column_List"/>
    from singer
    where id=#{id}
</select>

<select id="allSinger" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from singer
</select>

<select id="singerOfName" resultMap="BaseResultMap" parameterType="java.lang.String">
    select
    <include refid="Base_Column_List"/>
    from singer
    where name like #{name}
</select>

<select id="singerOfSex" resultMap="BaseResultMap" parameterType="java.lang.Integer">
    select
    <include refid="Base_Column_List"/>
    from singer
    where sex = #{sex}
</select>

<resultMap id="BaseResultMap" type="com.rabbiter.music.pojo.SongList" >
    <id column="id" jdbcType="INTEGER" property="id"/>
    <result column="title" jdbcType="VARCHAR" property="title"/>
    <result column="pic" jdbcType="VARCHAR" property="pic"/>
    <result column="style" jdbcType="VARCHAR" property="style"/>
</resultMap>

<resultMap id="ResultMapWithBLOBs" type="com.rabbiter.music.pojo.SongList" extends="BaseResultMap">
    <result column="introduction" jdbcType="LONGVARCHAR" property="introduction"/>
</resultMap>

<sql id="Base_Column_List">
    id,title,pic,style
</sql>

<sql id="Blob_Column_List">
    id,title,pic,style,introduction
</sql>

<insert id="insert" parameterType="com.rabbiter.music.pojo.SongList">
    insert into song_list
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null">
            id,
        </if>
        <if test="title != null">
            title,
        </if>
        <if test="pic != null">
            pic,
        </if>
        <if test="introduction != null">
            introduction,
        </if>
        <if test="style != null">
            style,
        </if>
    </trim>
    <trim prefix=" values (" suffix=")" suffixOverrides=",">
        <if test="id != null">
            #{id},
        </if>
        <if test="title != null">
            #{title},
        </if>
        <if test="pic != null">
            #{pic},
        </if>
        <if test="introduction != null">
            #{introduction},
        </if>
        <if test="style != null">
            #{style},
        </if>
    </trim>        
</insert>

<update id="update" parameterType="com.rabbiter.music.pojo.SongList">
    update song_list
    <set>
        <if test="title != null">
            title = #{title},
        </if>
        <if test="pic != null">
            pic = #{pic},
        </if>
        <if test="introduction != null">
            introduction = #{introduction},
        </if>
        <if test="style != null">
            style = #{style},
        </if>
    </set>
    where id = #{id}
</update>

<delete id="delete" parameterType="java.lang.Integer">
    delete from song_list
    where id=#{id}
</delete>

<select id="selectByPrimaryKey" resultMap="ResultMapWithBLOBs" parameterType="java.lang.Integer">
    select
    <include refid="Blob_Column_List"/>
    from song_list
    where id=#{id}
</select>

<select id="allSongList" resultMap="ResultMapWithBLOBs">
    select
    <include refid="Blob_Column_List"/>
    from song_list
</select>

<select id="songListOfTitle" resultMap="ResultMapWithBLOBs" parameterType="java.lang.String">
    select
    <include refid="Blob_Column_List"/>
    from song_list
    where title = #{title}
</select>

<select id="likeTitle" resultMap="ResultMapWithBLOBs" parameterType="java.lang.String">
    select
    <include refid="Blob_Column_List"/>
    from song_list
    where title like #{title}
</select>

<select id="likeStyle" resultMap="ResultMapWithBLOBs" parameterType="java.lang.String">
    select
    <include refid="Blob_Column_List"/>
    from song_list
    where style like #{style}
</select>

<resultMap id="BaseResultMap" type="com.rabbiter.music.pojo.Song" >
    <id column="id" jdbcType="INTEGER" property="id"/>
    <result column="singer_id" jdbcType="VARCHAR" property="singerId"/>
    <result column="name" jdbcType="VARCHAR" property="name"/>
    <result column="introduction" jdbcType="VARCHAR" property="introduction"/>
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
    <result column="pic" jdbcType="VARCHAR" property="pic"/>
    <result column="url" jdbcType="VARCHAR" property="url"/>
</resultMap>

<resultMap id="ResultMapWithBLOBs" type="com.rabbiter.music.pojo.Song" extends="BaseResultMap">
    <result column="lyric" jdbcType="LONGVARCHAR" property="lyric"/>
</resultMap>

<sql id="Base_Column_List">
    id,singer_id,name,introduction,create_time,update_time,pic,url
</sql>

<sql id="Blob_Column_List">
    id,singer_id,name,introduction,create_time,update_time,pic,lyric,url
</sql>

<insert id="insert" parameterType="com.rabbiter.music.pojo.Song">
    insert into song
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="id != null">
            id,
        </if>
        <if test="singerId != null">
            singer_id,
        </if>
        <if test="name != null">
            name,
        </if>
        <if test="introduction != null">
            introduction,
        </if>
        create_time,update_time,
        <if test="pic != null">
            pic,
        </if>
        <if test="lyric != null">
            lyric,
        </if>
        <if test="url != null">
            url,
        </if>
    </trim>
    <trim prefix=" values (" suffix=")" suffixOverrides=",">
        <if test="id != null">
            #{id},
        </if>
        <if test="singerId != null">
            #{singerId},
        </if>
        <if test="name != null">
            #{name},
        </if>
        <if test="introduction != null">
            #{introduction},
        </if>
        now(),now(),
        <if test="pic != null">
            #{pic},
        </if>
        <if test="lyric != null">
            #{lyric},
        </if>
        <if test="url != null">
            #{url},
        </if>
    </trim>        
</insert>

<update id="update" parameterType="com.rabbiter.music.pojo.Song">
    update song
    <set>
        <if test="singerId != null">
            singer_id = #{singerId},
        </if>
        <if test="name != null">
            name = #{name},
        </if>
        <if test="introduction != null">
            introduction = #{introduction},
        </if>
        update_time = now(),
        <if test="pic != null">
            pic = #{pic},
        </if>
        <if test="lyric != null">
            lyric = #{lyric},
        </if>
        <if test="url != null">
            url = #{url},
        </if>
    </set>
    where id = #{id}
</update>

<delete id="delete" parameterType="java.lang.Integer">
    delete from song
    where id=#{id}
</delete>

<select id="selectByPrimaryKey" resultMap="ResultMapWithBLOBs" parameterType="java.lang.Integer">
    select
    <include refid="Blob_Column_List"/>
    from song
    where id=#{id}
</select>

<select id="allSong" resultMap="ResultMapWithBLOBs">
    select
    <include refid="Blob_Column_List"/>
    from song
</select>

<select id="songOfName" resultMap="ResultMapWithBLOBs" parameterType="java.lang.String">
    select
    <include refid="Blob_Column_List"/>
    from song
    where name = #{name}
</select>

<select id="likeSongOfName" resultMap="ResultMapWithBLOBs" parameterType="java.lang.String">
    select
    <include refid="Blob_Column_List"/>
    from song
    where name like #{name}
</select>

<select id="songOfSingerId" resultMap="ResultMapWithBLOBs" parameterType="java.lang.Integer">
    select
    <include refid="Blob_Column_List"/>
    from song
    where singer_id = #{singerId}
</select>

6 界面展示与测试

6.1 前端界面展示

前端首页界面结构框图如图6.1-1所示:

前端注册界面结构框图如图6.1-2所示:

图6.1-2 前端注册界面结构框图

前端登录界面结构框图如图6.1-3所示:

图6.1-3 前端登录界面结构框图

前端歌单界面结构框图如图6.1-4所示:

图6.1-4 前端歌单界面结构框图

前端华语伤感女声歌单界面结构框图如图6.1-5所示:

图6.1-5 前端华语伤感女声歌单界面结构框图

前端歌手界面结构框图如图6.1-6所示:

图6.1-6前端歌手界面结构框图

前端歌手介绍界面结构框图如图6.1-7所示:

图6.1-7 前端歌手介绍界面结构框图

前端我的音乐(需要注册登录)界面结构框图如图6.1-8所示:

图6.1-8前端我的音乐界面结构框图

前端设置界面结构框图如图6.1-9所示:

图6.1-9 前端设置界面结构框图

6.2 后端界面展示

后端登录界面结构框图如图6.2-1所示:

图6.2-1 后端登录界面结构框图

后端系统首页结构框图如图6.2-2所示:

图6.2-2 后端系统首页结构框图

后端用户管理界面结构框图如图6.2-3所示:

图6.2-3 后端用户管理界面结构框图

后端歌手管理界面结构框图如图6.2-4所示:

图6.2-4 后端歌手管理界面结构框图

后端歌单管理界面结构框图如图6.2-5所示:

图6.2-5后端歌单管理界面结构框图

6.3 数据库界面展示

数据库构成界面结构框图如图6.3-1所示:

图6.3-1 数据库构成界面结构框图

数据库管理员表结构框图如图6.3-2所示:

图6.3-2 数据库管理员表结构框图

用户收藏喜爱的歌曲表结构框图如图6.3-3所示:

图6.3-3 用户收藏喜爱的歌曲表结构框图

用户评论表结构框图如图6.3-4所示:

图6.3-4 用户评论表结构框图

用户信息表结构框图如图6.3-5所示:

图6.3-5用户信息表结构框图

歌曲与歌单关联表结构框图如图6.3-6所示:

图6.3-6歌曲与歌单关联表结构框图

歌单评分表结构框图如图6.3-7所示:

图6.3-7歌单评分表结构框图

歌手信息表结构框图如图6.3-8所示:

图6.3-8歌手信息表结构框图

歌曲信息表结构框图如图6.3-9所示:

图6.3-9歌曲信息表结构框图

相关文章:

13.音乐管理系统(基于SpringBoot + Vue)

目录 1.系统的受众说明 ​​​​​​​ 2 需求分析 2.1用例图及用例分析 2.1.1 用户用例图及用例分析 2.1.2 管理员用例图及用例分析 2.2 系统结构图和流程图 2.2.1 音乐播放器的系统流程图&#xff08;图2.2.1-1&#xff09; 2.2.2 系统功能表&#xff08;表2.2.2…...

如何从iconfont中获取字体图标并应用到微信小程序中去?

下面我们一一个微信小程序的登录界面的制作为例来说明&#xff0c;如何从iconfont中获取字体图标是如何应用到微信小程序中去的。首先我们看效果。 这里所有的图标&#xff0c;都是从iconfont中以字体的形式来加载的&#xff0c;也就是说&#xff0c;我们自始至终没有使用一张…...

C语言中的位操作

第一章 变量某位赋值与连续赋值 寄存器 | 值 //例如&#xff1a;a 1000 0011b a | (1<<2) //a 1000 0111 b 单独赋值 a | (3<<2*2) // 1011 0011b 连续赋值 第二章 变量某位清零与连续清零 寄存器 & ~&#xff08;&#xff09; 值 //例子&#xff1a;a …...

Spring之HTTP客户端--RestTemplate的使用

原文网址&#xff1a;Spring之HTTP客户端--RestTemplate的使用_IT利刃出鞘的博客-CSDN博客 简介 本文介绍RestTemplate的用法。RestTemplate是Spring自带的HTTP客户端&#xff0c;推荐使用。 项目中经常需要使用http调用第三方的服务&#xff0c;常用的客户端如下&#xff1…...

vscode和pycharm在当前工作目录的不同|python获取当前文件目录和当前工作目录

问题背景 相信大家都遇到过一个问题&#xff1a;一个项目在vscode&#xff08;或pycharm&#xff09;明明可以正常运行&#xff0c;但当在pycharm&#xff08;或vscode&#xff09;中时&#xff0c;却经常会出现路径错误。起初&#xff0c;对于这个问题&#xff0c;我也是一知…...

速盾:海外高防CDN有哪些优势?

海外高防CDN&#xff08;Content Delivery Network&#xff09;是一种通过部署分布式节点服务器来加速网站内容分发的技术&#xff0c;它能够提供更快速、稳定、安全的网站访问体验。相比于传统的CDN服务&#xff0c;海外高防CDN具有以下几个优势&#xff1a; 全球分布&#xf…...

OpenCV视觉分析之目标跟踪(4)目标跟踪类TrackerDaSiamRPN的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::TrackerDaSiamRPN 是 OpenCV 中用于目标跟踪的一个类&#xff0c;它实现了 DaSiam RPN&#xff08;Deformable Siamese Region Proposal Net…...

自动对焦爬山算法原理

自动对焦爬山算法原理可以归纳为以下几个关键步骤&#xff1a; &#xff08;1&#xff09;初始化&#xff1a; 爬山算法从一个随机或预设的初始位置开始&#xff0c;这个位置代表了镜头的初始焦距。 &#xff08;2&#xff09;清晰度评价&#xff1a; 算法首先在当前焦距下捕…...

Hyperledger Fabric有那些核心技术,和其他区块链对比Hyperledger Fabric有那些优势

Hyperledger Fabric是一个模块化、权限化的企业级区块链平台&#xff0c;与比特币、以太坊等公有链相比&#xff0c;Fabric主要为私有链或联盟链设计&#xff0c;适用于企业应用。它包含多项核心技术&#xff0c;使其在企业级区块链应用中具有独特优势。以下是Fabric的核心技术…...

「Mac畅玩鸿蒙与硬件8」鸿蒙开发环境配置篇8 - 应用依赖与资源管理

本篇将介绍如何在 HarmonyOS 项目中高效管理资源文件和依赖&#xff0c;以确保代码结构清晰并提升应用性能。资源管理涉及图片、字符串、多语言文件等&#xff0c;通过优化文件加载和依赖管理&#xff0c;可以显著提升项目的加载速度和运行效率。 关键词 资源管理应用依赖优化…...

【Gorm】传统sql的增删查改,通过go去操作sql

MySQL中的建库&#xff0c;建表&#xff0c;删库&#xff0c;删表&#xff0c;添加记录&#xff0c;查询&#xff0c;删除记录&#xff0c;更新记录这些命令是一定要回的&#xff0c;就算我们脱离 orm 这些&#xff0c;也能直接连接上数据库进行操作。 一、数据库的操作 # 查…...

HTML小阶段二维表和思维导图

下面是对标签、元素、属性的对比二维表&#xff0c;通过对比3w1h&#xff08;what是什么、where用在哪、why为什么要用、how如何用&#xff09;来学习区分学习标签、元素、属性 标签 元素 属性 what &#xff08;Tags&#xff09;标签是用来标记内容块或标明元素内容意义 …...

AI与低代码的碰撞:企业数字化转型的新引擎

引言 在当今的商业环境中&#xff0c;企业数字化转型已从选择题变成了必答题。面对日益复杂的市场竞争和不断变化的客户需求&#xff0c;传统的开发模式常常显得力不从心——开发周期冗长、技术门槛高、成本居高不下&#xff0c;企业很难快速响应市场变化。而在这种背景下&…...

HarmonyOS应用开发者基础认证——初级闯关习题参考答案大全

相关文章 HarmonyOS应用开发者中级认证——中级闯关习题参考答案大全 HarmonyOS应用开发者高级认证——高级闯关习题参考答案大全 文章目录 HarmonyOS第一课 HarmonyOS介绍判断题单选题多选题 HarmonyOS第一课 DevEco Studio的使用判断题单选题多选题 HarmonyOS第一课 ArkTS语法…...

Vue背景图片自适应大屏与小屏

1&#xff0c;父绝子相 效果是台式看的更多&#xff0c;笔记本看部分。但是图片不会变形 <div class"father" style"width:100%; position:relative"> <img src"test.png" class"son" style"width:1920px; position:a…...

MongoDB 8.0.3版本安装教程

MongoDB 8.0.3版本安装教程 一、下载安装 1.进入官网 2.选择社区版 3.点击下载 4.下载完成后点击安装 5.同意协议&#xff0c;下一步 6.选择第二个Custon&#xff0c;自定义安装 7.选择安装路径 &#xff01;记住安装路径 8.默认&#xff0c;下一步 9.取…...

【C语言】预处理(预编译)详解(下)(C语言最终篇)

文章目录 一、#和##1.#运算符2.##运算符 二、预处理指令#undef三、条件编译1.单分支条件编译2.多分支条件编译3.判断符号是否被定义4.判断符号是否没有被定义 四、头文件的包含1.库头文件的包含2.本地头文件的包含3.嵌套包含头文件的解决方法使用条件编译指令使用预处理指令#pr…...

[Linux] linux 软硬链接与动静态库

标题&#xff1a;[Linux] linux 软硬链接与动静态库 个人主页水墨不写bug &#xff08;图片来源于网络&#xff09; /** _oo0oo_* o8888888o* 88" . "88* (| -_- |)* …...

GitHub Actions的 CI/CD

GitHub Actions 是一个强大的 CI/CD 工具&#xff0c;适用于自动化各种开发任务。GitHub Actions 的原理是基于事件驱动的自动化流水线工具&#xff0c;通过定义触发条件和执行步骤&#xff0c;可以让项目在特定条件下自动运行一系列操作&#xff0c;比如构建、测试、部署等。 …...

doris 表结构批量导出

导出 test 数据库中的 table1 表&#xff1a;mysqldump -h127.0.0.1 -P9030 -uroot --no-tablespaces --databases test --tables table1 导出 test 数据库中的 table1 表结构&#xff1a;mysqldump -h127.0.0.1 -P9030 -uroot --no-tablespaces --databases test --tables tab…...

linux查看文件命令

查看文件命令 显示命令 cat 语法&#xff1a;cat 【选项】 文件 选项 命令含义n显示行号包括空行b显示行号不包括空行s压缩空行为一行A显示隐藏字符 cat -n 文件&#xff1a;显示行号包括空行 cat -b 文件 cat -s 文件 cat -A 文件 more和less是 分页查看 tac和rev都…...

【2023工业图像异常检测文献】DiAD: 基于扩散模型的多类异常检测方法

DiAD: A Diffusion-based Framework for Multi-class Anomaly Detection 1、Background 当前主流的三种异常检测方法&#xff1a; 基于合成的方法&#xff1a;在正常图像上合成异常&#xff0c;通过训练模型识别这些合成的异常来提高检测和定位能力。基于嵌入的方法&#xff…...

三相继电保护机 继电器保护校验仪 微机继电保护测试仪

性能特点 电压电流输出灵活组合 输出达4相电压3相电流&#xff0c;可各种组合实现常规4相电压3相电流型输出模式&#xff0c;既可兼容传统的各种试验方式&#xff0c;也可方便地进行三相变压器差动试验和厂用电快切和备自投试验。 操作方式装置直接外接笔记本电脑或台式机进行…...

MyEclipse中讲解Git使用——结合GitLab

1、什么是Git Git是分布式版本控制系统 Git是一款免费、开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 2、在myeclipse安装Git插件 下载该文件&#xff0c;将egit.zip解压放入 myeclipse安装路径>dropins>下重新启动myeclipse EGit -…...

pdf转为txt文本格式并使用base64加密输出数据

第一步&#xff0c;pom.xml中引入jar包 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.24</version></dependency> 第二步 package org.example.test.example.changefile;…...

SpringBoot篇(运维实用篇 - 临时属性)

目录 一、临时属性设置 1. 简介 2. 属性加载优先级 那是否还有其他的配置方式呢&#xff1f; 3. 知识小结 二、开发环境中使用临时属性 1. 如何操作 2. 知识小结 3. 思考 三、配置文件分类 1. 简介 2. 4个级别 3. 为什么设计多种配置文件&#xff1f; 一个典型的应…...

MySQL定时异机备份

场景&#xff1a;将A机器MySQL数据库部分表每日定时备份到B机器上 &#xff08;只适用于Linux&#xff09; 实现方式算是比简单了&#xff0c;就是用mysqldump生成文件&#xff0c;使用scp命令传输到另一台机器上。 1. 编写备份shell脚本 在A机器新建脚本 (当然没有vim的话vi…...

MMA: Multi-Modal Adapter for Vision-Language Models

两个观察 图1所示。各种基于transformer的CLIP模型中不同层的数据集级识别精度。这个实验是为了确定样本属于哪个数据集。我们用不同的种子运行了三次&#xff0c;并报告了每层识别精度的平均值和标准差。 X E m b e d XEmbed XEmbed是指变压器块之前的文本或图像嵌入层&#x…...

uniapp通过id获取div的宽度,高度,位置等(应该是 任意平台都通用 )

uniapp通过id获取div的宽度&#xff0c;高度&#xff0c;位置等&#xff08;应该是 任意平台都通用 &#xff09; <template><view class"" id"domId"></view> </template>// 如果获取的dome高度等不对&#xff0c;还需要加上延迟…...

Python Transformer 模型的基本原理:BERT 和 GPT 以及它们在情感分析中的应用

Transformer 模型的基本原理&#xff1a;BERT 和 GPT 以及它们在情感分析中的应用 近年来&#xff0c;Transformer 模型在自然语言处理&#xff08;NLP&#xff09;领域取得了巨大成功&#xff0c;为任务如翻译、生成文本、问答和情感分析带来了显著的性能提升。本文将介绍 Tr…...

wordpress頂部公告插件/seo发外链工具

当我们的项目中有peerDependencies时&#xff0c;执行npm install会发现peerDependencies的依赖项并不会下载&#xff0c;如果一个个下载太过麻烦&#xff0c;因此推荐一个npm库npm-install-peers&#xff0c;可以直接下载。 npm install --save-dev npm-install-peersnpm scr…...

公众号开发网站建设合同/百度刷排名seo软件

Vue引入bootstrap主要有两种方法 方法一&#xff1a;在main.js中引入&#xff0c;此方法导入的bootstrap中对于html&#xff0c;body的一些预设置的css样式可能无效。 一、引入jQuery 在当前项目的目录下&#xff08;就是package.json&#xff09;&#xff0c;运行命令 cnpm in…...

上海企业网站建设/百度网页pc版登录

地球系统科学读书会 双线性神经网络方法&#xff1a;双线性神经网络方法&#xff1a;双线性神经网络方法&#xff1a; 示例&#xff1a;图中下边公式为图中上边网络的描述示例&#xff1a;图中下边公式为图中上边网络的描述示例&#xff1a;图中下边公式为图中上边网络的描述 …...

北京大兴最专业的网站建设公司/广州网站营销优化qq

所有浏览器都支持该对象。Navigator 对象包含有关浏览器的信息。 Navigator 对象包含的属性描述了正在使用的浏览器。可以使用这些属性进行平台专用的配置。 <script type"text/JavaScript"> $(function(){ var browser{},matchReg; …...

化工企业网站jsp/模板建站代理

** JS遍历对 象的总结 ** 1、使用Object.keys()遍历 返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性). var obj {‘0’:‘a’,‘1’:‘b’,‘2’:‘c’}; Object.keys(obj).forEach(function(key){ console.log(key,’:’,obj[key]); }); 输出结果…...

做打鱼网站犯法不/刚刚济南发通知

一、final关键字的基本用法 1、修饰类 当用final修饰一个类时&#xff0c;表明这个类不能被继承。注意&#xff1a; final类中的成员变量可以根据需要设为final&#xff0c; final类中的所有成员方法都会被隐式地指定为final方法。 2、修饰方法 下面这段话摘自《Java编程思想》…...