SSM项目实战——哈哈音乐(四)前台模块开发

1、项目准备

①导入依赖和前端资源

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><parent><artifactId>hami-parent</artifactId><groupId>com.qcby</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>hami-portal</artifactId><packaging>war</packaging><name>hami-portal Maven Webapp</name><dependencies><dependency><groupId>com.qcby</groupId><version>1.0-SNAPSHOT</version><artifactId>hami-core</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><scope>provided</scope></dependency><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId></dependency></dependencies></project>

 

②在resources下导入创建springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><mvc:annotation-driven><mvc:message-converters><bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"><property name="supportedMediaTypes" value="text/html;charset=UTF-8"/><property name="features"><array><value>WriteMapNullValue</value><value>WriteNullStringAsEmpty</value></array></property><property name="dateFormat" value="yyyy-MM-dd"></property></bean></mvc:message-converters></mvc:annotation-driven><context:component-scan base-package="com.qcby.controller"/><bean id="viewResource" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/page/"></property><property name="suffix" value=".jsp"></property></bean><mvc:view-controller path="/index" view-name="index"></mvc:view-controller><mvc:default-servlet-handler/>
</beans>

③配置web.xml

<web-appversion="2.5"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xml="http://www.w3.org/XML/1998/namespace"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><filter><filter-name>SpringCharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>SpringCharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern></servlet-mapping><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param>
</web-app>

2、歌曲界面

①展示所有歌曲

启动tomcat后,进入index.jsp页面,发送dofindAll,可以根据条件查询歌曲也可以查询所有歌曲信息

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body><jsp:forward page="/song/dofindAll"></jsp:forward>
</body>
</html>

 创建SongController,编写dofindAll,给search.jsp页面返回歌曲和所有专辑信息

package com.qcby.controller;import com.qcby.model.Mtype;
import com.qcby.model.Page;
import com.qcby.model.Song;
import com.qcby.query.SongQuery;
import com.qcby.service.MtypeService;
import com.qcby.service.SongService;
import com.qcby.service.SongerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;@Controller
@RequestMapping("/song")
public class SongController {@Autowiredprivate SongService songService;@Autowiredprivate MtypeService mtypeService;@RequestMapping("/dofindAll")public String list(SongQuery mq, Model model){if(mq.getPageNo() == 0){mq.setPageNo(1);}Page<Song> page = songService.selectObjectByCondition(mq);model.addAttribute("page", page);model.addAttribute("mq", mq);List<Mtype> mtypes = mtypeService.selectObjectAll();model.addAttribute("mtypes", mtypes);return "search";}

research.jsp界面展示歌曲信息

<div id="body" class="gap"><input id="tid" type="hidden" value="${mq.tid}"><input id="isHot" type="hidden" value="${mq.isHot}"><input id="isNew" type="hidden" value="${mq.isNew}"><div class="wrapper"><div class="content_wrapper"><div class="content"><div class="filter" data-spm="1392350033"><dl><dt>流派&nbsp;:</dt><dd><p><a href="#" ftype="mtype" value="" class="current">全部</a><c:forEach items="${mtypes}" var="mtype"><a href="#" ftype="mtype" value="${mtype.tid}">${mtype.tname}</a></c:forEach></p></dd></dl><dl><dt>热门&nbsp;:</dt><dd><p><a href="#" ftype="isHot" value="" class="current">全部</a><a href="#" ftype="isHot" value="1">热门</a></p></dd></dl><dl><dt>新歌&nbsp;:</dt><dd><p><a href="#" ftype="isNew" value="" class="current">全部</a><a href="#" ftype="isNew" value="1">最新</a></p></dd></dl></div><div class="chart" data-spm="1392350021"><table><thead><tr><td width="40"></td><td width="45"></td><td></td><td width="180"></td><td width="180"></td><td width="130"></td></tr><tr><th align="right"><input type="checkbox" checked onclick="selectall(this);"></th><th align="left" colspan="5"><b class="play" onclick="playsongs();"></b></th></tr></thead><tbody id="content"><c:forEach items="${page.list}" var="song" varStatus="status"><tr data-index="0"><td align="right"><input type="checkbox" name="chartids" checked="checked"value="${song.sid}"></td><td align="center">${status.count}</td><td><div class="song"><div class="image"><img src="${filePath}${song.songer.pic}" alt="Every Breath You Take"height="55" width="55"/><b></b></div><div class="info"><p><strong><a target="_blank" title="Every Breath You Take"href="#">${song.sname}</a></strong></p></div></div></td><td><span><a target="_blank" href="#" title="Karen Souza">${song.songer.srname}</a></span></td><td><span><a target="_blank" title="Essentials" href="#">${song.album.aname}</a></span></td><td><div class="action"><button class="play" onclick="play(${song.sid});" title="试听">试听</button><button class="download" title="下载">下载</button><button class="offline" title="发送到">发送到</button></div></td></tr></c:forEach></tbody></table></div><input type="hidden" id="pageNoPortal" value="${mq.pageNoPortal}"><c:if test="${page.pageNo < page.totalPage}"><div class="loadr" id="loader"><a href="javascript:void(0);" onclick="loadMore()"><b></b>查看更多</a></div></c:if><c:if test="${page.pageNo == page.totalPage}"><div class="loadr" id="nomore" style="font-size: 18px;">没有更多啦!</div></c:if></div></div><div class="sidebar" data-spm="1392350021"><div class="nav"><a class="index" href="#"><b></b>发现</a><a class="top" href="#"><b></b>排行榜</a><a class="magazines" href="#"><b></b>音乐人企划</a><a class="artists" href="/songer/dofindAll"><b></b>音乐人</a><a class="songs current" href="/song/dofindAll"><b></b>歌曲</a><a class="albums" href="#"><b></b>专辑<sup>无损</sup></a></div><div class="genre"><c:forEach items="${mtypes}" var="mtype"><a href="/song/dofindAll?tid=${mtype.tid}"><b></b>${mtype.tname}</a></c:forEach></div></div></div></div>

 

②根据条件搜索歌曲 

search.jsp页面的js请求

<script>var tid = "";var isHot = "";var isNew = "";$(function () {//指定点击事件$(".filter p a").click(function () {//移除同辈的a链接的样式$(this).siblings().removeClass("current");//把点击的a链接的样式加上$(this).addClass("current");//获得流派的选中值var tid = $("a[ftype='mtype'][class='current']").attr("value");var isHot = $("a[ftype='isHot'][class='current']").attr("value");var isNew = $("a[ftype='isNew'][class='current']").attr("value");//alert(tid+"   "+isHot+"   "+isNew);window.location.href = "/song/dofindAll?tid=" + tid + "&isHot=" + isHot + "&isNew=" + isNew;})tid = $("#tid").val();isHot = $("#isHot").val();isNew = $("#isNew").val();//流派的回显$("a[ftype='mtype'][class='current']").removeClass("current");$("a[ftype='mtype'][value='" + tid + "']").addClass("current");//热门回显$("a[ftype='isHot'][class='current']").removeClass("current");$("a[ftype='isHot'][value='" + isHot + "']").addClass("current");//新歌回显$("a[ftype='isNew'][class='current']").removeClass("current");$("a[ftype='isNew'][value='"+ isNew + "']").addClass("current");})

③查看更多

 js代码

function loadMore() {//2  111111  5 10 15 20var pageNoPortal = parseInt($("#pageNoPortal").val());//计算pageSizevar pageSize = 5 * (++pageNoPortal);window.location.href = "/song/dofindAll?tid=" + tid + "&isHot=" + isHot + "&isNew=" + isNew + "&pageSize=" + pageSize + "&pageNoPortal=" + pageNoPortal;}

前端代码

<c:if test="${page.pageNo < page.totalPage}">
<div class="loadr" id="loader"><a href="javascript:void(0);" onclick="loadMore()"><b></b>查看更多</a>
</div>
</c:if>
<c:if test="${page.pageNo == page.totalPage}">
<div class="loadr" id="nomore" style="font-size: 18px;">没有更多啦!</div>
</c:if>

上面三个功能都是通过controller中dofindAll这一个请求来实现,只是所传的参数不一致 

对于展示所有歌曲,dofindAll不传任何参数,直接查询所有的歌曲信息

对于根据条件搜索歌曲,传入歌曲流派、是否热门、是否是新歌这三个信息作为筛选条件进行歌曲搜索

对于查看更多,除了传入三个搜索条件还传入页面大小和当前页码作为条件进行查询

④歌曲播放

功能:可以通过点试听,单个歌曲播放,也可以选取多个歌曲放入播放列表中按顺序播放

实现思路:对于单个歌曲播放功能,直接根据当前传入的歌曲id查询歌曲信息,将歌曲信息传给play.jsp页面进行歌曲播放

对于播放列表播放歌曲,首先通过cookie获取上一次未播放完的歌曲id,然后本次传入的歌曲id列表加上上次的歌曲id列表,变成一个新的歌曲id列表,并将新的歌曲id列表存入cookie中。根据歌曲id列表查询歌曲信息,将其交给paly.jsp页面,进行歌曲播放

js代码

function selectall(checkallObj) {var checked = $(checkallObj).attr("checked");if(checked =="checked"){$("tbody tr td input[type='checkbox']").attr("checked","checked");}else{$("tbody tr td input[type='checkbox']").removeAttr("checked");}}function playsongs() {//拿到所有的复选框选中的元素var songs = $("tbody tr td input[type='checkbox']:checked")var sids = ""; //"1,2,3,4,5,"songs.each(function () {var sid = $(this).val();sids = sids + sid+","})window.open("/song/play?sids="+sids,"play");}function play(sid) {window.open("/song/play?sids="+sid,"play");}</script>

controller代码

/*** 实现歌曲播放列表* @param sids   选中的歌曲列表* @param model* @param request* @param response* @return* @throws UnsupportedEncodingException*/@RequestMapping("/play")public String play(String sids, Model model, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {//1、处理sids字符串,变成集合给后台查询,变成cookie作为下一次使用的记录//idList记录歌曲播放列表,就是本次新添加的播放歌曲sids+上一次的播放歌曲列表List<String> idList = new ArrayList<>();String[] idArr = null;//程序严谨性判断if(sids != null && !"".equals(sids)){idArr = sids.split(",");for (String s : idArr) {idList.add(s);}}//如果是第一次添加歌曲列表,不考虑,否则需要拿到cookie查看上次播放记录//pids存储的是上次歌曲播放值String pids = "";Cookie[] cookies = request.getCookies();if(cookies != null && cookies.length > 0){for (Cookie cookie : cookies) {String name = cookie.getName();if("playids".equals(name)){//解码  防止乱码pids = URLDecoder.decode(cookie.getValue(),"UTF-8");}}}//oldArr存放的是上一次播放的歌曲列表String[] oldArr = pids.split(",");for (int i = 0; i < oldArr.length; i++) {//保证不重复添加相同的歌曲,如果上次歌曲播放列表中含有本次添加的播放列表,则不添加到新的播放列表if(!idList.contains(oldArr[i])){idList.add(oldArr[i]);}}//创建新的歌曲播放列表,原来存储的播放歌曲列表为list<String>类型,idsList变成list<Integer>,用于后台查询List<Integer> idsList = new ArrayList<>();//字符串类型的新的播放列表,用于cookie传值给前端作为上一次播放列表String playids = "";for (String s : idList) {if(!"".equals(s)){idsList.add(new Integer(s));playids = playids + s+",";}}List<Song> songs = new ArrayList<>();if(idsList.size() > 0)songs = songService.getSongByIds(idsList);model.addAttribute("songs",songs);System.out.println(songs);System.out.println(playids);playids = URLEncoder.encode(playids, "UTF-8");Cookie cookie = new Cookie("playids", playids);//cookie的有效时间cookie.setMaxAge(60*60*24*30);//设置cookie的访问有效路径cookie.setPath("/");response.addCookie(cookie);return "player";}/*** 获取播放的歌曲信息,实现歌曲播放* @param sid* @return*/@ResponseBody@RequestMapping("/getSong")public Song getSong(Integer sid){Song song = songService.getSong(sid);System.out.println(song);return song;}

 通过歌曲id获取歌曲信息的service接口

 //添加播放列表public List<Song> getSongByIds(List<Integer> idsList);
//实现歌曲播放Song getSong(Integer sid);

通过歌曲id获取歌曲信息的service实现类

 @Overridepublic List<Song> getSongByIds(List<Integer> idsList) {return songMapper.getSongByIds(idsList);}
//实现歌曲播放@Overridepublic Song getSong(Integer sid) {return songMapper.getSong(sid);}

通过歌曲id获取歌曲信息的mapper接口

//实现添加播放列表List<Song> getSongByIds(List<Integer> idsList);
//实现歌曲播放Song getSong(Integer sid);

通过歌曲id获取歌曲信息的sql

<resultMap id="getSongByIdsRM" type="com.qcby.model.Song" extends="ResultMapWithBLOBs"><association property="songer" javaType="com.qcby.model.Songer" resultMap="com.qcby.dao.SongerMapper.BaseResultMap"></association></resultMap><!--  查询要播放的歌曲集合返回--><select id="getSongByIds" parameterType="java.util.List" resultMap="selectObjectByConditionRM">select * from song s left join mtype m on s.tid=m.tid left join songer sr on s.srid=sr.srid left join album a on s.aid=a.aid<where>s.sid in<if test="list!=null"><foreach collection="list" open="(" close=")" separator="," item="sid">#{sid}</foreach></if>order by field (s.sid,<foreach collection="list" separator="," item="sid">#{sid}</foreach>)</where></select><resultMap id="getSongRM" type="com.qcby.model.Song" extends="ResultMapWithBLOBs"><association property="songer" javaType="com.qcby.model.Songer" resultMap="com.qcby.dao.SongerMapper.BaseResultMap"></association></resultMap><!--  实现歌曲播放--><select id="getSong" parameterType="int" resultMap="getSongRM">select * from song left join songer on song.srid=songer.srid where song.sid=#{sid}</select>

play.jsp页面

<c:forEach items="${songs}" var="song" varStatus="status"><li class="songList"><div class="songLMain"><div class="check"><input class="checkIn" type="checkbox" select="0" value="${song.sid}"></div><div class="start" ><em sonN="${status.count}" msid="${song.sid}">${status.count}</em></div><div class="songBd"><div class="col colsn">${song.sname}</div><div class="col colcn">${song.songer.srname}</div><div class="col">${song.album.aname}</div></div><div class="control"><a class="cicon love"></a><a class="cicon more" style="display:none"></a><a class="cicon dele" style="display:none"></a></div></div>									</li>
</c:forEach>

3、音乐人界面

①展示所有音乐人

创建SongerController,编写controller

package com.qcby.controller;import com.qcby.model.Mtype;
import com.qcby.model.Page;
import com.qcby.model.Songer;
import com.qcby.query.SongerQuery;
import com.qcby.service.MtypeService;
import com.qcby.service.SongService;
import com.qcby.service.SongerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.ArrayList;
import java.util.List;@Controller
@RequestMapping("/songer")
public class SongerController {@Autowiredprivate SongerService songerService;@Autowiredprivate MtypeService mtypeService;@RequestMapping("/dofindAll")public String listType(SongerQuery mq, Model model) {if (mq.getPageNo() == 0) {mq.setPageNo(1);}mq.setPageSize(20);Page<Songer> page = songerService.selectObjectByCondition(mq);List<Mtype> mtypes = mtypeService.selectObjectAll();List<List<Songer>> list = new ArrayList<>();List<Songer> slist = (List<Songer>) page.getList();List<Songer> list1 = null;for (int i = 0; i < 20; i++) {if (i % 5 == 0) {list1 = new ArrayList<>();list.add(list1);}Songer s = null;if (i < slist.size()) {s = slist.get(i);list1.add(s);}}model.addAttribute("sList", list);model.addAttribute("page", page);model.addAttribute("mq", mq);model.addAttribute("mtypes", mtypes);return "songers";}

前端songers.jsp页面展示

<div id="body" class="gap"><input id="tid" type="hidden" value="${mq.tid}"><input id="isHot" type="hidden" value="${mq.isHot}"><div class="wrapper"><div class="content_wrapper"><div class="content"><div class="filter" data-spm="1392350033"><dl><dt>流派&nbsp;:</dt><dd><p><a href="#" ftype="mtype" value="" class="current">全部</a><c:forEach items="${mtypes}" var="mtype"><a href="#" ftype="mtype" value="${mtype.tid}">${mtype.tname}</a></c:forEach></p></dd></dl><dl><dt>热门&nbsp;:</dt><dd><p><a href="#" ftype="isHot" value="" class="current">全部</a><a href="#" ftype="isHot" value="1">热门</a></p></dd></dl></div><div class="albums" data-spm="1392350021"><c:forEach items="${sList}" var="subList"><div class="album_list"><c:forEach items="${subList}" var="songer"><div class="album" data-needpay="0" data-playstatus="1" data-downloadstatus="1"><div class="image"><a target="_blank" title="${songer.srname}" href="/songer/getSonger?srid=${songer.srid}"><img src="${filePath}${songer.pic}" alt="${songer.srname}"><b class="icon toplay" onclick="playalbum(406532);return false;" style="display: none;"></b><dl style="display: none;"><dt><b class="icon toheart"></b><b class="icon todropmenu"></b></dt><dd style="display: none;"><ul><li onclick="tag(406532,5);return false;"><b class="icon tofavourite"></b>收藏</li><li onclick="album2collect(406532);return false;"><b class="icon tocollect"></b>添加到</li><li onclick="recommend(406532,33);return false;"><b class="icon toshare"></b>分享到</li></ul></dd></dl><sup title="${songer.srname}"></sup>			</a></div><div class="info"><p><a target="_blank" title="${songer.srname}" href="#">${songer.srname}</a></p></div></div></c:forEach></div></c:forEach></div><input type="hidden" id="pageNoPortal" value="${mq.pageNoPortal}"><c:if test="${page.pageNo < page.totalPage}"><div class="loadr" id="loader"><a href="javascript:void(0);" onclick="loadMore01()"><b></b>查看更多</a></div></c:if><c:if test="${page.pageNo == page.totalPage}"><div class="loadr" id="nomore" style="font-size: 18px;">没有更多啦!</div></c:if></div></div><div class="sidebar" data-spm="1392350021"><div class="nav"><a class="index" href="#"><b></b>发现</a><a class="top" href="#"><b></b>排行榜</a><a class="magazines" href="#"><b></b>音乐人企划</a><a class="artists current" href="#"><b></b>音乐人</a><a class="songs " href="/song/dofindAll"><b></b>歌曲</a><a class="albums" href="#"><b></b>专辑<sup>无损</sup></a></div><div class="genre"><c:forEach items="${mtypes}" var="mtype"><a href="/songer/dofindAll?tid=${mtype.tid}"><b></b>${mtype.tname}</a></c:forEach></div></div></div></div>

②根据条件搜索音乐人

songers.jsp页面的js请求

<script>$(function () {var tid = "";var isHot = "";$(function () {//指定点击事件$(".filter p a").click(function () {//移除同辈的a链接的样式$(this).siblings().removeClass("current");//把点击的a链接的样式加上$(this).addClass("current");//获得流派的选中值var tid = $("a[ftype='mtype'][class='current']").attr("value");var isHot = $("a[ftype='isHot'][class='current']").attr("value");//alert(tid+"   "+isHot+"   "+isNew);window.location.href = "/songer/dofindAll?tid="+tid+"&isHot="+isHot;})tid = $("#tid").val();isHot = $("#isHot").val();//流派的回显$("a[ftype='mtype'][class='current']").removeClass("current");$("a[ftype='mtype'][value='"+tid+"']").addClass("current");//热门回显$("a[ftype='isHot'][class='current']").removeClass("current");$("a[ftype='isHot'][value='"+isHot+"']").addClass("current");})

③查看更多

songers.jsp页面的js请求

 function loadMore01() {var pageNoPortal = parseInt($("#pageNoPortal").val());//计算pageSizevar pageSize = 5*(++pageNoPortal);window.location.href = "/song/dofindAll?tid="+tid+"&isHot="+isHot+"&pageSize="+pageSize+"&pageNoPortal="+pageNoPortal;}

这里前三个共用一个请求—dofindAll,和歌曲界面相似,也只是请求参数不一样 

④查看音乐人的详细信息

点击音乐人的图片,就可以查看音乐人的详细信息,发送getSonger请求,并带有音乐人的id

<a target="_blank" title="${songer.srname}" href="/songer/getSonger?srid=${songer.srid}">

controller编写,根据音乐人的id联表查询歌曲信息,将其返回给songer,jsp页面

@RequestMapping("/getSonger")public String getSong(Integer srid, Model model) {Songer songer = songerService.getSongs(srid);model.addAttribute("songer",songer);System.out.println(songer);return "songer";}

根据音乐人的id联表查询歌曲信息的service接口

//根据歌手id联表查询歌曲信息public Songer getSongs(Integer srid);

根据音乐人的id联表查询歌曲信息的service实现类

@Overridepublic Songer getSongs(Integer srid) {return songerMapper.getSongs(srid);}

根据音乐人的id联表查询歌曲信息的mapper接口

 //根据歌手id联表查询歌曲信息public Songer getSongs(Integer srid);

根据音乐人的id联表查询歌曲信息的sql

 <resultMap id="getSongsRM" type="com.qcby.model.Songer" extends="ResultMapWithBLOBs"><collection property="songs" ofType="com.qcby.model.Song" resultMap="com.qcby.dao.SongMapper.BaseResultMap"></collection><collection property="mtype" ofType="com.qcby.model.Mtype" resultMap="com.qcby.dao.MtypeMapper.BaseResultMap"></collection></resultMap><select id="getSongs" parameterType="Integer" resultMap="getSongsRM">select sr.srid, sr.srname, sr.area, sr.intro, sr.pic, m.*, s.* from songer sr left join mtype m on sr.tid=m.tid left join song s on sr.srid=s.srid where sr.srid=#{srid}</select>

songer.jsp页面

 <div id="artist_info"><table><tbody><tr><td width="56" valign="top" class="item">地区:</td><td valign="top">${songer.area}</td></tr><tr><td width="56" valign="top" class="item">风格:</td><td valign="top"><a href="/songer/dofindAll?tid="${songer.mtype.tid}>${songer.mtype.tname}</a></td></tr><tr><td width="56" valign="top" class="item">档案:</td><td valign="top"><div class="record">${songer.intro}</div></td></tr></tbody></table></div><div id="artist_photo"><a id="cover_lightbox"href="#" target="_blank"title="${songer.srname}" data-lightbox="lightbox"> <imgsrc="${filePath}${songer.pic}"alt="${songer.srname}"/></a></div>

至此,一个哈哈音乐项目就全部完成啦!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决element-plus table组件 fixed=“right“(left)浮动后横向滚动文字穿透的问题

BUG 版本&#xff1a;element-plus 2.6.1 浏览器&#xff1a;360极速浏览器22.1 (Chromium内核) 组件&#xff1a;el-table组件 问题&#xff1a;在头部/尾部浮动加上斑马条纹后&#xff0c;横向滚动存在文字穿透的问题。具体如图&#xff1a; 白色背景行的文字&#xff0c…

蓝桥杯单片机真题实践篇

这里就不完全写思路过程代码什么的&#xff0c;这一篇文章就写我在训练真题中遇到的过程。 &#xff08;呜呜呜&#xff0c;时间不够辣&#xff0c;能做多少算多少吧....&#xff09; 十三届省赛题 问题1&#xff1a;数码管的数字消影不明显 &#xff08;参考&#xff1a;蓝…

【蓝桥杯-单链表-网络寻路】

蓝桥杯-单链表-网络寻路 单链表基本操作操作一&#xff1a;向链表头插入一个数操作二:在第 k个插入的数后插入一个数操作三&#xff1a;删除第 k个插入的数后面的一个数&#xff1b; P8605 [蓝桥杯 2013 国 AC] 网络寻路 单链表基本操作 初始化有关操作 // head 表示头结点的…

python-基础篇-字符串、列表、元祖、字典-列表

文章目录 2.3.2列表2.3.2.1列表介绍2.3.2.1.1列表的格式2.3.2.1.2打印列表 2.3.2.2列表的增删改查2.3.2.2.1列表的遍历2.3.2.2.1.1使用for循环2.3.2.2.1.2使用while循环 2.3.2.2.2添加元素("增"append, extend, insert)2.3.2.2.2.1append 2.3.2.2.2.2extend2.3.2.2.2…

考研回忆录【二本->211】

备考时长差不多快一年半&#xff0c;从22年的11月底开始陆陆续续地准备考研&#xff0c;因为开始的早所以整个备考过程显得压力不是很大&#xff0c;中途还去一些地方旅游&#xff0c;我不喜欢把自己绷得太紧。虽然考的不是很好&#xff0c;考完我甚至都没准备复试&#xff0c;…

12-1-CSS 常用样式属性

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 CSS 常用样式属性1 CSS 三角形2 CSS 用户界面样式2.1 什么是界面样式2.2 鼠标…

微电网优化:基于​海象优化算法(Walrus Optimization Algorithm,WOA)​的微电网优化(提供MATLAB代码)

一、微电网优化模型 微电网是一个相对独立的本地化电力单元&#xff0c;用户现场的分布式发电可以支持用电需求。为此&#xff0c;您的微电网将接入、监控、预测和控制您本地的分布式能源系统&#xff0c;同时强化供电系统的弹性&#xff0c;保障您的用电更经济。您可以在连接…

(学习日记)2024.04.02:UCOSIII第三十节:信号量

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

Ps:预览调整 32 位 HDR 图像

由于 HDR 图像的动态范围超出了标准计算机显示器的显示范围。在 Photoshop 中打开 HDR 图像时&#xff0c;图像可能会非常暗或出现褪色现象。 Photoshop 提供了专门的预览调整功能&#xff0c;以使标准显示器显示的 HDR 图像的高光和阴影不会太暗或出现褪色现象。 预览调整设置…

docker的安装及入门指令

目录 一、将docker安装到云服务器步骤 1.更新系统yum版本 2.安装所需依赖 3.添加docker仓库设置(使用的是阿里云) 4.安装docker引擎 5.启动docker并开启自动启动 6. 检查是否安装成功&#xff0c;成功会显示相应版本&#xff0c;否则安装失败 二、docker常用命令 1.从…

最优算法100例之33-数据流的中位数

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。 例如, [2,3,4] 的中位数是 3 [2,3] 的中位…

Map源码解析

基本介绍 其实HashMap底层是个什么东西我们之前也讲过, 就是一个哈希桶(差不多可以看成一个数组), 然后每一个节点又连接着链表/红黑树之类的, 下面让我们看一看具体在源码上是怎样实现的: 常量及其它 -> static final int DEFAULT_INITIAL_CAPACITY 1 << 4; //这个…

计算机网络——35什么是网络安全

什么是网络安全 机密性&#xff1a;只有发送方和预订的接收方能否理解传输的报文内容 发送方加密报文接收方解密报文 认证&#xff1a;发送方和接收方需要确认对方的身份报文完整性&#xff1a;发送方、接收方需要确认的报文在传输的过程中或者事后没有被改变访问控制和服务的…

利用nginx-http-flv-module实现三种直播

目录 一、说明 二、目标 三、实现 四、直播地址 一、说明 此文在《流媒体服务器的搭建(支持hls)》《搭建nginx-http-flv-module直播系统》之后编写,很多详细内容需要参考它。 流媒体服务器的搭建(支持hls)

若依:一个基于Spring Boot、Spring Security、JWT、Vue和Element的全部开源快速开发平台

若依后台管理系统&#xff1a;一个基于Spring Boot、Spring Security、JWT、Vue和Element的全部开源快速开发平台 一、引言 随着软件开发技术的发展&#xff0c;前后端分离的开发模式逐渐成为主流。这种模式能够提高开发效率&#xff0c;降低维护成本&#xff0c;使前后端工程…

c# wpf template itemtemplate+ListBox

1.概要 2.代码 <Window x:Class"WpfApp2.Window7"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/…

Kafka参数介绍

官网参数介绍:Apache KafkaApache Kafka: A Distributed Streaming Platform.https://kafka.apache.org/documentation/#configuration

开源大语言模型(LLM)汇总(持续更新中)

随着ChatGPT的火爆&#xff0c;越来越多人希望在本地运行一个大语言模型。为此我维护了这个开源大语言模型汇总&#xff0c;跟踪每天不发的大语言模型和精调语言模型。 我将根据个模型采用的基础大模型进行分类&#xff0c;每个大模型下列出各派生模型。 Alpaca (Stanford) 斯…

STM32CubeIDE基础学习-通用定时器中断实验

STM32CubeIDE基础学习-通用定时器中断实验 文章目录 STM32CubeIDE基础学习-通用定时器中断实验前言第1章 工程配置1.1 工程外设配置部分1.2 生成工程代码部分 第2章 代码编写第3章 实验现象总结 前言 生活中很多应用都有用到定时器功能、计时功能等。 定时器中断可以大大降低…

Win10文件夹共享(有密码的安全共享)(SMB协议共享)

前言 局域网内&#xff08;无安全问题&#xff0c;比如自己家里wifi&#xff09;无密码访问&#xff0c;参考之前的操作视频 【电脑文件全平台共享、播放器推荐】手机、电视、平板播放硬盘中的音、视频资源 下面讲解公共网络如办公室网络、咖啡厅网络等等环境下带密码的安全…