Springboot+Vue音乐播放网站系统设计与实现

前言

博主介绍:优快云特邀作者、985高校计算机专业毕业、现任某互联网大厂高级全栈开发工程师、Gitee/掘金/华为云/阿里云/GitHub等平台持续输出高质量技术内容、深耕Java、小程序、前端、python等技术领域和毕业项目实战,以及程序定制化开发、全栈讲解。

💯文末获取源码+数据库💯
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以找我咨询,希望帮助更多的人。

详细视频演示

演示教程

具体实现截图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

后端框架SpringBoot

Spring Boot允许开发者快速构建出既可以独立运行又满足生产级别标准的Spring基础应用程序。此框架通过提供一系列便捷的工具和服务,极大地促进了基于Spring的应用开发工作的效率和质量。通过提供一系列大型项目中常用的默认配置,Spring Boot最大化减少配置文件的使用,开发者能够迅速启动和运行Spring应用程序。

Spring Boot通过约定优于配置的原则,避免了许多传统Spring应用开发时繁琐的配置,该框架支持对内嵌服务器的自动配置,如Tomcat、Jetty或Undertow,从而简化了Web应用的部署过程。

前端框架Vue

Vue.js是一种流行的JavaScript框架,它具有许多优势。其中,Vue.js的核心优势之一是虚拟DOM技术。虚拟DOM是一个内存中的数据结构,它在实现高效的DOM操作方面发挥了重要作用。

Vue.js采用了响应式数据绑定、虚拟DOM、组件化等现代化技术,为开发者提供了一种灵活、高效、易于维护的开发模式。当数据发生变化时,Vue.js能够自动更新UI,开发者无需手动更新UI,从而能够更加专注于数据处理。

持久层框架MyBaits

MyBatis是一个开源的持久层框架,它可以帮助开发者简化数据库操作的编写和管理。MyBatis的核心思想是将SQL语句和Java代码分离,通过XML或注解的方式来描述数据库操作,从而实现了数据访问层的解耦和灵活性。

MyBatis的优势主要包括以下几点:

简化数据库操作:MyBatis通过提供强大的SQL映射功能,可以将Java对象与数据库表进行映射,开发者无需手动编写繁琐的SQL语句,大大简化了数据库操作的编写和维护。

灵活的SQL控制:MyBatis支持动态SQL,可以根据不同的条件和逻辑来动态生成SQL语句,使得查询、更新等操作更加灵活和可控。

缓存支持:MyBatis提供了一级缓存和二级缓存的支持,可以有效减少数据库的访问次数,提高系统性能。

可扩展性强:MyBatis采用插件机制,可以方便地扩展和定制自己的功能,满足各种不同的业务需求。

所有项目均为博主亲自收集、开发并严格测试,确保源码完整、可运行,无缺失依赖或兼容性问题!同学们拿到后就能使用!博主具备多年高级开发经验,能深入讲解代码架构、核心逻辑及技术难点,助你高效掌握项目精髓。

成功系统案例:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考代码

package com.shanzhu.music.controller;

import cn.hutool.core.util.BooleanUtil;
import com.shanzhu.music.common.R;
import com.shanzhu.music.entity.po.SongList;
import com.shanzhu.music.entity.vo.UploadPicVo;
import com.shanzhu.music.service.RecommendSongListService;
import com.shanzhu.music.service.SongListService;
import com.shanzhu.music.utils.PathUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * 歌单 控制层
 *
 * @author: CodeUp
 * @date: 2025-07-01
 */
@RestController
@RequestMapping("/songList")
@RequiredArgsConstructor
public class SongListController {

    @Value("${useRecommend}")
    private Boolean userRecommend;

    private final SongListService songListService;

    private final RecommendSongListService recommendSongListService;

    /**
     * 添加歌单
     *
     * @param title        标题
     * @param pic          歌单图片
     * @param introduction 简介
     * @param style        风格
     * @return 添加结果
     */
    @PostMapping(value = "/add")
    public R addSongList(
            String title,
            String pic,
            String introduction,
            String style
    ) {
        //保存到歌单的对象中
        SongList songList = new SongList();
        songList.setTitle(title);
        songList.setPic(pic);
        songList.setIntroduction(introduction);
        songList.setStyle(style);

        //添加成功
        if (songListService.insert(songList)) {
            return R.ok("添加成功");
        }

        return R.error("添加失败");
    }

    /**
     * 修改歌单
     *
     * @param id           主键
     * @param title        标题
     * @param introduction 简介
     * @param style        风格
     * @return 修改结果
     */
    @PostMapping(value = "/update")
    public R updateSongList(
            String id,
            String title,
            String introduction,
            String style
    ) {
        //保存到歌单的对象中
        SongList songList = new SongList();
        songList.setId(Integer.parseInt(id));
        songList.setTitle(title);
        songList.setIntroduction(introduction);
        songList.setStyle(style);

        //修改成功
        if (songListService.update(songList)) {
            return R.ok("修改成功");
        }
        return R.error("修改失败");
    }

    /**
     * 删除歌单
     *
     * @param id 歌单id
     * @return 删除结果
     */
    @GetMapping(value = "/delete")
    public Boolean deleteSongList(Integer id) {
        return songListService.delete(id);
    }

    /**
     * 查询歌单
     *
     * @param id 歌单id
     * @return 歌单
     */
    @GetMapping(value = "/selectByPrimaryKey")
    public SongList selectByPrimaryKey(Integer id) {
        return songListService.selectByPrimaryKey(id);
    }

    /**
     * 查询所有歌单
     *
     * @param userId 用户id
     * @return 歌单列表
     */
    @GetMapping(value = "/allSongList")
    public List<SongList> allSongList(@RequestParam(value = "userId", required = false) String userId) {
        if (userId == null || "0".equals(userId) || "null".equals(userId) || BooleanUtil.isFalse(userRecommend)) {
            return songListService.allSongList();
        } else {
            //通过用户收藏来推荐
            return recommendSongListService.recommendSongListByCollect(Integer.valueOf(userId));
        }
    }

    /**
     * 根据标题精确查询歌单列表
     *
     * @param title 标题
     * @return 歌单列表
     */
    @GetMapping(value = "/songListOfTitle")
    public List<SongList> songListOfName(String title) {
        return songListService.songListOfTitle(title);
    }

    /**
     * 根据标题模糊查询歌单列表
     *
     * @param title 标题
     * @return 歌单列表
     */
    @GetMapping(value = "/likeTitle")
    public List<SongList> likeTitle(String title) {
        return songListService.likeTitle("%" + title + "%");
    }

    /**
     * 根据风格模糊查询歌单列表
     *
     * @param style 歌单风格
     * @return 歌单列表
     */
    @RequestMapping(value = "/likeStyle", method = RequestMethod.GET)
    public Object likeStyle(String style) {
        return songListService.likeStyle("%" + style + "%");
    }

    /**
     * 更新歌单图片
     *
     * @param avatorFile 头像文件
     * @param id         歌单id
     * @return 更新结果
     */
    @PostMapping(value = "/updateSongListPic")
    public R<UploadPicVo> updateSongListPic(
            @RequestParam("file") MultipartFile avatorFile,
            @RequestParam("id") Integer id
    ) throws IOException {
        if (avatorFile.isEmpty()) {
            return R.error("文件上传失败");
        }

        //文件名=当前时间到毫秒+原来的文件名
        String fileName = System.currentTimeMillis() + avatorFile.getOriginalFilename();
        //文件路径
        String filePath = PathUtils.getClassLoadRootPath() + "/img/songListPic/";
        //如果文件路径不存在,新增该路径
        File file1 = new File(filePath);
        if (!file1.exists()) {
            file1.mkdir();
        }
        //实际的文件地址
        File dest = new File(filePath + fileName);
        //存储到数据库里的相对文件地址
        String storeAvatorPath = "/img/songListPic/" + fileName;

        avatorFile.transferTo(dest);
        SongList songList = new SongList();
        songList.setId(id);
        songList.setPic(storeAvatorPath);

        //更新歌单
        if (songListService.update(songList)) {
            UploadPicVo uploadPicVo = new UploadPicVo();
            uploadPicVo.setPic(storeAvatorPath);
            return R.ok("上传成功", uploadPicVo);
        }

        return R.error("上传失败");
    }

}

数据库

-- ----------------------------
-- Table structure for collect
-- ----------------------------
DROP TABLE IF EXISTS `collect`;
CREATE TABLE `collect` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `user_id` int DEFAULT NULL COMMENT '用户id',
  `type` tinyint(1) DEFAULT NULL COMMENT '收藏类型(0歌曲1歌单)',
  `song_id` int DEFAULT NULL COMMENT '歌曲id',
  `song_list_id` int DEFAULT NULL COMMENT '歌单id',
  `create_time` datetime DEFAULT NULL COMMENT '收藏时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=80 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC COMMENT='收藏';

-- ----------------------------
-- Records of collect
-- ----------------------------
BEGIN;
INSERT INTO `collect` (`id`, `user_id`, `type`, `song_id`, `song_list_id`, `create_time`) VALUES (70, 35, 0, 27, NULL, '2024-07-25 10:38:07');
INSERT INTO `collect` (`id`, `user_id`, `type`, `song_id`, `song_list_id`, `create_time`) VALUES (79, 36, 0, 116, NULL, '2024-07-25 10:58:37');
COMMIT;

-- ----------------------------
-- Table structure for comment
-- ----------------------------
DROP TABLE IF EXISTS `comment`;
CREATE TABLE `comment` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `user_id` int DEFAULT NULL COMMENT '用户id',
  `type` tinyint(1) DEFAULT NULL COMMENT '评论类型(0歌曲1歌单)',
  `song_id` int DEFAULT NULL COMMENT '歌曲id',
  `song_list_id` int DEFAULT NULL COMMENT '歌单id',
  `content` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8_general_ci DEFAULT NULL COMMENT '评论内容',
  `create_time` datetime DEFAULT NULL COMMENT '收藏时间',
  `up` int DEFAULT '0' COMMENT '评论点赞数',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC COMMENT='评论';

-- ----------------------------
-- Records of comment
-- ----------------------------
BEGIN;
INSERT INTO `comment` (`id`, `user_id`, `type`, `song_id`, `song_list_id`, `content`, `create_time`, `up`) VALUES (63, 33, 1, NULL, 87, '很好听的歌曲', '2023-11-26 10:36:51', 0);
INSERT INTO `comment` (`id`, `user_id`, `type`, `song_id`, `song_list_id`, `content`, `create_time`, `up`) VALUES (64, 33, 1, NULL, 91, '11', '2023-11-26 15:32:36', 0);
INSERT INTO `comment` (`id`, `user_id`, `type`, `song_id`, `song_list_id`, `content`, `create_time`, `up`) VALUES (65, 35, 1, NULL, 86, '非常不错', '2023-11-28 21:34:41', 0);

源码获取

如需交流/获取资料,请先【关注+私信】我,评论源码,发送源码获取方式~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值