该后台管理系统是用于管理视频网站数据的,目前分5个菜单项,这篇博客主要讲述【影片管理】的具体功能和实现

后台代码结构和【影片管理】的界面如下图


该界面分为上下2部分,【搜索条件】和【影片列表】,2部分所用到的字段都在【Video】实体类中,具体代码如下

package me.xiaomaju.entity;

import lombok.Data;

@Data
public class Video { //表sys_video字段
private String id_video;
private String name_video;
private String describe;
private String image;
private int id_state;
private String id_area;
private String dt_show; //关联sys_type查询,拼接
private String type;
//关联sys_state查询
private String name_state;
//关联sys_area查询
private String area; //查询条件 page和limit要和LayUI的数据表格参数一致
private Integer page;//当前页码
private Integer limit;//每页显示数量 private String dt_begin;
private String dt_end;
private String id_type; }

视频表【sys_video】、状态表【sys_state】、地区表【sys_area】、类型表【sys_type】的表结构如下图


LayUI官网于2021年10月左右关闭,查看LayUI相关文档可以到 https://lln.kim/layui/index.html

【影片管理】明显用到LayUI的表单模块和数据表格模块,前端页面代码如下

<div style="width: 80% ">
<!-- 搜索表单 -->
<div>
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 10px;">
<legend>搜索条件</legend>
</fieldset>
<form class="layui-form layui-form-pane" method="post" style="text-align: center"> <div class="layui-inline">
<label class="layui-form-label">名称</label>
<div class="layui-input-inline">
<input type="text" name="name_video" required placeholder="请输入名称" class="layui-input">
</div>
</div> <div class="layui-inline">
<label class="layui-form-label">类型</label>
<div class="layui-input-inline">
<select name="id_type" id="select_type" class="layui-input">
<option value="">请选择类型</option>
</select>
</div>
</div> <div class="layui-inline">
<label class="layui-form-label">上映时间</label>
<div class="layui-input-inline">
<input type="text" name="dt_begin" id="dt_begin" required placeholder=""
class="layui-input">
</div>
</div> <div class="layui-inline">
<label class="layui-form-label">至</label>
<div class="layui-input-inline">
<input type="text" name="dt_end" id="dt_end" required placeholder=""
class="layui-input">
</div>
</div> <div class="layui-inline">
<button type="submit" class="layui-btn" lay-submit lay-filter="doSearch">搜索</button>
</div>
</form>
</div>
<!-- 搜索表单end --> <!-- 数据表格 -->
<div>
<fieldset class="layui-elem-field site-demo-button">
<legend>影片列表</legend>
<div>
<!-- 表格 -->
<table class="layui-hide" id="dataTable" lay-filter="dataTable"></table>
</div>
</fieldset> <!-- 头部工具栏 -->
<script type="text/html" id="topToolbar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="add"><i class="layui-icon layui-icon-add-circle"></i>添加
</button>
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="batchDelete"><i
class="layui-icon layui-icon-delete"></i>批量删除
</button>
</div>
</script>
<!-- 行工具栏 -->
<script type="text/html" id="rowToolbar">
<button class="layui-btn layui-btn-xs" lay-event="edit">编辑</button>
<button class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delete">删除</button>
</script> </div>
<!-- 数据表格end -->
</div>

开始写js代码,后面所有的js代码写在layui.use的 { } 里面。

<script>
layui.use(['form', 'table', 'jquery', 'layer', 'laydate', 'upload'], function () {
var form = layui.form;
var table = layui.table;
var $ = layui.jquery;
var layer = layui.layer;
var laydate = layui.laydate;
var upload = layui.upload; //渲染表格组件
var tableIns = table.render({
elem: "#dataTable",//绑定表格元素,推荐使用ID选择器
url: "${pageContext.request.contextPath}/video/video-list",//异步请求地址,加入分页后,默认使用page(当前页码)和limit(每页显示数量)作为参数名称
page: true,//开启分页
toolbar: "#topToolbar",
cols: [[
{type: "checkbox", fixed: "left", width: 80, align: "center"}
, {field: 'id_video', title: 'ID', align: "center", width: 170}
, {field: 'name_video', title: '名称', align: "center", width: 150}
, {field: 'describe', title: '描述', align: "left", width: 255}
, {field: 'image', title: '封面', align: "center", width: 150}
, {field: 'name_state', title: '状态', align: "center", width: 60}
, {field: 'type', title: '类型', align: "center", width: 140}
, {field: 'area', title: '地区', align: "center", width: 90}
, {field: 'dt_show', title: '上映时间', align: "center", width: 120}
, {title: "操作", toolbar: "#rowToolbar", align: "center", width: 150}
]]
});

})
</script>

通过url获取后台数据渲染数据表格,数据表格的数据要求4个属性,先新建该实体,代码如下

package me.xiaomaju.entity;

import lombok.Data;
import lombok.NoArgsConstructor; @Data
@NoArgsConstructor
public class LayUIDataGridView { private Integer code=0;
private String msg="";
private Long count;
private Object data; /**
* 封装数据表格
* @param count
* @param data
*/
public LayUIDataGridView(Long count, Object data) {
this.count = count;
this.data = data;
} }

接下来通过 url: "${pageContext.request.contextPath}/video/video-list"  写后台代码

controller层代码如下

@Controller
@RequestMapping("/video")
public class VideoController { private static final Logger logger = org.apache.log4j.Logger.getLogger(VideoController.class); @Autowired
private VideoService videoService; @RequestMapping(value = "/video-list")
@ResponseBody
public LayUIDataGridView findAll(Video video) {
//设置分页信息(当前页码,每页条数)
PageHelper.startPage(video.getPage(), video.getLimit());
//查询数据
List<Video> videoList = videoService.findByAttributes(video);
//创建分页对象
PageInfo<Video> pageInfo = new PageInfo<Video>(videoList);
//返回数据
return new LayUIDataGridView(pageInfo.getTotal(), pageInfo.getList());
} }
pagehelper是一个分页插件,在mybatis.xml配置一下即可,配置如下
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 分页合理化参数,默认false,设置为true是,pageNum<=0查第一页,pageNum>pages查最后一页-->
<property name="reasonable" value="true"/>
</plugin>
</plugins>

service层代码如下

@Service
public class VideoServiceImpl implements VideoService { private static final Logger logger = org.apache.log4j.Logger.getLogger(VideoServiceImpl.class); @Autowired
private IVideoMapper videoMapper; @Override
public List<Video> findByAttributes(Video video) {
return videoMapper.findByAttributes(video);
}

}

mapper层代码如下

package me.xiaomaju.mapper;

import me.xiaomaju.entity.Area;
import me.xiaomaju.entity.Type;
import me.xiaomaju.entity.Video;
import org.apache.ibatis.annotations.*; import java.util.List; public interface IVideoMapper { @Select("<script> " +
"select v.id_video, v.name_video,v.describe,v.image,v.id_state,v.id_area, v.dt_show, s.name_state,a.area from sys_video v " +
"left join sys_state s on v.id_state=s.id_state " +
"left join sys_area a on v.id_area=a.id_area " +
" </script> ")
public List<Video> findByAttributes(Video video); }

这样查出了【sys_video】表的所有字段,关联状态和地区表查出具体中文状态和地区。视频与类型则是多对多关系,这种多对多关系的数据用一张中间表来存储。

中间表【sys_video_type】只有2列,id_video和id_type,id_type又是类型表【sys_type】的主键。

所以可以在service层用id_video为入参,查询类型的中文,并将多个类型用逗号拼接在一起,代码如下

    @Override
public List<Video> findByAttributes(Video video) {
List<Video> videoList = videoMapper.findByAttributes(video);
if (videoList.size() < 1)
return null;
//封装类型 type
for (Video _video : videoList) {
List<String> typeList = videoMapper.findVideoType(_video.getId_video());
String type = StringUtil.getListStrs(typeList);
_video.setType(type);
}
return videoList;
}

mapper层查询类型代码如下

    @Select("select t.name_type from sys_type t left join sys_video_type vt ON t.id_type= vt.id_type where vt.id_video=#{id} ")
public List<String> findVideoType(String id);

通过上述表关系在那几张表造一些数据,页面数据表格就有对应数据显示了。


接下来实现上方【搜索条件】的查询功能,效果如下图

其中2个时间项用到了LayUI的日期与时间选择模块,需要进行组件渲染。搜索表单中【类型】下拉框的数据是动态的,后面介绍新增与编辑功能时会将对应js代码写出来。

        //渲染日期组件
laydate.render({
elem: "#dt_begin",
});
laydate.render({
elem: "#dt_end"
});
        //监听搜索按钮提交事件
form.on("submit(doSearch)", function (data) {
tableIns.reload({
where: data.field,//查询条件
page: {
curr: 1
}
});
//禁止页面刷新
return false;
});

需要注意的是,搜索和一开始的数据表格渲染走的是相同的后台代码,即"${pageContext.request.contextPath}/video/video-list"。

搜索表单中的字段都在Video实体中,所以直接在mapper层的代码中新增过滤条件,将原方法修改后的代码如下

    @Select("<script> " +
"select distinct v.id_video, v.name_video,v.describe,v.image,v.id_state,v.id_area, v.dt_show, s.name_state,a.area from sys_video v " +
"left join sys_state s on v.id_state=s.id_state " +
"left join sys_area a on v.id_area=a.id_area " +
"left join sys_video_type vt on v.id_video=vt.id_video " +
" <where> " +
" <if test=\"name_video != null and name_video !='' \"> v.name_video=#{name_video} </if> " +
" <if test=\" id_type != null and id_type !='' \"> and vt.id_type=#{id_type} </if> " +
" <if test=\"dt_begin != null and dt_begin!='' \"> <![CDATA[ and v.dt_show >= #{dt_begin} ]]> </if> " +
" <if test=\"dt_end != null and dt_end!='' \"> <![CDATA[ and v.dt_show <= #{dt_end} ]]> </if> " +
" <if test=\"id_state != 0\"> AND v.id_state=#{id_state}</if> " +
" </where> " +
" </script> ")
public List<Video> findByAttributes(Video video);

 


接下来实现新增和编辑的功能,新增和编辑用的是同一个表单,效果如下图

首先写这个表单的前台代码

<!-- 弹出层 -->
<div id="addOrUpdateCardView" style="display: none;margin: 10px">
<form id="dataForm" method="post" class="layui-form layui-form-pane" lay-filter="dataForm">
<!-- 隐藏域,保存当前ID -->
<input type="hidden" name="id_video"> <div class="layui-form-item">
<label class="layui-form-label">名称</label>
<div class="layui-input-block">
<input type="text" name="name_video" required lay-verify="required|name_video" placeholder="请输入"
autocomplete="off" 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 name="describe" lay-verify="required|describe" class="layui-textarea"></textarea>
</div>
</div> <div class="layui-form-item">
<label class="layui-form-label">封面</label>
<div class="layui-input-block">
<button type="button" class="layui-btn" id="btn-img">上传图片</button>
<img class="layui-upload-img" width="50" height="50">
<!-- 隐藏域,保存后台传回来的图片保存路径 -->
<input type="hidden" id="imgPath" name="image" value="">
</div>
</div> <div class="layui-form-item">
<label class="layui-form-label">地区</label>
<div class="layui-input-block">
<select name="id_area" class="layui-input">
<option value="">请选择地区</option>
</select>
</div>
</div> <div class="layui-form-item">
<label class="layui-form-label">类型</label>
<div class="layui-input-block" id="chkBox_type"> </div>
</div> <div class="layui-form-item">
<label class="layui-form-label">上映时间</label>
<div class="layui-input-block">
<input type="text" name="dt_show" id="dt_show" lay-verify="required|dt_show" placeholder="请输入"
class="layui-input">
</div>
</div> <div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block" id="sexRadio">
<input type="radio" name="id_state" value="1" title="禁用">
<input type="radio" name="id_state" value="2" title="正常" checked>
<input type="radio" name="id_state" value="3" title="热播">
</div>
</div> <div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="doSubmit" id="formSubmit">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div> </form>
</div>
<!-- 弹出层end-->

新增和编辑对应的js代码,【上映日期】需要进行日期组件渲染

        laydate.render({
elem: "#dt_show",
type: "date"//默认
});
        //监听表格头部工具栏事件
table.on("toolbar(dataTable)", function (obj) {
switch (obj.event) {
//添加
case 'add':
openAddWindow();
break;
}
}); //监听表格行工具栏事件
table.on("tool(dataTable)", function (obj) {
switch (obj.event) {
//编辑
case 'edit':
openUpdateWindow(obj.data);
break;
}
});
        var url;//提交地址
var mainIndex;//窗口索引 //打开编辑窗口
function openUpdateWindow(data) { //清空表单数据
$("#dataForm")[0].reset(); //将该行的类型给表单勾选上
var types = data.type.split(",");
var typeCheckbox = $("input:checkbox[name='id_types']");
for (var j = 0; j < types.length; j++) {
for (var i = 0; i < typeCheckbox.length; i++) {
if (typeCheckbox[i].title == types[j]) {
typeCheckbox[i].checked = true;
}
}
form.render(); //更新渲染
} mainIndex = layer.open({
type: 1,//弹出层类型
title: "影片信息修改",
area: ['800px', '600px'],
content: $("#addOrUpdateCardView"),//引用的窗口代码
success: function () {
//表单数据回显
// console.log(data);
form.val("dataForm", data);
//修改请求
url = "${pageContext.request.contextPath}/video/update";
}
});
} //打开添加窗口
function openAddWindow() {
mainIndex = layer.open({
type: 1,//弹出层类型
title: "添加影片",
area: ['800px', '600px'],
content: $("#addOrUpdateCardView"),//引用的窗口代码
success: function () {
//清空表单数据
$("#dataForm")[0].reset();
url = "${pageContext.request.contextPath}/video/add";
}
});
}
//监听弹出层的表单提交事件
form.on("submit(doSubmit)", function (data) { if ($("input:checkbox[name='id_types']:checked").length > 3 || $("input:checkbox[name='id_types']:checked").length < 1) {
layer.msg('类型为必填项,且最多只能选3项!', {icon: 5});
return false;
} //获取checkbox[name='id_types']的值,获取所有选中的复选框,并将其值放入数组中
var arr = new Array();
$("input:checkbox[name='id_types']:checked").each(function (i) {
arr[i] = $(this).val();
});
// 替换 data.field.id_types的数据为拼接后的字符串
data.field.id_types = arr.join(","); $.post(url, data.field, function (result) {
if (result.success) {
layer.alert(result.message, {icon: 1});
//关闭窗口
layer.close(mainIndex);
//刷新数据表格
tableIns.reload();
} else {
layer.alert(result.message, {icon: 2});
}
}, "json");
return false;
});

编辑功能的controller层代码如下

    @RequestMapping(value = "/update", produces = "text/html;charset=UTF-8")
@ResponseBody
public String update(Video video, String[] id_types, HttpSession session) {
Map<String, Object> map = new HashMap<String, Object>();
int result = videoService.update(video); // 先删除类型再新增
int types1 = videoService.deleteVideoType(video.getId_video());
int types = videoService.addVideoType(video.getId_video(), id_types); if (result > 0 && types > 0) {
map.put("success", true);
map.put("message", "修改成功"); Admin admin = (Admin) session.getAttribute("loginAdmin");
logger.info("修改影片的人员为:" + admin.getName_admin() + ";影片ID为:" + video.getId_video());
} else {
map.put("success", false);
map.put("message", "修改失败");
}
return JSON.toJSONString(map);
}

新增功能的controller层代码与编辑类似,新增的是直接新增类型,即往【sys_video_video】插入数据;而编辑需要先删除类型再新增类型,因为【id_types】的长度(表单中类型复选框勾选的数量)不是固定的。

而直接在新增功能的controller层代码中【video.getId_video()】是为空的,需要在mapper层加一个注解,详情见我下一篇博客。

搜索表单中的下拉框【类型】,新增功能和编辑功能的弹出层中的下拉框【地区】和复选框【类型】的数据是动态的,需要向后台发送Ajax请求,js代码如下

        //发送Ajax请求查询类型
$.get("${pageContext.request.contextPath}/video/query-type", function (result) {
var duoxuan = "";
var xiala = "";
//循环遍历集合
for (let i = 0; i < result.length; i++) {
duoxuan += "<input type=\"checkbox\" name=\"id_types\" title='" + result[i].name_type + "' value='" + result[i].id_type + "' lay-skin=\"primary\" lay-verify=\"fuxuan\"> "
xiala += "<option value='" + result[i].id_type + "'>" + result[i].name_type + "</option>"
}
//将网页代码追加到下拉列表和多选框中
$("[id='chkBox_type']").append(duoxuan);
$("[id='select_type']").append(xiala);
//更新渲染select下拉框
form.render("select");
}, "json"); //发送Ajax请求查询地区
$.get("${pageContext.request.contextPath}/video/query-area", function (result) {
var html = "";
//循环遍历集合
for (let i = 0; i < result.length; i++) {
html += "<option value='" + result[i].id_area + "'>" + result[i].area + "</option>"
}
//将网页代码追加到下拉列表中
$("[name='id_area']").append(html);
//更新渲染select下拉框
form.render("select");
}, "json");

后台controller调用service,service 调用mapper查询地区和类型,返回对应实体的List集合即可。

如果你的前端页面和我一样是用jsp写的,不出意料的话,你的复选框显示可能有问题,在<html>标签上面加上 <!DOCTYPE html> 即可。

下面实现弹出层表单中的图片上传功能,js代码如下

        //图片上传
var uploadInst = upload.render({
elem: "#btn-img" /*根据绑定id,打开本地图片*/
, url: "${pageContext.request.contextPath}/video/upload-img" /*上传后台接受接口*/
, done: function (res) {
if (res.success) {
$('#imgPath').attr('value', res.message);
} else {
layer.alert(res.message, {icon: 2});
}
}
});

后台controller层代码如下

    @RequestMapping(value = "/upload-img", produces = "text/html;charset=UTF-8")
@ResponseBody
public String uploadImg(@RequestParam(value = "file", required = false) MultipartFile file, HttpServletRequest request) {
Map<String, Object> map = new HashMap<String, Object>();
String originalFilename = file.getOriginalFilename(); // 获取文件上传名
String path = request.getServletContext().getRealPath("/") +"static\\img\\"+ originalFilename;
logger.info("上传路径:"+path );
try {
file.transferTo(new File(path));
map.put("success", true);
map.put("message", path);
} catch (IOException e) {
map.put("success", false);
map.put("message", "图片上传失败");
}
return JSON.toJSONString(map);
}

如果上传成功,将图片路径传到前台,放到弹出层表单中【封面】后的隐藏域中。


接下来实现行删除和批量删除,效果如下图

新增和批量删除在表格头部工具栏事件监听到,而行删除和编辑在表格行工具栏事件监听到,js代码如下

        //监听表格头部工具栏事件
table.on("toolbar(dataTable)", function (obj) {
switch (obj.event) {
//添加
case 'add':
openAddWindow();
break;
//批量删除
case 'batchDelete':
batchDelete();
break;
}
}); //监听表格行工具栏事件
table.on("tool(dataTable)", function (obj) {
switch (obj.event) {
//编辑
case 'edit':
openUpdateWindow(obj.data);
break;
//删除
case 'delete':
deleteById(obj.data);
break;
}
});
        //单个删除
function deleteById(data) {
//提示用户确认是否删除
layer.confirm('真的要删除吗?', {icon: 3, title: '提示'}, function (index) {
//发送ajax请求
$.post("${pageContext.request.contextPath}/video/deleteById", {"id_video": data.id_video}, function (result) {
if (result.success) {
layer.alert(result.message, {icon: 1});
//刷新数据表格
tableIns.reload();
} else {
layer.alert(result.message, {icon: 2});
}
}, "json");
//关闭提示框
layer.close(index);
});
} //批量删除
function batchDelete() {
//获取表格对象
var checkStatus = table.checkStatus('dataTable');
//判断是否有选中行
if (checkStatus.data.length > 0) {
//定义数组,保存选中行的ID
var idArr = [];
//循环遍历获取选中行(目的是获取选中的每一行的ID值)
for (let i = 0; i < checkStatus.data.length; i++) {
//将选中的ID值添加到数组的末尾
idArr.push(checkStatus.data[i].id_video);
}
//将数组转成字符串
var ids = idArr.join(",");
//提示用户是否删除
layer.confirm('真的要删除吗?', {icon: 3, title: "提示"}, function (index) {
//发送ajax请求
$.post("${pageContext.request.contextPath}/video/batch-delete", {"ids": ids}, function (result) {
if (result.success) {
layer.alert(result.message, {icon: 1});
//刷新数据表格
tableIns.reload();
} else {
layer.alert(result.message, {icon: 2});
}
}, "json"); //关闭提示框
layer.close(index);
});
} else {
layer.msg("请选择要删除的数据");
}
}

单个删除和批量删除的controller层代码如下

   @RequestMapping(value = "/deleteById", produces = "text/html;charset=UTF-8")
@ResponseBody
public String deleteById(String id_video) {
Map<String, Object> map = new HashMap<String, Object>();
int result = videoService.deleteById(id_video);
if (result > 0) {
map.put("success", true);
map.put("message", "删除成功");
} else {
map.put("success", false);
map.put("message", "删除失败");
}
return JSON.toJSONString(map);
} @RequestMapping(value = "/batch-delete", produces = "text/html;charset=UTF-8")
@ResponseBody
public String batchDelte(String ids) {
Map<String, Object> map = new HashMap<String, Object>();
int result = videoService.batchDelte(ids);
if (result > 0) {
map.put("success", true);
map.put("message", "删除成功");
} else {
map.put("success", false);
map.put("message", "删除失败");
}
return JSON.toJSONString(map);
}

批量删除需要在service层中将ids按逗号分隔成数组再删除。


完毕

LayUI+SSM实现一个简单的后台管理系统的更多相关文章

  1. 基于ThinkPHP框架的简单的后台管理系统

    版权声明:本文为博主原创文章,未经博主允许不得转载. 基于ThinkPHP框架的简单的后台管理系统 一个简单的后台管理系统,可能还不全面,可以自己改,有登录功能 实例如图:    

  2. Asp.NetMVC利用LigerUI搭建一个简单的后台管理详解(函登录验证)

    上一篇 Asp.Net 中Grid详解两种方法使用LigerUI加载数据库数据填充数据分页  了解了LigerUI 中Grid的基本用法  现在结合上一篇的内容做一个简单的后台管理,当然也有前台的页面 ...

  3. 使用PHP开发一个简单的后台接口(响应移动端的get请求和post请求)

    写一个简单的后台,在接到app请求数据的时候,返回对应的内容: index.php文件如下: <?php $id = $_POST['id']; if($id==001){ echo json_ ...

  4. PureMVC和Unity3D的UGUI制作一个简单的员工管理系统实例

    前言: 1.关于PureMVC: MVC框架在很多项目当中拥有广泛的应用,很多时候做项目前人开坑开了一半就消失了,后人为了填补各种的坑就遭殃的不得了.嘛,程序猿大家都不喜欢像文案策划一样组织文字写东西 ...

  5. ABP教程(四)- 开始一个简单的任务管理系统 - 实现UI端的增删改查

    接上一篇:ABP教程(三)- 开始一个简单的任务管理系统 – 后端编码 1.实现UI端的增删改查 1.1添加增删改查代码 打开SimpleTaskSystem.sln解决方案,添加一个“包含视图的MV ...

  6. php+js实现一个简单的用户管理系统

    php + js 实现一个简单的用户管理系统 说实话,我对PHP是抵触的,但是我们的WEB课程刚好学的就是这个,不得已看了看,下面是用PHP实现的一个简单的用户管理系统. 我们首先来看一下目录结构 a ...

  7. SSM框架整合练习——一个简单的文章管理系统

    使用SSM框架搭建的简易文章管理系统,实现了简单的增删改查功能. @ 目录 开发工具版本: 最终的项目结构 IDEA+Maven搭建项目骨架 1. 新建Maven项目: 2. 在新建的项目中添加所需要 ...

  8. Layui 写一个简单的后台页面

    参考如下: 1.layui 官方文档 http://www.layui.com/doc/ 2.https://blog.csdn.net/huyanliang/article/details/7796 ...

  9. ASP.NET Core MVC 打造一个简单的图书馆管理系统 (修正版)(七) 学生信息增删

    前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/asp ...

随机推荐

  1. C++ 限定符Const和指针

    指向常量的指针 指向常量的指针不能用于其所指对象的值.若想存放常量对象的地址,只能使用指向常量的指针. const int a = 3; //a是个常量,其值不能改变 int *b = &a; ...

  2. vue 组件复用 - component

    vue 组件复用 - component vue 组件复用 就是对 component 标签的使用 先看图 下图看使用 结果: 可以看到 在箱包 这一项,我将banner 组件用了两次,我 每次 点击 ...

  3. Windbg调试工具命令详解

    .cls -------------------------------清屏 ~ ----------------------------------查看当前程序的所有线程 ~0s --------- ...

  4. 罗马数字转整数,Java执行时间超过100%用户的写法

    执行用时:2 ms, 在所有 Java 提交中击败了100.00%的用户 题目 https://leetcode-cn.com/problems/roman-to-integer 罗马数字包含以下七种 ...

  5. 通过Nginx TCP反向代理实现Apache Doris负载均衡

    概述 Nginx能够实现HTTP.HTTPS协议的负载均衡,也能够实现TCP协议的负载均衡.那么,问题来了,可不可以通过Nginx实现Apache Doris数据库的负载均衡呢?答案是:可以.接下来, ...

  6. WMS、WFS、WCS、WPS、WMTS、WMSC、TMS等常见地图服务的区别

    WebGIS的开发者经常需要面对各种地图服务规范,例如WMS.WFS.WCS.WPS.WMTS.TMS.WMSC等.因此了解这些服务的内容是相当重要的,这里对常见的服务进行了整理. OGC联盟: 开放 ...

  7. C# iText 7 切分PDF,处理PDF页面大小

    一.itext 我要使用itext做一个pdf的页面大小一致性处理,然后再根据数据切分出需要的pdf. iText的官网有关于它的介绍,https://itextpdf.com/ 然后在官网可以查找a ...

  8. ChCore Lab1 机器启动 实验笔记

    本文为上海交大 ipads 研究所陈海波老师等人所著的<现代操作系统:原理与实现>的课程实验(LAB)的学习笔记的第一篇. 书籍官网:现代操作系统:原理与实现,里面有实验的参考指南和代码仓 ...

  9. 干货 | LVM快照学习

    一个执着于技术的公众号 前言 在上一章节,我们学习了LVM逻辑卷管理技术,知道了LVM能够通过增减PE的数量来弹性调整文件系统的大小.除此之外,LVM还有另一个重要功能「LVM快照技术」,也就是可以给 ...

  10. 实战| Nginx+keepalived 实现高可用集群

    一个执着于技术的公众号 前言 今天通过两个实战案例,带大家理解Nginx+keepalived 如何实现高可用集群,在学习新知识之前您可以选择性复习之前的知识点: 给小白的 Nginx 10分钟入门指 ...