一、功能需求分析
接口需要满足两个需求:
模糊查询:支持按音乐名称关键词搜索收藏的歌曲
全量查询:当不传参数时,返回用户所有收藏的音乐
二、接口设计
GET /lovemusic/findlovemusic
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
musicName | String | 否 | 音乐名称关键词 |
响应设计(假设的一个例子)
{
"status": 0,
"message": "查询到了所有的收藏的音乐",
"data": [
{
"id": 19,
"title": "银河与星斗(女生版)",
"singer": "gaobo",
"url": "/music/get?path=银河与星斗(女生版)",
"time": "2022-03-28",
"userid": 3
}
]
}
三、接口实现
Mapper接口设计
/**
如果没有传⼊具体的歌曲名,显⽰当前⽤⼾收藏的所有⾳乐
@param userId
@return
*/
List<Music> findLoveMusicByUserId(int userId);
/**
根据某个⽤⼾的ID和歌曲名称查询,某个⽤⼾收藏的⾳乐
@param musicName
@param userId
@return
*/
List<Music> findLoveMusicBykeyAndUID(String musicName, int userId);
XML映射配置
<resultMap id="BaseMap1" type="com.example.musicplayer.model.Music">
<id column="id" property="id" />
<id column="title" property="title" />
<id column="singer" property="singer" />
<id column="time" property="time" />
<id column="url" property="url" />
<id column="userId" property="userId" />
</resultMap>
<select id="findLoveMusicByUserId" resultMap="BaseMap1">
select m.* from lovemusic lm,music m where m.id = lm.music_id and
lm.user_id=#{userId}
</select>
<resultMap id="BaseMap2" type="com.example.musicplayer.model.Music">
<id column="id" property="id" />
<id column="title" property="title" />
<id column="singer" property="singer" />
<id column="time" property="time" />
<id column="url" property="url" />
<id column="userId" property="userId" />
</resultMap>
<select id="findLoveMusicBykeyAndUID" resultMap="BaseMap2">
select m.* from lovemusic lm,
music m where m.id = lm.music_id and lm.user_id=#{userId} and title like
concat('%',#{musicName},'%')
</select>
这一段语句,相对于之前的Mybatis语句显得稍微复杂一点,我们可以简单的分析一下这段语句:
在SQL中,当使用逗号(,)连接两个表(如`from lovemusic lm, music m`)而不指定连接条件时,会产生笛卡尔积(即两个表所有行的组合)。但是,在这个例子中,where子句中指定了连接条件(`m.id = lm.music_id`)以及额外的过滤条件(`lm.user_id=#{userId}`)。因此,这里并不是笛卡尔积,而是内连接(等价于使用INNER JOIN)。
INNER JOIN就是同时将两表作为参考对象,根据ON后给出的两表的条件将两表连接起来。结果则是两表同时满足ON后的条件的部分才会列出。
四、服务层实现
Controller核心逻辑
@RequestMapping("/findlovemusic")
public ResponseBodyMessage<List<Music>>
findLoveMusic(@RequestParam(required=false)String musicName,
HttpServletRequest req) {
//没有session不创建
HttpSession httpSession = req.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();
List<Music> musics = new ArrayList<>();
if(musicName != null) {
musics = loveMusicMapper.findLoveMusicBykeyAndUID(musicName,userid);
}else {
musics = loveMusicMapper.findLoveMusicByUserId(userid);
}
return new ResponseBodyMessage<>(0,"查询到了所有的收藏的⾳乐",musics);
}
由于并没有放任何数据进去,所以我们看到的data里面的内容都是空的。
我们尝试做一些违法操作,直接在数据库中塞入一条数据。我们就可以看到!!
一些参考点:
使用
@RequestParam(required=false)
实现可选参数通过Session验证用户状态
根据参数动态选择查询方法
统一响应格式封装
代码仓库: