ssm实战项目──哈米音乐(二)

[复制链接]
发表于 2025-12-19 22:51:08 | 显示全部楼层 |阅读模式
目次
1、流派搜索与分页
2、流派的添加
3、流派的修改
4、流派的删除

接上篇:ssm实战项目──哈米音乐(一),我们完成了项目的团体搭建,接下来举行配景模块的开辟。
起首是流派模块:
在该模块中接纳分页查询,将数据库中流派的信息通太过页举行查询,盼望查询效果如下:

1、流派搜索与分页

想要告竣该效果须要在后端查询到的数据出现到前端的jsp页面上。
起首在后端中要把查询效果包装到一起,因此在ham-core子模块中的util文件夹下创建Page类来存放查询到的数据,该类包罗每页展示数量(已知),当前的页号,总页数,开始页数,数据聚集效果和总记载数。使用该类的一个对象将其返回到前端界面即可。
该类信息如下:
  1. /**
  2. * 封装前端需要的承载数据以及分页相关的一个实体
  3. * 自定义页的类
  4. */
  5. public class Page<T> {
  6.     //每页展示数量(已知)
  7.     private Integer pageSize=5;
  8.     //页码(已知)
  9.     private Integer pageNo=1;
  10.     //总页数(计算)  总记录数/每页展示数量
  11.     private Integer totalPage;
  12.     //开始行号(计算)(pageNO-1) *pagesize
  13.     private Integer startNum=0;
  14.     //数据集合结果
  15.     private List<T> list;
  16.     //总记录数 count(*)
  17.     private Integer totalCount=0;
  18.     public Integer getPageSize() {
  19.         return pageSize;
  20.     }
  21.     public void setPageSize(Integer pageSize) {
  22.         this.pageSize = pageSize;
  23.     }
  24.     public Integer getPageNo() {
  25.         return pageNo;
  26.     }
  27.     public void setPageNo(Integer pageNo) {
  28.         this.pageNo = pageNo;
  29.     }
  30.     public Integer getTotalPage() {
  31.         totalPage=totalCount/pageSize;
  32.         if(totalCount==0 || totalCount%pageSize!=0){
  33.             totalPage++;
  34.         }
  35.         return totalPage;
  36.     }
  37.     public void setTotalPage(Integer totalPage) {
  38.         this.totalPage = totalPage;
  39.     }
  40.     public Integer getStartNum() {
  41.         return startNum;
  42.     }
  43.     public void setStartNum(Integer startNum) {
  44.         this.startNum = startNum;
  45.     }
  46.     public List<T> getList() {
  47.         return list;
  48.     }
  49.     public void setList(List<T> list) {
  50.         this.list = list;
  51.     }
  52.     public Integer getTotalCount() {
  53.         return totalCount;
  54.     }
  55.     public void setTotalCount(Integer totalCount) {
  56.         this.totalCount = totalCount;
  57.     }
  58. }
复制代码
将后端查询到的实体返回前端界面,在jsp界面中接纳foreach举行吸取,代码如下:
  1. <tbody>
  2. <c:forEach items="${page.list}" var="mtype" varStatus="status">
  3.    <tr>
  4.        <td class="hidden-xs-portrait">${mtype.tid}</td>
  5.        <td class="hidden-xs-portrait">${mtype.tname}</td>
  6.        <td class="hidden-xs"> ${mtype.tdesc} </td>
  7.        <td>
  8.            <button  class="btn btn-sm btn-primary" type="button" modify tid="${mtype.tid}" > 修改</button>
  9.            <button data-toggle="button" class="btn btn-sm btn-warning" tid="${mtype.tid}"> 删除</button>
  10.        </td>
  11.    </tr>
  12. </c:forEach>
  13. </tbody>
  14.   <jsp:include page="pagination.jsp"></jsp:include>
复制代码
为节省代码,将分页的页码单独写一个界面pagination.jsp,并在其他界面中引用:
  1. <div class="clearfix text-right">
  2.     <%--隐藏域--%>
  3.     <input type="hidden" id="pageNo" name="pageNo" value="${mq.pageNo}">
  4.     <input type="hidden" id="totalPage" value="${page.totalPage}">
  5.     <ul class="pagination no-margin">
  6.         <li id="prev" class="disabled"><a href="#">Prev</a></li>
  7.         <c:forEach begin="1" end="${page.totalPage}" var="myPageNo">
  8.             <li <c:if test="${myPageNo == mq.pageNo}">class="active"</c:if>><a
  9.                     pageNoButton href="#">${myPageNo}</a></li>
  10.         </c:forEach>
  11.         <li id="next"><a href="#">Next</a></li>
  12.     </ul>
  13. </div>
复制代码
在界面中使用js来控制分页:
  1. /**
  2.              * 用于控制上一页和下一页的可用的切换
  3.              * @type {jQuery}
  4.              */
  5.             var pageNo = $("#pageNo").val();
  6.             var totalPage = $("#totalPage").val();
  7.             pageNo = parseInt(pageNo);
  8.             totalPage = parseInt(totalPage);
  9.             if (pageNo == 1 && pageNo == totalPage) {
  10.                 $("#prev").addClass("disabled");
  11.                 $("#next").addClass("disabled");
  12.             }
  13.             if (pageNo == 1 && pageNo < totalPage) {
  14.                 $("#prev").addClass("disabled");
  15.                 $("#next").removeClass("disabled");
  16.             }
  17.             if (pageNo > 1 && pageNo < totalPage) {
  18.                 $("#prev").removeClass("disabled");
  19.                 $("#next").removeClass("disabled");
  20.             }
  21.             if (pageNo > 1 && pageNo == totalPage) {
  22.                 $("#prev").removeClass("disabled");
  23.                 $("#next").addClass("disabled");
  24.             }
  25.             $("#prev").click(function () {
  26.                 $("#pageNo").val(--pageNo);
  27.                 $("#txForm").submit();
  28.             })
  29.             $("#next").click(function () {
  30.                 $("#pageNo").val(++pageNo);
  31.                 $("#txForm").submit();
  32.             })
  33.             $("a[pageNoButton]").click(function () {
  34.                 var pageNo = $(this).html();
  35.                 $("#pageNo").val(pageNo);
  36.                 $("#txForm").submit();
  37.             })
复制代码
想要分页查询到流派信息还须要一个流派查询的类,封装前端传来的参数传给后端,比方当前是第几页,要实现搜素功能时要通报的名字
在ham-core的query文件下创建该类如下:
  1. /**
  2. * 只作为表现层接收前端参数封装使用
  3. */
  4. public class MtypeQuery extends Mtype{
  5.     //页码
  6.     private Integer pageNo;
  7.     //每页展示数量
  8.     private Integer pageSize=5;
  9.     //开始行号
  10.     private Integer startNum;
  11.     public Integer getPageNo() {
  12.         return pageNo;
  13.     }
  14.     public void setPageNo(Integer pageNo) {
  15.         this.pageNo = pageNo;
  16.     }
  17.     public Integer getPageSize() {
  18.         return pageSize;
  19.     }
  20.     public void setPageSize(Integer pageSize) {
  21.         this.pageSize = pageSize;
  22.     }
  23.     public Integer getStartNum() {
  24.         return startNum;
  25.     }
  26.     public void setStartNum(Integer startNum) {
  27.         this.startNum = startNum;
  28.     }
  29. }
复制代码
  MtypeQuery专门用来处置惩罚分页,继承前端传来的参数.
  继承了Mtype-->可以封装上tname
  要知道前端用户想看第几页:pagNo
  开始行号是盘算出来的
  想要得到分页查询的数据,须要在数据库中查询到详细信息和数量,末了通过在实现类中编写详细方法逻辑将数据包装进一个Page对象中返回
在MtypeMapper.xml下须要编写sql语句如下:
查询出全部数据和数量并界说查询效果resultMap:
  1. <resultMap id="BaseResultMap" type="com.qcby.model.Mtype">
  2.     <id column="TID" jdbcType="INTEGER" property="tid" />
  3.     <result column="TNAME" jdbcType="VARCHAR" property="tname" />
  4.     <result column="TDESC" jdbcType="VARCHAR" property="tdesc" />
  5.   </resultMap>
  6. <select id="selectPage" parameterType="com.qcby.query.MtypeQuery" resultMap="BaseResultMap">
  7.     SELECT * FROM mtype
  8.     <where>
  9.       <if test=" tname != null and tname != ''">
  10.         tname like '%${tname}%'
  11.       </if>
  12.     </where>
  13.     LIMIT #{startNum},#{pageSize}
  14.   </select>
  15.   
  16.   <select id="selectCount" parameterType="com.qcby.query.MtypeQuery" resultType="int">
  17.     SELECT count(*) FROM mtype
  18.     <where>
  19.       <if test=" tname != null and tname != ''"> tname like '%${tname}%' </if>
  20.     </where>
  21.   </select>
  22.   <select id="selectAll" resultType="com.qcby.model.Mtype">
  23.     SELECT * from mtype
  24.   </select>
复制代码
写好了sql语句下面就须要界说接口和方法来调用sql语句
由于每个模块中都要用到分页查询,因此编写接口和方法时写在公共方法即可;
在BaseDao接口中界说长期层接口
  1. /**
  2. * 持久层公共接口
  3. * @param <T>
  4. */
  5. public interface BaseDao<Q,T> {
  6.     //省略其他方法...
  7.    
  8.     List<T> selectPage(Q mq);      
  9.     Integer selectCount(Q mq);
  10. }
复制代码
在BaseService中提供相应的分页查询接口:
  1. /**
  2. * 业务层公共接口
  3. * @param <T> 泛型
  4. */
  5. public interface BaseService<Q,T> {
  6.    
  7.     //分页查询接口
  8.     Page<T> selectByPage(Q mq);
  9. }
复制代码
实现类:在实现类中编写分页查询的详细逻辑
先通过反射获取pageNo和pageSize,并根据此盘算出startNum
之后通过长期层接口调用sql语句查询数据库,末了将查询到的效果放入Page对象中
  1. public class BaseServiceImpl<Q,T> implements BaseService<Q,T> {
  2.     protected BaseDao<Q,T> baseDao;
  3.    
  4.     /**
  5.      * 多有业务模块的分页业务逻辑处理
  6.      * 简单理解:page对象
  7.      * 保证page对象各个属性的值按要求返回
  8.      * @param mq
  9.      * @return
  10.      */
  11.     @Override
  12.     public Page<T> selectByPage(Q mq){
  13.         //1.先准备一个要返回的承载数据的页对象
  14.         Page<T> page = new Page<T>();        
  15.         Class<?> cq = mq.getClass();
  16.         try {
  17.             //反射调用getPageNo方法拿到pageNo
  18.             //获得getPageNo对象
  19.             Method getPageNo = cq.getDeclaredMethod("getPageNo", null);
  20.             //反射调用getPageNo方法
  21.             Integer pageNo = (Integer) getPageNo.invoke(mq,null) ;
  22.             //反射调用getPageNo方法拿到pageSize
  23.             Method getPageSize = cq.getDeclaredMethod("getPageSize", null);
  24.             Integer pageSize = (Integer) getPageSize.invoke(mq,null) ;
  25.             //给返回的page设置值
  26.             page.setPageNo(pageNo);
  27.             page.setPageSize(pageSize);
  28.             //设置pageNO  前端给的
  29.             //设置pageSize  前端给的
  30.             //设置startNum  计算
  31.             Method setStartNum = cq.getDeclaredMethod("setStartNum",Integer.class);
  32.             setStartNum.invoke(mq,(pageNo-1)*pageSize);
  33.             page.setStartNum((pageNo-1)*pageSize);
  34.             //查询数据库 调用Mapper baseDao查询满足条件的数据
  35.             List<T> list = baseDao.selectPage(mq);
  36.             page.setList(list);
  37.             //StartNum tname  把结果给page的list设置上
  38.             //查询数据库 满足条件的数据总量 page的totalCount设置上值
  39.             Integer count=baseDao.selectCount(mq);
  40.             page.setTotalCount(count);
  41.         }catch (Exception e){
  42.             e.printStackTrace();
  43.         }
  44.         return page;
  45.     }
  46. }
复制代码
至此分页查询的接口和方法编写完毕,接下来就可以在配景模块ham-console的控制类中调用该方法查询到想要的数据并将其返回。
编写MtypeController类:
  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.ui.Model;
  4. import org.springframework.web.bind.annotation.PostMapping;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.ResponseBody;
  7. /**
  8. * @Controller将该类交spring管理设为控制类
  9. * @RequestMapping("/mtype") 设置路径来让前端调用
  10. */
  11. @RequestMapping("/mtype")
  12. @Controller
  13. public class MtypeController {
  14.     /**
  15.      * 注入流派业务层的对象
  16.      * 调用业务层的分页条件查询逻辑
  17.      */
  18.     @Autowired
  19.     private MtypeService mtypeService;
  20.     /**
  21.      * 查询流派信息
  22.      * 分页   条件   查询
  23.      * 流派名称 查看的页码 每页展示数量
  24.      * @return
  25.      */
  26.     @RequestMapping("/list")
  27.     public String list(MtypeQuery mq, Model model){
  28.         //1.程序严谨性:判断前端传递的参数
  29.         //有没有传递想看第几页,没有设计为访问第一页
  30.         if(mq.getPageNo()==null){
  31.             mq.setPageNo(1);
  32.         }
  33.         //2.调用业务层进行分页条件查询
  34.         Page<Mtype> page = mtypeService.selectByPage(mq);
  35.         //3.返回前端想要的数据  返回一个页对象
  36.         model.addAttribute("page",page);
  37.         //要进行搜索参数的回显功能
  38.         model.addAttribute("mq",mq);
  39.         return "mtype";
  40.     }
  41. }
复制代码
2、流派的添加

使用layui的弹出层,点击“添加流派”按钮,弹出层弹出,如图:



  • 添加流派按钮:
  1. <button id="addSong" class="btn btn-primary" data-target="#myModal2"
  2.         type="button">添加流派
  3. </button>
复制代码


  • 弹出层表单元素:
  1. <div id="mtypePop" style="margin-right: 50px;margin-top: 50px; display: none">
  2.     <form id="addMtypeForm" class="layui-form" method="post" action="/mtype/addMtype" lay-filter="example">
  3.         <div class="layui-form-item">
  4.             <label class="layui-form-label">流派</label>
  5.             <div class="layui-input-block">
  6.                 <input type="text" name="tname" style="color: black;" lay-verify="title" autocomplete="off"
  7.                        placeholder="请输入流派名" class="layui-input">
  8.             </div>
  9.         </div>
  10.         <div class="layui-form-item layui-form-text">
  11.             <label class="layui-form-label">描述</label>
  12.             <div class="layui-input-block">
  13.                 <textarea style="color: black;" placeholder="请输入流派描述" class="layui-textarea" name="tdesc"></textarea>
  14.             </div>
  15.         </div>
  16.         <div class="layui-form-item">
  17.             <div class="layui-input-block">
  18.                 <button class="layui-btn layui-btn-normal layui-btn-radius" lay-submit="" lay-filter="demo1">添加流派
  19.                 </button>
  20.             </div>
  21.         </div>
  22.     </form>
  23. </div>
复制代码


  • JS弹出界面:
点击addSong按钮,创建弹出层,内容是id为“mtypePop”的元素
  1. var pop;
  2. $("#addSong").click(function () {
  3.     pop = layer.open({
  4.         type: 1,
  5.         area: [600, 350],
  6.         content: $('#mtypePop')
  7.     });
  8. })
复制代码


  • 表单提交
添加弹出层也是表单,在JS中编写点击确认后表单提交,调用后端方法
  1. layui.use('form', function () {
  2.     var form = layui.form;
  3.     //监听提交
  4.     form.on('submit(demo1)', function (data) {
  5.         //layer.msg(JSON.stringify(data.field));
  6.         $.ajax({
  7.             url: "/mtype/addMtype",
  8.             type: "post",
  9.             data: data.field,
  10.             dataType: "text",
  11.             success: function (text) {
  12.                 if (text == "success") {
  13.                     layer.msg("添加成功");
  14.                     layer.close(pop);
  15.                 }
  16.             }
  17.         })
  18.         //阻止页面跳转  防止同步提交  使用ajax异步提交表单
  19.         return false;
  20.     });
复制代码


  • 配景controller:
  1. @RequestMapping("/addMtype")
  2. @ResponseBody
  3. public String addMtype(Mtype mtype){
  4.     mtypeService.insert(mtype);
  5.     return  "success";
  6. }
复制代码
3、流派的修改

点击“修改”按钮,弹出弹出层,表现原有数据,如图:



  • 修改按钮:
  1. <button  class="btn btn-sm btn-primary" type="button" modify tid="${mtype.tid}" > 修改</button>
复制代码


  • 弹出层div元素:
  1. <div id="mtypePop1" style="margin-right: 50px;margin-top: 50px; display: none">
  2.     <form id="updateMtypeForm" class="layui-form" method="post" action="/mtype/updateMtype" lay-filter="example">
  3.         <input type="hidden" name="tid" id="tid">
  4.         <div class="layui-form-item">
  5.             <label class="layui-form-label">输入框</label>
  6.             <div class="layui-input-block">
  7.                 <input id="ptname" type="text" name="tname" style="color: black;" lay-verify="title" autocomplete="off"
  8.                        placeholder="请输入流派名" class="layui-input">
  9.             </div>
  10.         </div>
  11.         <div class="layui-form-item layui-form-text">
  12.             <label class="layui-form-label">文本域</label>
  13.             <div class="layui-input-block">
  14.                 <textarea id="ptdesc" style="color: black;" placeholder="请输入流派描述" class="layui-textarea"
  15.                           name="tdesc"></textarea>
  16.             </div>
  17.         </div>
  18.         <div class="layui-form-item">
  19.             <div class="layui-input-block">
  20.                 <button class="layui-btn layui-btn-normal layui-btn-radius" lay-submit="" lay-filter="demo2">修改流派
  21.                 </button>
  22.             </div>
  23.         </div>
  24.     </form>
  25. </div>
复制代码


  • 弹出层的数据回显:
点击带有“modify”类的元素的时间,实行函数,获取所点击的元素的tid,发送ajax哀求,将tid作为哀求参数发送到服务器,哀求json范例的数据,回调函数在哀求乐成后实行,使用返回的 JSON 数据来添补表单字段。ID 为 mtypePop1 的 HTML 元素作为弹出层的内容。
  1. var pop1;
  2. $("[modify]").click(function () {
  3.     var tid = $(this).attr("tid");
  4.     $.ajax({
  5.         url: "/mtype/getMtype",
  6.         type: "post",
  7.         data: {
  8.             tid:tid
  9.         },
  10.         dataType: "json",
  11.         success: function (jsonObj) {
  12.             $("#tid").val(jsonObj.tid);
  13.             $("#ptname").val(jsonObj.tname);
  14.             $("#ptdesc").val(jsonObj.tdesc);
  15.         }
  16.     })
  17.     pop1 = layer.open({
  18.         type: 1,
  19.         area: [600, 350],
  20.         content: $('#mtypePop1')
  21.     });
  22. })
复制代码


  • 点击修改按钮后完成修改
  1. layui.use('form', function () {
  2.     var form = layui.form;
  3.     //监听提交
  4.     form.on('submit(demo2)', function (data) {
  5.         //layer.msg(JSON.stringify(data.field));
  6.         $.ajax({
  7.             url: "/mtype/updateMtype",
  8.             type: "post",
  9.             data: data.field,
  10.             dataType: "text",
  11.             success: function (text) {
  12.                 if (text == "success") {
  13.                     layer.msg("修改成功");
  14.                     layer.close(pop1);
  15.                     $("#txForm").submit();
  16.                 }
  17.             }
  18.         })
  19.         return false;
  20.     });
  21. })
复制代码


  • 在MtypeController中编写回显方法和修改方法
  1. /**
  2. * 流派修改  回显数据
  3. */
  4. @ResponseBody
  5. @PostMapping("/getMtype")
  6. public Mtype getMtype(int tid){
  7.     Mtype mtype=mtypeService.selectByPrimaryKey(tid);
  8.     return mtype;
  9. }
  10. @ResponseBody
  11. @PostMapping("/updateMtype")
  12. public String updateMtype(Mtype mt){
  13.     mtypeService.updateByPrimaryKeySelective(mt);
  14.     return "success";
复制代码
4、流派的删除

点击删除按钮,弹出提示框。



  • 删除按钮
  1. <button data-toggle="button" class="btn btn-sm btn-warning" tid="${mtype.tid}"> 删除</button>
复制代码


  • JS
  1. $(".btn-warning").click(function () {
  2.     //获取tid
  3.     var tid = $(this).attr("tid");
  4.     layer.confirm('是否确认删除?', {icon: 3, title:'提示'}, function(index){
  5.         $.ajax({
  6.             url: "/mtype/delMtype",
  7.             type: "post",
  8.             data: {
  9.                 tid:tid
  10.             },
  11.             dataType: "text",
  12.             success: function (text) {
  13.                 if (text == "success") {
  14.                     layer.msg("删除成功");
  15.                     layer.close(index);
  16.                     $("#txForm").submit();
  17.                 }
  18.             }
  19.         })
  20.     });
  21. })
复制代码


  • controller
  1. @RequestMapping("/delMtype")
  2. @ResponseBody
  3. public String delMtype(int tid){
  4.     mtypeService.deleteByPrimaryKey(tid);
  5.     return "success";
  6. }
复制代码
至此,配景流派模块编写完毕,下一篇举行专辑模块的开辟。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表