管理员信息维护

  • 一、分页显示管理员信息部分
    • (1) 思路
    • (2) 技术点
      • ① 让 SQL 语句针对 keyword 时有时无的情况进行适配
      • ② PageHelper 使用
      • ③ 显示页码
    • (3) 后端代码
      • ① 查询 Admin 数据的 SQL 语句
      • ② AdminMapper 中的抽象方法
      • ③ AdminService 方法
      • ④ AdminHandler 方法
    • (4) 前端代码
      • ① 准备 admin-page.jsp
      • ② 在 admin-page 页面显示真实数据
  • 二、分页导航条
    • (1) 加入 Pagination 插件环境
    • (2) 在页面上引入样式文件和 JavaScript 文件
      • ★ 出现的问题
    • (3) 编写 Pagination 代码
    • (4) 修改 jquery.pagination.js 文件源码
    • (5) 添加数据库测试数据
  • 三、关键词查询
    • (1) 页面调整待提交的表单
    • (2) 在翻页时保持 keyword 值
  • 四、单条删除 管理员
    • (1) 调整删除的按钮
    • (2) AdminHandler
    • (3) AdminService
    • (4) AdminServiceImpl
  • 五、新增管理员信息
    • (1) 思路
    • (2) 代码
      • ① 设置唯一约束
      • ② AdminService
      • ③ AdminServiceImpl
      • ④ 异常映射处理器类
      • ⑤ 自定义异常
      • ⑥ AdminHandler
      • ⑦ 调整新增按钮
      • ⑧ 配置view-controller
      • ⑨ 准备表单页面 admin-add.jsp
  • 六、更新管理员信息
    • (1) 思路
    • (2) 代码
      • ① 准备“更新”超链接
      • ② handler 代码
      • ③ AdminService
      • ④ AdminServiceImpl
      • ⑤ 调整修改的按钮
      • ⑥ 准备表单页面 admin-edit.jsp
      • ⑦ 执行更新
        • AdminHandler
        • AdminService
        • AdminServiceImpl
        • 自定义异常

一、分页显示管理员信息部分

(1) 思路

(2) 技术点

① 让 SQL 语句针对 keyword 时有时无的情况进行适配

使用 SQL 中做字符串连接的函数:CONCAT("%",#{keyword},"%")

  • keyword 有值:“like %tom%”
  • keyword 无值:“like %%”

② PageHelper 使用

  • 引入依赖

<!-- MyBatis分页插件 -->
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId>
</dependency>
  • 在 SqlSessionFactoryBean 中配置 PageHelper

<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"><!-- 装配数据源--><property name="dataSource" ref="dataSource"/><!-- 指定MyBatis 全局配置文件位置--><property name="configLocation" value="classpath:mybatis-config.xml"/><!-- 指定Mapper 配置文件位置--><property name="mapperLocations" value="classpath:mybatis/mapper/*Mapper.xml"/><!-- 配置 MyBatis 的插件 --><property name="plugins"><array><!-- 配置 PageHelper --><bean class="com.github.pagehelper.PageHelper"><!-- 配置相关属性 --><property name="properties"><props><!-- 配置数据库方言,告诉 PageHelper 当前使用的具体数据库,--><!-- 让 PageHelper 可以根据当前数据库生成对应的分页 SQL 语句 --><prop key="dialect">mysql</prop><!-- 配置页码的合理化修正 --><!-- 让 PageHelper 自动把浏览器传来的 PageNum 修正到 0~总页数范围 --><prop key="reasonable">true</prop></props></property></bean></array></property>
</bean>
  • 在 Java 代码中使用
PageHelper.startPage(pageNum, pageSize)PageInfo<Admin> pageInfo = new PageInfo(adminList );

③ 显示页码

使用 jQuery 插件Pagination


(3) 后端代码

① 查询 Admin 数据的 SQL 语句

<select id="selectAdminListByKeyword" resultMap="BaseResultMap">select<include refid="Base_Column_List"/>from t_adminwhere login_acct like CONCAT("%",#{keyword},"%")oruser_name like CONCAT("%",#{keyword},"%")oremail like CONCAT("%",#{keyword},"%")
</select>

② AdminMapper 中的抽象方法

List<Admin> selectAdminListByKeyword(String keyword);

③ AdminService 方法

// 管理员分页
@Override
public PageInfo<Admin> getAdminPage(String keyword, Integer pageNum, Integer pageSize) {// 1.开启分页功能PageHelper.startPage(pageNum,pageSize);// 2.查询 Admin 数据List<Admin> admins = adminMapper.selectAdminListByKeyword(keyword);// 3.为了方便页面使用将 adminList 封装为 PageInfoPageInfo<Admin> pageInfo = new PageInfo<>(admins);return pageInfo;
}

④ AdminHandler 方法

// 管理员分页
@RequestMapping("/admin/page.html")
public String getAdminPage(// 注意:页面上有可能不提供关键词,要进行适配// 在@RequestParam注解中设置defaultValue属性为空字符串// 表示浏览器不提供关键词时keyword 变量赋值为空字符串@RequestParam(value="keyword", defaultValue="") String keyword,// 浏览器未提供 pageNum 时,默认前往第一页@RequestParam(value="pageNum", defaultValue="1") Integer pageNum,// 浏览器未提供 pageSize 时,默认每页显示 5 条记录@RequestParam(value="pageSize", defaultValue="5") Integer pageSize,ModelMap modelMap) {// 查询得到分页结果PageInfo<Admin> pageInfo = adminService.getAdminPage(keyword, pageNum, pageSize);// 将分页数据存入模型modelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO,pageInfo);return "admin-page";
}

(4) 前端代码

① 准备 admin-page.jsp

② 在 admin-page 页面显示真实数据

<tbody>
<c:if test="${empty requestScope.pageInfo.list }"><tr><td colspan="2">抱歉!没有查询到相关的数据!</td></tr>
</c:if>
<c:if test="${!empty requestScope.pageInfo.list }"><c:forEach items="${requestScope.pageInfo.list }" var="admin" varStatus="myStatus"><tr><td>${myStatus.count }</td><td><input type="checkbox"></td><td>${admin.loginAcct }</td><td>${admin.userName }</td><td>${admin.email }</td><td><button type="button" class="btn btn-success btn-xs"><i class=" glyphicon glyphicon-check"></i></button><button type="button" class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></button><button type="button" class="btn btn-danger btn-xs"><i class=" glyphicon glyphicon-remove"></i></button></td></tr></c:forEach>
</c:if>
</tbody>


二、分页导航条

(1) 加入 Pagination 插件环境

(2) 在页面上引入样式文件和 JavaScript 文件

<link rel="stylesheet" href="css/pagination.css">
<script type="text/javascript" src="jquery/jquery.pagination.js"></script>

★ 出现的问题

在href和src后的路径最前面加了../ ,一开始没加时,发现没有代码提示,
于是当时突然觉得是因为要先找到上一级目录,也就是webapp
再从该目录下寻找。于是,pagination不生效了,找了半天错误,最后想起来在公共jsp中写了base
所以链接的前面不用写/了,大概率是因为这个原因,于是去掉../,问题得到解决

(3) 编写 Pagination 代码

<script type="text/javascript">$(function () {// 调用专门的函数初始化分页导航条initPagination();});// 声明一个函数用于初始化 Paginationfunction initPagination() {// 获取分页数据中的总记录数var totalRecord = ${requestScope.pageInfo.total};// 声明 Pagination 设置属性的 JSON 对象var properties = {num_edge_entries: 3,                                // 边缘页数num_display_entries: 5,                             // 主体页数callback: pageSelectCallback,                       // 用户点击“翻页”按钮之后执行翻页操作的回调函数current_page: ${requestScope.pageInfo.pageNum-1},   // 当前页,pageNum 从 1 开始,必须-1 后才可以赋值prev_text: "上一页",next_text: "下一页",items_per_page:${requestScope.pageInfo.pageSize}    // 每页显示 1 项};// 调用分页导航条对应的 jQuery 对象的 pagination()方法生成导航条$("#Pagination").pagination(totalRecord, properties);}// 翻页过程中执行的回调函数// 点击“上一页”、“下一页”或“数字页码”都会触发翻页动作,从而导致当前函数被调用// pageIndex 是用户在页面上点击的页码数值function pageSelectCallback(pageIndex, jQuery) {// pageIndex 是当前页页码的索引,相对于 pageNum 来说,pageIndex 比 pageNum 小 1var pageNum = pageIndex + 1;// 执行页面跳转也就是实现“翻页”window.location.href = "admin/page.html?pageNum=" + pageNum;// 取消当前超链接的默认行为return false;}
</script>

(4) 修改 jquery.pagination.js 文件源码


问题的解决:不让 Pagination 在页码导航条初始化完成时就调用回调函数!

(5) 添加数据库测试数据

@Test
public void test1() {for (int i = 2; i < 234; i++) {Admin admin = new Admin(null,"admin"+i,"admin"+i,"admin"+i,"admin"+i+"@qq.com",null);adminMapper.insertSelective(admin);}}


三、关键词查询

(1) 页面调整待提交的表单

<form action="admin/get/page.html" method="post" class="form-inline" role="form" style="float:left;"><div class="form-group has-feedback"><div class="input-group"><div class="input-group-addon">查询条件</div><input name="keyword" class="form-control has-success" type="text" placeholder="请输入查询条件"></div></div><button type="submit" class="btn btn-warning"><i class="glyphicon glyphicon-search"></i> 查询</button>
</form>

(2) 在翻页时保持 keyword 值

// 执行页面跳转也就是实现“翻页“
window.location.href = "admin/get/page.html?pageNum="+pageNum+"&keyword=${param.keyword}";

四、单条删除 管理员

(1) 调整删除的按钮

<a href="admin/remove/${admin.id }/${requestScope.pageInfo.pageNum }/${param.keyword }.html" class="btn btn-danger btn-xs"><i class=" glyphicon glyphicon-remove"></i>
</a>

(2) AdminHandler

// 管理员单条删除
@RequestMapping("/admin/remove/{adminId}/{pageNum}/{keyword}.html")
public String removeAdmin(@PathVariable("adminId") int adminId,@PathVariable("pageNum") int pageNum,@PathVariable("keyword") String keyword
) {// 执行删除adminService.removeAdmin(adminId);// 页面跳转:回到分页页面// 尝试方案1:直接转发到admin-page.jsp会无法显示分页的数据// return "admin-page";// 尝试方案2:转发到/admin/get/page.html地址,一旦刷新页面会重新执行删除操作,浪费性能// return "forward:/admin/get/page.html";// 尝试方案3:重定向到/admin/get/page.html地址// 同时为了保持原本所在的页面和查询关键词再附加pageNum和keyword两个请求参数return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword;
}

(3) AdminService

void removeAdmin(int adminId);

(4) AdminServiceImpl

// 管理员删除
@Override
public void removeAdmin(int adminId) {adminMapper.deleteByPrimaryKey( adminId);
}

五、新增管理员信息

(1) 思路

(2) 代码

① 设置唯一约束

ALTER TABLE `t_admin` ADD UNIQUE INDEX (`login_acct`)

② AdminService

void addAdmin(Admin admin);

③ AdminServiceImpl

// 增加管理员
@Override
public void addAdmin(Admin admin) {// 生成当前系统时间Date date = new Date();SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String createTime = format.format(date);admin.setCreateTime(createTime);// 针对登录密码进行加密String userPswd = admin.getUserPswd();String encoded = CrowdUtil.md5(userPswd);admin.setUserPswd(encoded);// 执行保存,如果账户被占用会抛出异常try {adminMapper.insert(admin);}catch (Exception e) {e.printStackTrace();// 检测当前捕获的异常对象,如果是 DuplicateKeyException 类型说明是账号重复导致的if (e instanceof DuplicateKeyException) {// 抛出自定义的 LoginAcctAlreadyInUseException 异常throw new LoginAcctAlreadyInUseException(CrowdConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE);}// 为了不掩盖问题,如果当前捕获到的不是 DuplicateKeyException 类型的异常,则把当前捕获到的异常对象继续向上抛出throw e;}
}

④ 异常映射处理器类

// 账号已存在异常
@ExceptionHandler(LoginAcctAlreadyInUseException.class)
public ModelAndView LoginAcctAlreadyInUseException(LoginAcctAlreadyInUseException exception,HttpServletRequest request,HttpServletResponse response
) throws IOException {// 只是指定当前异常对应的页面即可String viewName = "admin-add";return commonResolveException(exception, request, response, viewName);
}

⑤ 自定义异常

public class LoginAcctAlreadyInUseException extends RuntimeException{public LoginAcctAlreadyInUseException() {super();}public LoginAcctAlreadyInUseException(String message) {super(message);}public LoginAcctAlreadyInUseException(String message, Throwable cause) {super(message, cause);}public LoginAcctAlreadyInUseException(Throwable cause) {super(cause);}protected LoginAcctAlreadyInUseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}

⑥ AdminHandler

// 添加管理员
@RequestMapping("/add/admin.html")
public String addAdmin(Admin admin) {// 执行添加adminService.addAdmin(admin);// 重定向到分页页面,使用重定向是为了避免刷新浏览器重复提交表单// 为了能看到刚添加的管理员,所以去到最后一页,return "redirect:/admin/get/page.html?pageNum="+Integer.MAX_VALUE;
}

⑦ 调整新增按钮

</button>
<%--旧代码--%>
<%--<button type="button" class="btn btn-primary" style="float:right;"--%>
<%--οnclick="window.location.href='add.html'"><i class="glyphicon glyphicon-plus"></i> 新增--%>
<%--</button>--%><%--新代码--%>
<a href="admin/to/add/page.html" class="btn btn-primary"><i class="glyphicon glyphicon-plus"></i></a>

⑧ 配置view-controller

<!-- 新增管理员页面-->
<mvc:view-controller path="/admin/to/add/page.html" view-name="admin-add" />

⑨ 准备表单页面 admin-add.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<%@include file="include-head.jsp" %>
<body>
<%@include file="include-nav.jsp" %>
<div class="container-fluid"><div class="row"><%@include file="include-sidebar.jsp" %><div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"><ol class="breadcrumb"><li><a href="admin/to/main/page.html">首页</a></li><li><a href="admin/get/page.html">数据列表</a></li><li class="active">新增</li></ol><div class="panel panel-default"><div class="panel-heading">表单数据<div style="float:right;cursor:pointer;" data-toggle="modal" data-target="#myModal"><i class="glyphicon glyphicon-question-sign"></i></div></div><div class="panel-body"><form action="add/admin.html" method="post" role="form"><p>${requestScope.exception.message}</p><div class="form-group"><label for="exampleInputPassword1">登录账号</label><input name="loginAcct"  type="text" class="form-control" id="exampleInputPassword1" placeholder="请输入登录账号"></div><div class="form-group"><label for="exampleInputPassword1">登录密码</label><input name="userPswd"  type="text" class="form-control" id="exampleInputPassword2" placeholder="请输入登录密码"></div><div class="form-group"><label for="exampleInputPassword1">用户昵称</label><input name="userName" type="text" class="form-control" id="exampleInputPassword3" placeholder="请输入用户昵称"></div><div class="form-group"><label for="exampleInputEmail1">邮箱地址</label><input name="email" type="email" class="form-control" id="exampleInputEmail1" placeholder="请输入邮箱地址"><p class="help-block label label-warning">请输入合法的邮箱地址, 格式为: xxxx@xxxx.com</p></div><button type="submit" class="btn btn-success"><i class="glyphicon glyphicon-plus"></i> 新增</button><button type="reset" class="btn btn-danger"><i class="glyphicon glyphicon-refresh"></i> 重置</button></form></div></div></div></div>
</div>
</body>
</html>

六、更新管理员信息

(1) 思路

(2) 代码

① 准备“更新”超链接

<%--旧代码--%>
<%--<button type="button" class="btn btn-success btn-xs">--%>
<%--<i class=" glyphicon glyphicon-check"></i>--%>
<%--</button>--%>
<%--新代码--%>
<a href="admin/to/edit/page.html?adminId=${admin.id}&pageNum=${requestScope.pageInfo.pageNum}&keyword=${param.keyword}" class="btn btn-success btn-xs"><i class=" glyphicon glyphicon-check"></i>
</a>

② handler 代码

// 更新管理员信息
@RequestMapping("/admin/to/edit/page.html")
public String editAdmin(@RequestParam("adminId") int adminId,ModelMap modelMap) {// 通过id获取修改的管理员Admin admin = adminService.getAdminById(adminId);// 将获取到的admin放入request域中modelMap.addAttribute("admin",admin);return "admin-edit";
}

③ AdminService

Admin getAdminById(int adminId);

④ AdminServiceImpl

// 通过id获取admin对象
@Override
public Admin getAdminById(int adminId) {return adminMapper.selectByPrimaryKey(adminId);
}

⑤ 调整修改的按钮

<%--旧代码--%>
<%--<button type="button" class="btn btn-success btn-xs">--%>
<%--<i class=" glyphicon glyphicon-check"></i>--%>
<%--</button>--%>
<%--新代码--%>
<a href="admin/to/edit/page.html?adminId=${admin.id}&pageNum=${requestScope.pageInfo.pageNum}&keyword=${param.keyword}" class="btn btn-success btn-xs"><i class=" glyphicon glyphicon-check"></i>
</a>

⑥ 准备表单页面 admin-edit.jsp


⑦ 执行更新

AdminHandler
// 更新管理员信息
@RequestMapping("/admin/update.html")
public String adminUpdate(Admin admin,@RequestParam("pageNum") int pageNum,@RequestParam("keyword") String keyword) {// 执行更新adminService.updateAdmin(admin);//return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword;
}
AdminService
void updateAdmin(Admin admin);
AdminServiceImpl
// 修改管理员信息
@Override
public void updateAdmin(Admin admin) {try {// "Selective" 表示有选择的更新,对于null值的字段不更新adminMapper.updateByPrimaryKeySelective(admin);}catch (Exception e) {e.printStackTrace();// 检测当前捕获的异常对象,如果是 DuplicateKeyException 类型说明是账号重复导致的if (e instanceof DuplicateKeyException) {// 抛出自定义的 LoginAcctAlreadyInUseException 异常throw new LoginAcctAlreadyInUseForUpdateException(CrowdConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE);}// 为了不掩盖问题,如果当前捕获到的不是 DuplicateKeyException 类型的异常,则把当前捕获到的异常对象继续向上抛出throw e;}
}
自定义异常

public class LoginAcctAlreadyInUseForUpdateException extends RuntimeException{public LoginAcctAlreadyInUseForUpdateException() {super();}public LoginAcctAlreadyInUseForUpdateException(String message) {super(message);}public LoginAcctAlreadyInUseForUpdateException(String message, Throwable cause) {super(message, cause);}public LoginAcctAlreadyInUseForUpdateException(Throwable cause) {super(cause);}protected LoginAcctAlreadyInUseForUpdateException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}

// 修改管理员信息账号已存在异常
@ExceptionHandler(LoginAcctAlreadyInUseForUpdateException.class)
public ModelAndView LoginAcctAlreadyInUseForUpdateException(LoginAcctAlreadyInUseForUpdateException exception,HttpServletRequest request,HttpServletResponse response) throws IOException {// 只是指定当前异常对应的页面即可String viewName = "system-error";return commonResolveException(exception, request, response, viewName);}

【尚筹网项目】 三、【后台】 管理员信息维护相关推荐

  1. 尚筹网(众筹项目实战)

    尚筹网是一个在线众筹平台,通过向普通大众募集资金来支持创业项目,支持者可以获得与支持金额相当的回报.该项目视频在学习路线中的定位是:从单一架构到分布式架构的过渡阶段,适合学完SSM框架后,需要通过一个 ...

  2. 【尚筹网】IDEA版实现(十二)项目展示

    由于尚硅谷的视频是通过Eclipse软件来做的,其中有些操作与IDEA上有所区别,所以我在这里将IDEA区别于Eclipse的操作.操作过程中涉及的源码(与视频的源码略有出入)以及大家可能遇到的种种问 ...

  3. 【尚筹网】IDEA版实现(八)前台环境配置

    由于尚硅谷的视频是通过Eclipse软件来做的,其中有些操作与IDEA上有所区别,所以我在这里将IDEA区别于Eclipse的操作.操作过程中涉及的源码(与视频的源码略有出入)以及大家可能遇到的种种问 ...

  4. SSM 尚筹网 Vue3 + Vite + Java

    SSM 尚筹网 2022年3月27日15:07:51 文章目录 SSM 尚筹网 1.Maven结构: 1.基于Maven的MyBatis逆向工程 2.资源归为 3. 父工程管理 4.SSM整合步骤 4 ...

  5. 【尚筹网】IDEA版实现(九)会员登录

    由于尚硅谷的视频是通过Eclipse软件来做的,其中有些操作与IDEA上有所区别,所以我在这里将IDEA区别于Eclipse的操作.操作过程中涉及的源码(与视频的源码略有出入)以及大家可能遇到的种种问 ...

  6. 尚筹网 —— 5、角色维护

    目录 1.角色分页操作 1.1.目标 1.2.思路 1.3.代码 1.3.1.创建数据库表 1.3.2.逆向生成相关资源 1.3.3.准备查询的 SQL 语句 1.3.4.添加 mapper 方法 1 ...

  7. 尚筹网-前台-会员系统(springboot,springcloud 实战)

    总目标: 环境搭建 会员登录注册 发起众筹项目 展示众筹项目 支持众筹项目 订单 支付 1. 会员系统架构 1.1 架构图 1.2  需要创建的工程 父工程.聚合工程:shangcouwang01-m ...

  8. 商城管理系统项目(前台+后台+管理员+用户+html+jsp)

    管理员后台 用户前台 如果下载项目报错,加包即可(包已经打包放在下载地址) 数据库:mysql drop database shoppingmall; create database shopping ...

  9. 基于SPRINGBOOT尚筹网-创意产品众筹平台

    开发工具(eclipse/idea): eclipse4.5/4.8或者idea2018,jdk1.8 数据库:mysql 功能模块: 1.完成登录注册功能 2.用户登录到主页后 页面显示产品的图片及 ...

最新文章

  1. matlab门槛回归,重磅!这可能是最全的门槛回归汇总了
  2. 使用MapReduce实现join操作
  3. python3.7.3 离线安装paramiko_centos7 python3 安装paramiko模块
  4. 添加新闻在分层里的实现
  5. HH SaaS电商系统的出库功能模块设计
  6. Python中socket入门例子
  7. 一个WIFI热点的脚本思路,顺记shell知识
  8. java.sql.SQLException: Io 异常: The Network Adapter could not establish the connection 解决
  9. Java韩顺平 | IO流专题 | 学习小记
  10. 域控下发脚本_让系统及时的通过域用户脚本自动的打补丁
  11. 数据库面试题及优化手段
  12. sip协议详解(三)
  13. php mysql电子_用php与mysql的电子贺卡代码
  14. Centos7模板机制作
  15. 如何导入和导出Maven项目(分享给别人源码)
  16. XML的解析方法(如何解析XML)
  17. 计算机网络局域网组建课程设计,计算机网络课程设计 组建校园局域网.doc
  18. 发力小程序社交电商,礼物说完成C1轮1亿人民币融资
  19. python保存文件的几种方式
  20. Harmonyos官网申请的,HarmonyOS 2.0手机开发者Beta公测招募,普通用户有没有必要申请?...

热门文章

  1. 解决linux使用yum安装新版JDK时,Java文件夹下没有lib、bin等文件,只有jre的问题
  2. 开源 | 智能家居场景,基于 AriKiss 配网的微信小程序
  3. 老衲与你一起走过。。。
  4. hihoCoder #1073 光棍节
  5. C#毕业设计——基于C#+asp.net+sqlserver的视频点播系统设计与实现(毕业论文+程序源码)——视频点播系统
  6. 于我而言,大早上的好消息——JetBrains Fleet来了
  7. 夜光 带你走进微信小程序研发(三)
  8. live.com邮箱换成中文界面
  9. 苹果连接电脑 计算机不显示硬盘,解决方法:Mac Mac计算机无法识别的硬盘解决方案...
  10. CISAW证书发证机构是哪里?权威性如何?