本地音乐服务器(三)

 6. 删除音乐模块设计

6.1 删除单个音乐

1. 请求响应设计

2. 开始实现

首先在musicmapper新增操作

 Music findMusicById(int id);
    
    int deleteMusicById(int musicId);

其次新增相对应的.xml代码:

 <select id="findMusicById" resultType="com.example.spring_musicserver_1113.model.Music">
        select * from music where id = #{id};
    </select>

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

最后musiccontroller代码:

 /**
     * 删除单个音乐
     * @param id
     * @return
     */
    @RequestMapping("/delete")
    public ResponseBodyMessage<Boolean> deleteMusicById(@RequestParam String id){
        //1、检查当前ID的音乐是否存在
        int iid = Integer.parseInt(id);
        //2、如果当前ID音乐存在的话就要删除
        Music music = musicMapper.findMusicById(iid);
        if(music == null){
            System.out.println("没有查询到当前id的音乐");
            return new ResponseBodyMessage<>(-1,"没有查询到当前id的音乐",false);
        }else {
            //2.1 删除数据路
            int ret = musicMapper.deleteMusicById(iid);
            if(ret == 1){
                //2.2 删除服务器上的数据
                int index = music.getUrl().lastIndexOf("=");
                String fileName = music.getUrl().substring(index+1);
                File file = new File(SAVE_PATH+"/"+fileName+".mp3");
                System.out.println("当前的路径"+file.getPath());
                if (file.delete()){
                    return new ResponseBodyMessage<>(0,"服务器中的音乐删除成功",true);
                }else {
                   return   new ResponseBodyMessage<>(-1,"服务器中的音乐删除失败",false);
                }

            }else {
                return new ResponseBodyMessage<>(-1,"数据库当中的音乐没有删除成功",false);
            }
        }
    }

进行测试:

发现数据库和服务器路径下的mp3文件都被删除了;

6.2 批量删除选中的音乐

 1、请求响应设计

2、代码实现

新增deleteSelMusic方法:

        其逻辑和之前单个删除的类似,在之前代码的基础上使用一个for循环,来查询每一个音乐文件是否存在并进行删除和统计,当统计的数量值是需要删除的数量值的时候就是批量删除成功;

@RequestMapping("/deleteSel")
    public ResponseBodyMessage<Boolean> deleteSelMusic(@RequestParam("id[]")
                                                       List<Integer> id){
        System.out.println("所有的id"+ id);
        int sum = 0;
        for (int i = 0; i < id.size(); i++) {
            Music music = musicMapper.findMusicById(id.get(i));
            if(music == null){
                System.out.println("没有查询到当前id的音乐");
                return new ResponseBodyMessage<>(-1,"没有查询到当前id的音乐",false);
            }
            int ret = musicMapper.deleteMusicById(id.get(i));
            if(ret == 1) {
                int index = music.getUrl().lastIndexOf("=");
                String fileName = music.getUrl().substring(index + 1);
                File file = new File(SAVE_PATH + "/" + fileName + ".mp3");
                if (file.delete()) {
                    sum += ret;
                } else {
                    return new ResponseBodyMessage<>(-1, "服务器中的音乐删除失败", false);
                }
            }else {
                return new ResponseBodyMessage<>(-1,"数据库当中的音乐没有删除成功",false);
            }
        }
        if(sum == id.size()){
            System.out.println("批量删除成功");
            return new ResponseBodyMessage<>(0,"音乐批量删除成功",true);
        }else {
            System.out.println("批量删除失败");
            return   new ResponseBodyMessage<>(-1,"音乐批量删除失败",false);
        }
    }

进行测试:

7. 查询⾳乐模块设计

        1、请求响应模块设计

         此处查询需要满⾜⼏个功能:

1. ⽀持模糊查询

2. ⽀持传⼊参数为空

        当我们传递的参数为空的时候,查询的结果就是当前表里面的所所有music数据;

2、代码实现

数据层代码如下:

musicmapper新增接口:

 List<Music> findMusic();


 List<Music> findMusicByName(String musicName);

.xml配置如下:

  <select id="findMusic" resultType="com.example.spring_musicserver_1113.model.Music">
        select * from music;
    </select>

    <select id="findMusicByName" resultType="com.example.spring_musicserver_1113.model.Music">
        select * from music where title like concat('%',#{musicName},'%');
    </select>

控制层代码如下:

@RequestMapping("/findmusic")
    public ResponseBodyMessage<List<Music>> findMusic(
            @RequestParam(required = false) String musicName){
        List<Music> musicList = null;
        if(musicName != null){
            musicList = musicMapper.findMusicByName(musicName);
        }else {
            musicList = musicMapper.findMusic();
        }
        return new ResponseBodyMessage<>(0,"查询到了当前的所有音乐",musicList);
    }

进行测试,模糊有参查找:

        空参查找测试:

8. 喜欢音乐模块设计

8.1 添加⾳乐⾄喜欢的列表模块设计

1、响应和请求

        2、代码实现

数据层:

        实现LoveMusicMapper接⼝,收藏/喜欢⾳乐功能:

        1、需要查询此次收藏⾳乐是否之前收藏过,收藏过则不能添加

         2、没有收藏过,插⼊数据库中⼀条记录

   Music findLoveMusicByMusicIdAndUserId(int userId,int musicId);

  
    boolean insertLoveMusic(int userId,int musicId);

进行xml文件配置:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.spring_musicserver_1113.mapper.LoveMusicMapper">
    <select id="findLoveMusicByMusicIdAndUserId" resultType="com.example.spring_musicserver_1113.model.Music">
        select * from lovemusic where user_id = #{userId} and music_id = #{musicId};
    </select>

    <insert id="insertLoveMusic">
        insert into lovemusic(user_id,music_id) values(#{userId},#{musicId});
    </insert>
</

控制层:实现LoveMusicController类 

@RestController
@RequestMapping("/lovemusic")
public class LoveMusicController {

    @Resource
    private LoveMusicMapper loveMusicMapper;
    @RequestMapping("/likeMusic")
    public ResponseBodyMessage<Boolean> likeMusic(@RequestParam String id,
                                        HttpServletRequest request){
        int musicId = Integer.parseInt(id);
        System.out.println("musicId:"+musicId);
        //1、检查当前是否等了
        HttpSession httpSession = request.getSession(false);
        if(httpSession == null || httpSession.getAttribute(Constant.USERINFO_SESSION_KEY) == null){
            System.out.println("没有登录!");
            return new ResponseBodyMessage<>(-1,"请登录后进行收藏喜欢",false);
        }
        User user = (User) httpSession.getAttribute(Constant.USERINFO_SESSION_KEY);
        int userId = user.getId();
        System.out.println("userId:"+userId);
        Music music = loveMusicMapper.findLoveMusicByMusicIdAndUserId(userId,musicId);
        if(music != null){//这里加一个取消收藏的功能
            return new  ResponseBodyMessage<>(-1,"该音乐已被喜欢收藏",false);
        }
        boolean effect = loveMusicMapper.insertLoveMusic(userId,musicId);
        if(effect){
            return new ResponseBodyMessage<>(0,"收藏成功",true);
        }else {
            return new ResponseBodyMessage<>(-1,"收藏失败",false);
        }
    }
}

测试结果如下:

 首先进行喜欢收藏测试,测试通过;当同一首歌进行第二次喜欢收藏时:

lovemusic表如下所示:

8.2 查询喜欢的⾳乐模块设计

1、请求和响应

上面是无参数请求,同时和有参数请求类似; 

2、代码实现

        数据层:实现LoveMusicMapper新增⽅法:

    List<Music> findLoveMusicByUserId(int userId);

    List<Music> findLoveMusicByKeyAndUID(String musicName,int userId);

         实现LoveMusicMapper.xml

    <select id="findLoveMusicByUserId" resultType="com.example.spring_musicserver_1113.model.Music">
        select m.* from lovemusic lm,music m where m.id = lm.music_id and lm.user_id = #{userId};
    </select>

    <select id="findLoveMusicByKeyAndUID" resultType="com.example.spring_musicserver_1113.model.Music">
        select m.* from lovemusic lm,music m where m.id = lm.music_id and lm.user_id = #{userId}
        and title like concat("%",#{musicName},"%");
    </select>

         控制层:实现LoveMusicController,新增⽅法

 @RequestMapping("findLoveMusic")
    public ResponseBodyMessage<List<Music>> findLoveMusic(@RequestParam(required = false) String musicName,
                                                    HttpServletRequest request){
        //1、验证当前是否登录
        HttpSession httpSession = request.getSession(false);
        if(httpSession == null || httpSession.getAttribute(Constant.USERINFO_SESSION_KEY) == null){
            System.out.println("没有登录!");
            return new ResponseBodyMessage<>(-1,"请登录后进行查找收藏喜欢的音乐",null);
        }
        User user = (User) httpSession.getAttribute(Constant.USERINFO_SESSION_KEY);
        int userId = user.getId();
        System.out.println("userId"+userId);
        List<Music>  musicList=null;
        if(musicName == null){
            musicList =loveMusicMapper.findLoveMusicByUserId(userId);
        }else {
            musicList = loveMusicMapper.findLoveMusicByKeyAndUID(musicName,userId);
        }
        return new ResponseBodyMessage<>(0,"查询到了所有的歌曲信息",musicList);
    }

 对于@RequestParam 注解:

        该注解@RequestParam 可以从请求中提取查询参数、表单参数甚至是多个参数,即获取下面请求中的查询字符串的值;

        变量名和参数名都是相同的(userId),如果变量名称和参数名称不同,可以使用 name 属性配置 @RequestParam 名称:

        @RequestParam(name = "name") String musicName:将请求中name的值提取出来赋给musicName:127.0.0.1:8089/lovemusic/findLoveMusic?name=w

        使用 @RequestParam 注解的方法参数默认为必填参数(默认是require== true),如果想要进行下面请求中带有参数的请求的话,spring会按照要求处理请求中查询字符串参数;如果没有请求字符串的话服务器会返回404的状态码;

        @RequestParam(required = false)就是对于请求中的查询字符串不做是否存在的要求;即没有查询字符串是为查询当前所有的数据;

有查询字符串是按照要求查找当前指定的数据;

8.3 移除喜欢的⾳乐模块设计

当前我们的收藏音乐表:

1. 请求和响应

2.代码实现

数据层:

int deleteLoveMusic(int userId,int musicId);
  <delete id="deleteLoveMusic" parameterType="java.lang.Integer">
        delete from lovemusic where user_id =#{userId} and music_id =#{musicId};
    </delete>

控制层:

 @RequestMapping("/deletelovemusic")
    public ResponseBodyMessage<Boolean> deleteLoveMusic(@RequestParam String id,
                                                        HttpServletRequest request){
        int musicId = Integer.parseInt(id);
        //验证登录
        HttpSession httpSession = request.getSession(false);
        if(httpSession == null || httpSession.getAttribute(Constant.USERINFO_SESSION_KEY) == null){
            System.out.println("没有登录!");
            return new ResponseBodyMessage<>(-1,"请登录后进行查找收藏喜欢的音乐",null);
        }
        User user = (User) httpSession.getAttribute(Constant.USERINFO_SESSION_KEY);
        int userId = user.getId();
        int ret = loveMusicMapper.deleteLoveMusic(userId,musicId);
        if(ret == 1){
            return new ResponseBodyMessage<>(0,"取消收藏成功",true);
        }else {
            return new ResponseBodyMessage<>(-1,"取消收藏失败",false);
        }
    }

如上所示,测试成功;

此时我们存在这样一个问题:

        表一为收藏音乐的表,表二为音乐列表,我们在表一中进行取消收藏操作是不会对表二有影响的;对表二进行删除操作也是没有影响的(但是实际上表二中的删除操作会导致表一中音乐会被间接的被取消收藏)

问题解决方法:

在音乐删除操作的逻辑中,添加通过musicid取消收藏的逻辑:

int deleteLoveMusicByMusicId(int musicId);
    <delete id="deleteLoveMusicByMusicId" parameterType="java.lang.Integer">
        delete from lovemusic where music_id =#{musicId};
    </delete>

测试结果如下:进行删除单曲音乐之后:

存在的问题:音乐在服务器中删除之后还能进行收藏; 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何在项目中用elementui实现分页器功能

1.在结构部分复制官网代码&#xff1a; <template> 标签: 这是 Vue 模板的根标签&#xff0c;包含所有的 HTML 元素和 Vue 组件。 <div> 标签: 这是一个普通的 HTML 元素&#xff0c;包裹了 el-pagination 组件。它没有特别的意义&#xff0c;只是为了确保 el-pagi…

VB.Net笔记-更新ing

1.1 设置默认VS的开发环境为VB.NET&#xff08;2024/11/18&#xff09; 1.2 新建一个“Hello&#xff0c;world”的窗体&#xff08;2024/11/18&#xff09; 1.3 计算圆面积的小程序&#xff08;2024/11/18&#xff09; 显示/隐式 声明 &#xff08;2024/11/18&#xff0…

每日一练:【优先算法】双指针之移动零(easy)

双指针概念介绍 常见的双指针有两种形式&#xff0c;一种是对撞指针&#xff0c;一种是左右指针。 对撞指针&#xff1a;一般用于顺序结构中&#xff0c;也称左右指针。 • 对撞指针从两端向中间移动。一个指针从最左端开始&#xff0c;另一个从最右端开始&#xff0c;然后逐渐…

树状数组 Color the ball hdu 1556 线段树 洛谷p3372

目录 前言 树状数组 lowbit函数 直观表述 代码 运行结果 树状数组构建代码 树状数组的应用 单点修改和&#xff08;单点&#xff09;区间查询 结合差分数组区间修改 ,单点查询 差分数组 Color the ball hdu 1556 问题描述 问题分析 代码 线段树 洛谷p3372 问题描述 问题…

学习笔记022——Ubuntu 安装 MySQL8.0版本踩坑记录

目录 1、查看可安装 MySQL 版本 2、Ubuntu安装 MySQL8.0 3、MySQL8.0 区分大小写问题 4、MySQL8.0 设置sql_mode 5、MySQL8.0 改端口33060&#xff08;个人遇到问题&#xff09; 1、查看可安装 MySQL 版本 ## 列出可用的MySQL版本&#xff08;列出所有可用的MySQL版本以…

【数据结构】树——链式存储二叉树的基础

写在前面 书接上文&#xff1a;【数据结构】树——顺序存储二叉树 本篇笔记主要讲解链式存储二叉树的主要思想、如何访问每个结点、结点之间的关联、如何递归查找每个结点&#xff0c;为后续更高级的树形结构打下基础。不了解树的小伙伴可以查看上文 文章目录 写在前面 一、链…

qt之QFTP对文件夹(含嵌套文件夹和文件)、文件删除下载功能

一、前言 主要功能如下&#xff1a; 1.实现文件夹的下载和删除&#xff0c;网上很多资料都是单独对某个路径的文件操作的&#xff0c;并不能对文件夹操作 2.实现目标机中含中文名称自动转码&#xff0c;有些系统编码方式不同&#xff0c;下载出来的文件会乱码 3.实现ftp功能…

集群聊天服务器(7)数据模块

目录 Mysql数据库代码封装头文件与源文件 Mysql数据库代码封装 业务层代码不要直接写数据库&#xff0c;因为业务层和数据层的代码逻辑也想完全区分开。万一不想存储mysql&#xff0c;想存redis的话&#xff0c;就要改动大量业务代码。解耦合就是改起来很方便。 首先需要安装m…

手机远程控制电脑,让办公更快捷

在数字化办公的浪潮下&#xff0c;远程控制软件已成为连接工作与生活的桥梁。它使得用户能够通过一台设备&#xff08;主控端&#xff09;来操作另一台设备&#xff08;被控端&#xff09;&#xff0c;无论它们是否位于同一局域网内。这种软件广泛应用于远程办公、手机远程控制…

面向FWA市场!移远通信高性能5G-A模组RG650V-NA通过北美两大重要运营商认证

近日&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;其旗下符合3GPP R17标准的新一代5G-A模组RG650V-NA成功通过了北美两家重要运营商认证。凭借高速度、大容量、低延迟、高可靠等优势&#xff0c;该模组可满足CPE、家庭/企业网关、移动热点、高清视频…

72项!湖北省2024年度第二批省级科技计划项目拟立项项目公示!

本期精选 SCI&EI ●IEEE 1区TOP 计算机类&#xff08;含CCF&#xff09;&#xff1b; ●EI快刊&#xff1a;最快1周录用&#xff01; 知网(CNKI)、谷歌学术期刊 ●7天录用-检索&#xff08;100%录用&#xff09;&#xff0c;1周上线&#xff1b; 免费稿件评估 免费匹配…

LeetCode 热题 100 回顾

目录 一、哈希部分 1.两数之和 &#xff08;简单&#xff09; 2.字母异位词分组 &#xff08;中等&#xff09; 3.最长连续序列 &#xff08;中等&#xff09; 二、双指针部分 4.移动零 &#xff08;简单&#xff09; 5.盛最多水的容器 &#xff08;中等&#xff09; 6…

Chrome 浏览器 131 版本开发者工具(DevTools)更新内容

Chrome 浏览器 131 版本开发者工具&#xff08;DevTools&#xff09;更新内容 一、使用 Gemini 调试 CSS Chrome DevTools 现在推出了一个新的实验性 AI 辅助面板&#xff0c;可以与 Gemini 聊天并获得帮助来调试 CSS。 在 Elements 面板中&#xff0c;右键点击一个元素并选…

网络编程-002-UDP通信

1.UDP通信的简单介绍 1.1不需要通信握手,无需维持连接,网络带宽需求较小,而实时性要求高 1.2 包大小有限制,不发大于路径MTU的数据包 1.3容易丢包 1.4 可以实现一对多,多对多 2.客户端与服务端=发送端与接收端 代码框架 收数据方一般都是客户端/接收端 3.头文件 #i…

websocket身份验证

websocket身份验证 前言 上一集我们就完成了websocket初始化的任务&#xff0c;那么我们完成这个内容之后就应该完成一个任务&#xff0c;当客户端与服务端连接成功之后&#xff0c;客户端应该主动发起一个身份认证的消息。 身份认证proto 我们看一眼proto文件的内容。 我…

初识C++(1)

C是在C语言的基础之上&#xff0c;容纳进去了面向对象编程思想&#xff0c;并增加了许多有用的库以及编程范式等。 在C语言中&#xff0c;变量、函数和类的名称存在于全局作用域中&#xff0c;因此可能会发生许多冲突。比如&#xff1a; #include<stdio.h> #include<…

Axure9生成的阅览页面如何自动展开左侧页面导航?

问题 Axure9生成的阅览页面&#xff0c;默认情况是自动折叠的&#xff0c;如何自动展开左侧页面导航&#xff1f; 解决 Axure工具&#xff1a;发布 > 预览选项 > 播放器 > 打开页面列表

LeetCode:700. 二叉搜索树中的搜索

目录 题目描述: 代码: 题目描述: 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 null 。 示例 1: 输入&#xff1a;root [4,2,7,1,3…

架构图解析:如何构建高效的微服务系统

在当今的数字化浪潮中&#xff0c;构建高效、灵活且可扩展的系统已成为企业的重要目标。微服务架构作为一种先进的软件设计模式&#xff0c;通过将复杂的应用程序分解为一系列小型、独立的服务&#xff0c;显著提升了系统的灵活性、可扩展性和维护性。本文将通过解析微服务系统…

【Android、IOS、Flutter、鸿蒙、ReactNative 】实现 MVP 架构

Android Studio 版本 Android Java MVP 模式 参考 模型层 model public class User {private String email;private String password;public User(String email, String password) {this.email = email;this.password = password;}public String getEmail() {return email;}…