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

目录

1、流派搜索与分页

2、流派的添加

3、流派的修改

4、流派的删除


接上篇:ssm实战项目──哈米音乐(一),我们完成了项目的整体搭建,接下来进行后台模块的开发。

首先是流派模块:

在该模块中采用分页查询,将数据库中流派的信息通过分页进行查询,期望查询结果如下:

1、流派搜索与分页

想要达成该效果需要在后端查询到的数据呈现到前端的jsp页面上。

首先在后端中要把查询结果包装到一起,因此在ham-core子模块中的util文件夹下创建Page类来存放查询到的数据,该类包括每页展示数量(已知),当前的页号,总页数,开始页数,数据集合结果和总记录数。使用该类的一个对象将其返回到前端界面即可。

该类信息如下:

/*** 封装前端需要的承载数据以及分页相关的一个实体* 自定义页的类*/
public class Page<T> {//每页展示数量(已知)private Integer pageSize=5;//页码(已知)private Integer pageNo=1;//总页数(计算)  总记录数/每页展示数量private Integer totalPage;//开始行号(计算)(pageNO-1) *pagesizeprivate Integer startNum=0;//数据集合结果private List<T> list;//总记录数 count(*)private Integer totalCount=0;public Integer getPageSize() {return pageSize;}public void setPageSize(Integer pageSize) {this.pageSize = pageSize;}public Integer getPageNo() {return pageNo;}public void setPageNo(Integer pageNo) {this.pageNo = pageNo;}public Integer getTotalPage() {totalPage=totalCount/pageSize;if(totalCount==0 || totalCount%pageSize!=0){totalPage++;}return totalPage;}public void setTotalPage(Integer totalPage) {this.totalPage = totalPage;}public Integer getStartNum() {return startNum;}public void setStartNum(Integer startNum) {this.startNum = startNum;}public List<T> getList() {return list;}public void setList(List<T> list) {this.list = list;}public Integer getTotalCount() {return totalCount;}public void setTotalCount(Integer totalCount) {this.totalCount = totalCount;}}

将后端查询到的实体返回前端界面,在jsp界面中采用foreach进行接收,代码如下:

<tbody>
<c:forEach items="${page.list}" var="mtype" varStatus="status"><tr><td class="hidden-xs-portrait">${mtype.tid}</td><td class="hidden-xs-portrait">${mtype.tname}</td><td class="hidden-xs"> ${mtype.tdesc} </td><td><button  class="btn btn-sm btn-primary" type="button" modify tid="${mtype.tid}" > 修改</button><button data-toggle="button" class="btn btn-sm btn-warning" tid="${mtype.tid}"> 删除</button></td></tr>
</c:forEach>
</tbody><jsp:include page="pagination.jsp"></jsp:include>

为节省代码,将分页的页码单独写一个界面pagination.jsp,并在其他界面中引用:

<div class="clearfix text-right"><%--隐藏域--%><input type="hidden" id="pageNo" name="pageNo" value="${mq.pageNo}"><input type="hidden" id="totalPage" value="${page.totalPage}"><ul class="pagination no-margin"><li id="prev" class="disabled"><a href="#">Prev</a></li><c:forEach begin="1" end="${page.totalPage}" var="myPageNo"><li <c:if test="${myPageNo == mq.pageNo}">class="active"</c:if>><apageNoButton href="#">${myPageNo}</a></li></c:forEach><li id="next"><a href="#">Next</a></li></ul>
</div>

在界面中使用js来控制分页:

/*** 用于控制上一页和下一页的可用的切换* @type {jQuery}*/var pageNo = $("#pageNo").val();var totalPage = $("#totalPage").val();pageNo = parseInt(pageNo);totalPage = parseInt(totalPage);if (pageNo == 1 && pageNo == totalPage) {$("#prev").addClass("disabled");$("#next").addClass("disabled");}if (pageNo == 1 && pageNo < totalPage) {$("#prev").addClass("disabled");$("#next").removeClass("disabled");}if (pageNo > 1 && pageNo < totalPage) {$("#prev").removeClass("disabled");$("#next").removeClass("disabled");}if (pageNo > 1 && pageNo == totalPage) {$("#prev").removeClass("disabled");$("#next").addClass("disabled");}$("#prev").click(function () {$("#pageNo").val(--pageNo);$("#txForm").submit();})$("#next").click(function () {$("#pageNo").val(++pageNo);$("#txForm").submit();})$("a[pageNoButton]").click(function () {var pageNo = $(this).html();$("#pageNo").val(pageNo);$("#txForm").submit();})

想要分页查询到流派信息还需要一个流派查询的类,封装前端传来的参数传给后端,例如当前是第几页,要实现搜素功能时要传递的名字

在ham-core的query文件下创建该类如下:

/*** 只作为表现层接收前端参数封装使用*/
public class MtypeQuery extends Mtype{//页码private Integer pageNo;//每页展示数量private Integer pageSize=5;//开始行号private Integer startNum;public Integer getPageNo() {return pageNo;}public void setPageNo(Integer pageNo) {this.pageNo = pageNo;}public Integer getPageSize() {return pageSize;}public void setPageSize(Integer pageSize) {this.pageSize = pageSize;}public Integer getStartNum() {return startNum;}public void setStartNum(Integer startNum) {this.startNum = startNum;}
}

MtypeQuery专门用来处理分页,接受前端传来的参数.

继承了Mtype-->可以封装上tname

要知道前端用户想看第几页:pagNo

开始行号是计算出来的

想要得到分页查询的数据,需要在数据库中查询到具体信息和数量,最后通过在实现类中编写具体方法逻辑将数据包装进一个Page对象中返回

在MtypeMapper.xml下需要编写sql语句如下:

查询出所有数据和数量并定义查询结果resultMap:

 <resultMap id="BaseResultMap" type="com.qcby.model.Mtype"><id column="TID" jdbcType="INTEGER" property="tid" /><result column="TNAME" jdbcType="VARCHAR" property="tname" /><result column="TDESC" jdbcType="VARCHAR" property="tdesc" /></resultMap><select id="selectPage" parameterType="com.qcby.query.MtypeQuery" resultMap="BaseResultMap">SELECT * FROM mtype<where><if test=" tname != null and tname != ''">tname like '%${tname}%'</if></where>LIMIT #{startNum},#{pageSize}</select><select id="selectCount" parameterType="com.qcby.query.MtypeQuery" resultType="int">SELECT count(*) FROM mtype<where><if test=" tname != null and tname != ''"> tname like '%${tname}%' </if></where></select><select id="selectAll" resultType="com.qcby.model.Mtype">SELECT * from mtype</select>

写好了sql语句下面就需要定义接口和方法来调用sql语句

由于每个模块中都要用到分页查询,因此编写接口和方法时写在公共方法即可;

在BaseDao接口中定义持久层接口


/*** 持久层公共接口* @param <T>*/
public interface BaseDao<Q,T> {//省略其他方法...List<T> selectPage(Q mq);      Integer selectCount(Q mq);
}

在BaseService中提供相应的分页查询接口:


/*** 业务层公共接口* @param <T> 泛型*/
public interface BaseService<Q,T> {//分页查询接口Page<T> selectByPage(Q mq);
}

实现类:在实现类中编写分页查询的具体逻辑

先通过反射获取pageNo和pageSize,并根据此计算出startNum

之后通过持久层接口调用sql语句查询数据库,最后将查询到的结果放入Page对象中

public class BaseServiceImpl<Q,T> implements BaseService<Q,T> {protected BaseDao<Q,T> baseDao;/*** 多有业务模块的分页业务逻辑处理* 简单理解:page对象* 保证page对象各个属性的值按要求返回* @param mq* @return*/@Overridepublic Page<T> selectByPage(Q mq){//1.先准备一个要返回的承载数据的页对象Page<T> page = new Page<T>();        Class<?> cq = mq.getClass();try {//反射调用getPageNo方法拿到pageNo//获得getPageNo对象Method getPageNo = cq.getDeclaredMethod("getPageNo", null);//反射调用getPageNo方法Integer pageNo = (Integer) getPageNo.invoke(mq,null) ;//反射调用getPageNo方法拿到pageSizeMethod getPageSize = cq.getDeclaredMethod("getPageSize", null);Integer pageSize = (Integer) getPageSize.invoke(mq,null) ;//给返回的page设置值page.setPageNo(pageNo);page.setPageSize(pageSize);//设置pageNO  前端给的//设置pageSize  前端给的//设置startNum  计算Method setStartNum = cq.getDeclaredMethod("setStartNum",Integer.class);setStartNum.invoke(mq,(pageNo-1)*pageSize);page.setStartNum((pageNo-1)*pageSize);//查询数据库 调用Mapper baseDao查询满足条件的数据List<T> list = baseDao.selectPage(mq);page.setList(list);//StartNum tname  把结果给page的list设置上//查询数据库 满足条件的数据总量 page的totalCount设置上值Integer count=baseDao.selectCount(mq);page.setTotalCount(count);}catch (Exception e){e.printStackTrace();}return page;}
}

至此分页查询的接口和方法编写完毕,接下来就可以在后台模块ham-console的控制类中调用该方法查询到想要的数据并将其返回。

编写MtypeController类:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;/*** @Controller将该类交spring管理设为控制类* @RequestMapping("/mtype") 设置路径来让前端调用*/
@RequestMapping("/mtype")
@Controller
public class MtypeController {/*** 注入流派业务层的对象* 调用业务层的分页条件查询逻辑*/@Autowiredprivate MtypeService mtypeService;/*** 查询流派信息* 分页   条件   查询* 流派名称 查看的页码 每页展示数量* @return*/@RequestMapping("/list")public String list(MtypeQuery mq, Model model){//1.程序严谨性:判断前端传递的参数//有没有传递想看第几页,没有设计为访问第一页if(mq.getPageNo()==null){mq.setPageNo(1);}//2.调用业务层进行分页条件查询Page<Mtype> page = mtypeService.selectByPage(mq);//3.返回前端想要的数据  返回一个页对象model.addAttribute("page",page);//要进行搜索参数的回显功能model.addAttribute("mq",mq);return "mtype";}
}

2、流派的添加

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

  • 添加流派按钮:
<button id="addSong" class="btn btn-primary" data-target="#myModal2"type="button">添加流派
</button>
  • 弹出层表单元素:
<div id="mtypePop" style="margin-right: 50px;margin-top: 50px; display: none"><form id="addMtypeForm" class="layui-form" method="post" action="/mtype/addMtype" lay-filter="example"><div class="layui-form-item"><label class="layui-form-label">流派</label><div class="layui-input-block"><input type="text" name="tname" style="color: black;" lay-verify="title" autocomplete="off"placeholder="请输入流派名" class="layui-input"></div></div><div class="layui-form-item layui-form-text"><label class="layui-form-label">描述</label><div class="layui-input-block"><textarea style="color: black;" placeholder="请输入流派描述" class="layui-textarea" name="tdesc"></textarea></div></div><div class="layui-form-item"><div class="layui-input-block"><button class="layui-btn layui-btn-normal layui-btn-radius" lay-submit="" lay-filter="demo1">添加流派</button></div></div></form>
</div>
  • JS弹出界面:

点击addSong按钮,创建弹出层,内容是id为“mtypePop”的元素

var pop;
$("#addSong").click(function () {pop = layer.open({type: 1,area: [600, 350],content: $('#mtypePop')});
})
  • 表单提交

添加弹出层也是表单,在JS中编写点击确认后表单提交,调用后端方法

layui.use('form', function () {var form = layui.form;//监听提交form.on('submit(demo1)', function (data) {//layer.msg(JSON.stringify(data.field));$.ajax({url: "/mtype/addMtype",type: "post",data: data.field,dataType: "text",success: function (text) {if (text == "success") {layer.msg("添加成功");layer.close(pop);}}})//阻止页面跳转  防止同步提交  使用ajax异步提交表单return false;});
  • 后台controller:
@RequestMapping("/addMtype")
@ResponseBody
public String addMtype(Mtype mtype){mtypeService.insert(mtype);return  "success";
}

3、流派的修改

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

  • 修改按钮:
<button  class="btn btn-sm btn-primary" type="button" modify tid="${mtype.tid}" > 修改</button>
  • 弹出层div元素:
<div id="mtypePop1" style="margin-right: 50px;margin-top: 50px; display: none"><form id="updateMtypeForm" class="layui-form" method="post" action="/mtype/updateMtype" lay-filter="example"><input type="hidden" name="tid" id="tid"><div class="layui-form-item"><label class="layui-form-label">输入框</label><div class="layui-input-block"><input id="ptname" type="text" name="tname" style="color: black;" lay-verify="title" autocomplete="off"placeholder="请输入流派名" class="layui-input"></div></div><div class="layui-form-item layui-form-text"><label class="layui-form-label">文本域</label><div class="layui-input-block"><textarea id="ptdesc" style="color: black;" placeholder="请输入流派描述" class="layui-textarea"name="tdesc"></textarea></div></div><div class="layui-form-item"><div class="layui-input-block"><button class="layui-btn layui-btn-normal layui-btn-radius" lay-submit="" lay-filter="demo2">修改流派</button></div></div></form>
</div>
  • 弹出层的数据回显:

点击带有“modify”类的元素的时候,执行函数,获取所点击的元素的tid,发送ajax请求,将tid作为请求参数发送到服务器,请求json类型的数据,回调函数在请求成功后执行,使用返回的 JSON 数据来填充表单字段。ID 为 mtypePop1 的 HTML 元素作为弹出层的内容。

var pop1;
$("[modify]").click(function () {var tid = $(this).attr("tid");$.ajax({url: "/mtype/getMtype",type: "post",data: {tid:tid},dataType: "json",success: function (jsonObj) {$("#tid").val(jsonObj.tid);$("#ptname").val(jsonObj.tname);$("#ptdesc").val(jsonObj.tdesc);}})pop1 = layer.open({type: 1,area: [600, 350],content: $('#mtypePop1')});
})
  • 点击修改按钮后完成修改
layui.use('form', function () {var form = layui.form;//监听提交form.on('submit(demo2)', function (data) {//layer.msg(JSON.stringify(data.field));$.ajax({url: "/mtype/updateMtype",type: "post",data: data.field,dataType: "text",success: function (text) {if (text == "success") {layer.msg("修改成功");layer.close(pop1);$("#txForm").submit();}}})return false;});
})
  • 在MtypeController中编写回显方法和修改方法
/*** 流派修改  回显数据*/
@ResponseBody
@PostMapping("/getMtype")
public Mtype getMtype(int tid){Mtype mtype=mtypeService.selectByPrimaryKey(tid);return mtype;
}@ResponseBody
@PostMapping("/updateMtype")
public String updateMtype(Mtype mt){mtypeService.updateByPrimaryKeySelective(mt);return "success";

4、流派的删除

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

  • 删除按钮
<button data-toggle="button" class="btn btn-sm btn-warning" tid="${mtype.tid}"> 删除</button>
  • JS
$(".btn-warning").click(function () {//获取tidvar tid = $(this).attr("tid");layer.confirm('是否确认删除?', {icon: 3, title:'提示'}, function(index){$.ajax({url: "/mtype/delMtype",type: "post",data: {tid:tid},dataType: "text",success: function (text) {if (text == "success") {layer.msg("删除成功");layer.close(index);$("#txForm").submit();}}})});
})
  • controller
@RequestMapping("/delMtype")
@ResponseBody
public String delMtype(int tid){mtypeService.deleteByPrimaryKey(tid);return "success";
}

至此,后台流派模块编写完毕,下一篇进行专辑模块的开发。

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

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

相关文章

STM32的中断(什么是外部中断和其他中断以及中断号是什么)

一、什么是EXTI 和NVIC EXTI&#xff08;External Interrupt/Event Controller&#xff09;EXTI 是外部中断/事件控制器&#xff0c;它负责处理外部信号变化&#xff0c;并将信号传递给中断控制器&#xff08;如 NVIC&#xff09;。主要负责以下功能&#xff1a; 外部事件检测…

5、AI测试辅助-生成测试用例思维导图

AI测试辅助-生成测试用例思维导图 创建测试用例两种方式1、Plantuml思维导图版本 (不推荐&#xff09;2、Markdown思维导图版本&#xff08;推荐&#xff09; 创建测试用例两种方式 完整的测试用例通常需要包含以下的元素&#xff1a; 1、测试模块 2、测试标题 3、前置条件 4、…

IDEA 2024安装指南(含安装包以及使用说明 cannot collect jvm options 问题 四)

汉化 setting 中选择插件 完成 安装出现问题 1.可能是因为之前下载过的idea&#xff0c;找到连接中 文件&#xff0c;卸载即可。

js+jquery实现经典推箱子游戏

纯前端项目&#xff0c;只使用html,css,js,jquery实现经典推箱子游戏&#xff0c;直接下载本地双击index.html即可运行体验。 游戏展示 开始界面 完成游戏 代码展示

《文件操作》

一 . 文本文件和二进制文件 根据数据的组织形式&#xff0c;数据文件被分为了二进制文件和文本文件 数据在内存中是以二进制的形式存储&#xff0c;如果不加转换的输出到外存的文件中&#xff0c;就是二进制文件。 如果要求在外存上以ASCII 码的形式存储&#xff0c;则需要再存…

监控报警系统的指标、规则与执行闭环

随笔 从千万粉丝“何同学”抄袭开源项目说起&#xff0c;为何纯技术死路一条&#xff1f; 数据源的统一与拆分 监控报警系统的指标、规则与执行闭环 java 老矣&#xff0c;尚能饭否&#xff1f; 一骑红尘妃子笑&#xff0c;无人知是荔枝来! 有所依 我们如何知道系统交易…

LLaMA-Mesh: Unifying 3D Mesh Generation with Language Models 论文解读

目录 一、概述 二、相关工作 1、LLMs到多模态 2、3D对象生成 3、自回归的Mesh生成 三、LLaMA-Mesh 1、3D表示 2、预训练模型 3、有监督的微调数据集 4、数据集演示 四、实验 1、生成的多样性 2、不同模型text-to-Mesh的比较 3、通用语境的评估 一、概述 该论文首…

【大数据学习 | Spark-Core】Spark提交及运行流程

spark的集群运行结构 我们要选择第一种使用方式 命令组成结构 spark-submit [选项] jar包 参数 standalone集群能够使用的选项。 --master MASTER_URL #集群地址 --class class_name #jar包中的类 --executor-memory MEM #executor的内存 --executor-cores NUM # executor的…

ES6 、ESNext 规范、编译工具babel

ES6 、ESNext 规范、编译工具简介 ES6ES&#xff08;ECMAScript&#xff09; vs JS常量进一步探讨 obj对象的扩展面试&#xff1a;使对象属性也不能更改——Object.freeze(obj) 解构deconstruction变量的解构赋值&#xff1a;数组解构赋值&#xff1a;对象解构赋值&#xff1a;…

【MyBatis】全局配置文件—mybatis.xml 创建xml模板

文章目录 模板文件配置元素typeAliasessettings 模板文件 创建模板 按照顺序打开【File】–>【settings】–>【Editor】–>【File and Code Templates】&#xff08;或直接搜索&#xff09; <?xml version"1.0" encoding"UTF-8" ?> <…

小程序免备案:快速部署与优化的全攻略

小程序免备案为开发者提供了便捷高效的解决方案&#xff0c;省去繁琐的备案流程&#xff0c;同时通过优化网络性能和数据传输&#xff0c;保障用户体验。本文从部署策略、应用场景到技术实现&#xff0c;全面解析小程序免备案的核心优势。 小程序免备案&#xff1a;快速部署与优…

【数据结构】—— 线索二叉树

引入 我们现在提倡节约型杜会&#xff0c; 一切都应该节约为本。对待我们的程序当然也不例外&#xff0c;能不浪费的时间或空间&#xff0c;都应该考虑节省。我们再观察团下图的二叉树&#xff08;链式存储结构)&#xff0c;会发现指针域并不是都充分的利用了&#xff0c;有许…

Outlook for Mac同步错误:The total attachment size exceeds the limit.

现象 mac一直弹出同步错误提示&#xff1a;The total attachment size exceeds the limit. 怎么也去不掉 解决办法 ①清除收件箱和已发送邮件的缓存 ②删除邮箱账号再重新添加

IT服务团队建设与管理

在 IT 服务团队中&#xff0c;需要明确各种角色。例如系统管理员负责服务器和网络设备的维护与管理&#xff1b;软件工程师专注于软件的开发、测试和维护&#xff1b;运维工程师则保障系统的稳定运行&#xff0c;包括监控、故障排除等。通过清晰地定义每个角色的职责&#xff0…

使用树莓派安装shairport-sync使老音响变身AirPlay音响

借助shairport-sync&#xff0c;可以让普通音响变成AirPlay无线音响&#xff0c;由于树莓派天生的低功耗&#xff0c;做这种事情最适合。所以架构就是树莓派安装Ubuntu24.04&#xff0c;在树莓派上安装shairport-sync&#xff0c;树莓派再通过3.5mm线连接音响。 安装Ubuntu24.…

全志T113双核异构处理器的使用基于Tina Linux5.0——RTOS系统定制开发

8、RTOS系统定制开发 此处以在rtos/components/aw目录下创建一个简单的软件包为例&#xff0c;帮助客户了解RTOS环境&#xff0c;为RTOS系统定制开发提供基础。 RTOS环境下的软件包主要由三部分组成&#xff0c;源文件&#xff0c;Makefile&#xff0c;Kconfig&#xff0c;如下…

用CAXA CAD电子图板导入图框、标题栏并导出pdf的方法

1.导入图框&#xff1a; 点击调入图框->出现读入图框文件 一个一个点击&#xff0c;选择合适的图框 然后点击导入 2.导入标题栏&#xff1a; 调入标题栏->出现读入标题栏文件 一个一个点击&#xff0c;选择合适的标题栏&#xff0c;然后点击导入 3.导出pdf&#x…

【Linux 篇】Docker 启动和停止的精准掌舵:操控指南

文章目录 【Linux 篇】Docker 启动和停止的精准掌舵&#xff1a;操控指南前言docker基本命令1. 帮助手册 2. 指令介绍 常用命令1. 查看镜像2. 搜索镜像3. 拉取镜像4. 删除镜像5. 从Docker Hub拉取 容器的相关命令1. 查看容器2. 创建与启动容器3. 查看镜像4. 启动容器5. 查看容…

Java---反射机制

JAVA反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c; 都能够调用它的任意方法和属性&#xff1b;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。 在编译后产生…