当前位置: 首页 > news >正文

文章详情页 - 评论功能的实现

目录

1. 准备工作

1.1 创建评论表

 1.2 创建评论实体类

 1.3 创建 mapper 层评论接口和对应的 xml  实现

1.4 准备评论的 service 层

1.5 准备评论的 controller 层

2. 总的初始化详情页

2.1 加载评论列表

2.1.1 实现前端代码

2.1.2 实现后端代码

2.2 查询当前登录用户的信息

2.2.1 实现前端代码

2.2.2 实现后端代码

3. 实现发表评论

3.1 实现前端代码

3.2 实现后端代码

4. 实现删除评论

4.1 实现前端代码

4.2 实现后端代码


1. 准备工作

本文是针对之前写的一篇博客系统项目实现了一个评论的扩展功能.

1.1 创建评论表

create table commentinfo(cid bigint auto_increment primary key comment '评论表的主键',aid bigint not null comment '文章表id',uid bigint not null comment '用户id',`content` varchar(500) not null comment '评论正文',createtime timestamp default CURRENT_TIMESTAMP() comment '评论的发表时间'
);

 1.2 创建评论实体类

@Data
@TableName("commentinfo")
public class CommentInfo implements Serializable {@TableId(type= IdType.AUTO)private long cid;private long aid;private long uid;private String content;private LocalDateTime createtime;
}

 1.3 创建 mapper 层评论接口和对应的 xml  实现

public interface CommentInfoMapper extends BaseMapper<CommentInfo> {
}

此处使用了 MyBatis-Plus 框架, 也可以使用之前的 MyBatis 框架, 根据个人喜好.

MyBatis-Plus 依赖:

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency>

 对应的 xml 实现:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.CommentInfoMapper"></mapper>

1.4 准备评论的 service 层

service 接口的定义:

public interface ICommentInfoService extends IService<CommentInfo> {List<CommentInfoVo> getList(Integer aid);
}

service 接口的实现类:

@Service
public class CommentInfoServiceImpl extends ServiceImpl<CommentInfoMapper, CommentInfo> implements ICommentInfoService  {}

1.5 准备评论的 controller 层

@RestController
@RequestMapping("/comment")
public class CommentController {@Resourceprivate ICommentInfoService commentInfoService;
}

2. 总的初始化详情页

// 总的初始化详情页
function initPage() {// 初始化文章详情页initArtDetail();// 加载评论列表initComment();// 更新访问量updateCount();// 查询当前登录用户的信息 getSessionUser();
}
initPage();

详情页要做的事情有 :

  • 加载博客详情 (博客标题, 发布时间, 博客访问量, 博客正文)  - 参考之前的文章
  • 加载当前博客对应作者的身份信息(username, 文章数量) - 参考之前的文章
  • 加载博客下面的评论
  • 加载当前登录人的名字到评论框下面 (登录了才能评论)

对于第四条 "加载当前登录人的名字到评论框下面" >

如果用户没有登录, 那么展示效果如下 : 

 如果用户登录了, 那么展示效果如下 :

2.1 加载评论列表

我们在查看博客详情页的时候, 如果该文章下面有评论, 则需要查询数据库将评论列表查询出来, 并且倒序排序展示出来.

完善前端页面blog_content.html : 

<!-- 右侧内容详情 -->
<div class="container-right"><div class="blog-content"><!-- 博客标题 --><h3 id="title"></h3><!-- 博客时间 --><div class="date"><span id="createtime"></span> &nbsp;&nbsp;&nbsp;&nbsp;访问量: <span id="rcount"></span></div><!-- 博客正文 --><div id="editorDiv"></div><hr><div><h3 style="text-align: left;margin: 30px 0 0 0;">评 论</h3><div id="addcomment"><div><textarea id="comment_content" placeholder="此处输入评论内容"style="text-align: left;width: 25%;height: 80px;"></textarea></div><div><span id="comment_login_name" style="margin-left: 10px;">请先登录</span>:<input type="button" value="发表评论" class="btn" onclick="addComment()"style="margin-left: 20px;margin-top: 10px;"></div></div><h4 id="commentCount" style="margin-left: 300px;margin-top: 30px;"></h4><br><div id="commentlist" style="margin-left: 300px;"></div></div></div>
</div>

从前边的页面可以看出, 加载评论列表既包含了评论内容, 又包含了当前登录人, 所以需要使用到多表联查, 一旦涉及到了多表联查, 那么使用 MyBatis-Plus 就没有 MyBatis 那么方便了. 其次, 我们可以看到评论后面带有删除按钮, 因为这篇文章属于张三的, 所以他可以管理他文章下面的评论, 而如果这篇文章不属于张三, 那么他查看详情页就不能显示删除按钮.

2.1.1 实现前端代码

因为是要获取当前文章下的评论, 所以需要传递一个文章 ID 给后端, 文章 ID 从哪来呢, 博客详情页的 URL 中带有对应文章的 aid, 所以可以从 URL 中取.

function getURLParam(key) {var params = location.search;  // query stringif(params.indexOf("?") >= 0) {params = params.substring(1);// 键值对之间使用 & 分割var paramArr = params.split('&');for(var i = 0; i < paramArr.length; i++) {// 键和值使用 = 分割var namevalues = paramArr[i].split("=");if(namevalues[0] == key) {return namevalues[1];}}} else {return "";}
}

从 URL 中获取文章 ID 在多个方法中都需要使用到, 我们可以将其封装成一个工具方法, 再通过 src 属性引入.

前端实现代码 : 

var aid = getURLParam("id"); // 文章ID// 加载评论列表
function initComment() {jQuery.ajax({url:"/comment/list",type:"GET",data:{"aid":aid},success:function(body) {if(body.code==200 && body.data!=null) {var commentListHtml = "";for(let comment of body.data) {commentListHtml += '<div style="margin-bottom: 26px;">';commentListHtml += comment.username + ':' + comment.content;commentListHtml += '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a class="comment_del_class" style="display: none;text-decoration:none; color:grey;" href="javascript:del(' +comment.cid + ')">删除</a>';commentListHtml += '</div>';}jQuery("#commentlist").html(commentListHtml);var commentCount = body.data.length;jQuery("#commentCount").html('共 ' + commentCount + ' 条评论');}}});
}initComment();

【注意】此处要给删除按钮添加 display: none 样式, 后续在 getSessionUser() 方法中会做判断, 判断当前登录人和文章作者是否为同一个人, 如果是则显示删除按钮, 如果不是, 则不显示删除按钮.

2.1.2 实现后端代码

因为本次查询需要包含一个 username, 而基础的评论 model 类是没有的, 所以可以新增一个commentinfo 的扩展类 - model.vo.CommentInfoVo.java

@Data
public class CommentInfoVo extends CommentInfo implements Serializable {private String username;
}

写 mapper 层 :

List<CommentInfoVo> getList(@Param("aid")Integer aid);

对应的 xml 实现 :

<select id="getList" resultType="com.example.demo.model.vo.CommentInfoVo">SELECT c.*,u.username from commentinfo cleft join userinfo u on c.uid=u.idwhere c.aid=#{aid}order by c.cid desc
</select>

写 service 层 :

ICommentInfoService

List<CommentInfoVo> getList(Integer aid);

CommentInfoServiceImpl

@Resource
private CommentInfoMapper commentInfoMapper;@Override
public List<CommentInfoVo> getList(Integer aid) {return commentInfoMapper.getList(aid);
}

写 controller 层:

/*** 获取评论列表* @param aid* @return*/
@RequestMapping("/list")
public Object getCommentList(Integer aid) {// 1. 参数效验if(aid==null || aid<=0) {return AjaxResult.fail(-1, "参数有误!");}// 2. 查询数据库List<CommentInfoVo> commentResult = commentInfoService.getList(aid);// 3. 就结果返回给前端return AjaxResult.success(commentResult);
}

后端接口 /comment/list 记得要在拦截器里边放行, 如果拦截了, 那么用户不登录, 就看不到评论了, 我们想要的效果是: 

就算用户不登录, 所有人的的博客列表页查看文章详情的时候, 也能看到评论, 只是不管文章归属人是谁都不会显示删除按钮. 

2.2 查询当前登录用户的信息

这个接口是为了实现 : 用户登录了才能发表评论,用户未登录,就显示请先登录.

2.2.1 实现前端代码

var islogin = false; // 是否登录 [是否能发表评论]// [是否要显示发表评论的人的名字] 获取当前登录的用户
function getSessionUser() {jQuery.ajax({url: "/user/myinfo",type: "GET",data: {},success: function (body) {if (body.code == 200 && body.data != null && body.data.id >= 0) {// 当前用户已经登录islogin = true;jQuery("#comment_login_name").html(body.data.username);  // 评论人// 判断当前文章是否是当前登录用户发表的, 如果是就显示删除按钮isArtByMe(aid); } else {// 当前用户未登录}}});
}// [是否要显示评论删除按钮] -  判断当前文章是否属于当前登录用户
function isArtByMe(aid) {jQuery.ajax({url: "/user/isartbyme",type: "GET",data: {"aid": aid},success: function (res) {if (res.code == 200 && res.data == 1) {// 当前文章归属于当前登录用户jQuery(".comment_del_class").each(function (i) {jQuery(this).show();});}}});
}

getSessionUser() 方法的作用是控制登录了才能发表评论,未登录不能发表评论.

isArtByMe()  方法的作用是控制是否显示删除按钮.

【注意】此处最好将 isArtByMe() 方法写在 getSessionUser() 中 ajax 最后, 如果写在外面, 会出现这样一个问题 : 

" 因为同一个页面下面的 ajax  请求的执行顺序是不一定的, 那么就有可能先执行了控制是否显示删除按钮的 ajax, 再执行 getSessionUser(), 如果是这样, 那么这篇文章属不属于当前登录人, 都不会显示删除按钮, 没有登录怎么判断文章归属人是吧."

所以 isArtByMe() 方法要在 getSessionUser() 方法执行后再调用.

2.2.2 实现后端代码

这部分代码比较简单, 实现 controller 层后, 后面的 mapper,xml,service 照猫画虎都能实现好.

// 获取登录人的身份信息
@RequestMapping("/myinfo")
public Object myInfo(HttpServletRequest request) {// 从 session 工具类中拿用户登录信息UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo == null || userInfo.getId() <= 0) {return AjaxResult.fail(-2, "当前用户未登录!");}return AjaxResult.success(userInfo);
}@RequestMapping("/isartbyme")
public Object isArtByMe(Integer aid, HttpServletRequest request) {if(aid == null || aid <= 0) {return AjaxResult.fail(-1, "参数有误! ");}UserInfo userInfo = SessionUtil.getLoginUser(request);if(userInfo == null || userInfo.getId() <= 0) {return AjaxResult.fail(-2, "当前用户未登录! ");}ArticleInfo articleInfo = articleService.getById(aid);if(articleInfo != null && articleInfo.getId() >= 0&& articleInfo.getUid() == userInfo.getId()) {// 文章归属于当前登录人return AjaxResult.success(1);}return AjaxResult.success(0);
}

此处的 /user/myinfo 和 /user/isArtByMe 接口都需要在拦截器里边放行. 

3. 实现发表评论

3.1 实现前端代码

给 "发表评论按钮" 加上点击事件:

// 添加评论
function addComment() {// 拿到评论正文var comment_content = jQuery("#comment_content");// 1.非空效验if(comment_content.val().trim() == "") {alert("请输入你的评论! ");comment_content.focus();return false;}// 2.登录判断if(!islogin) {alert("您还未登录, 请先登录! ");return false;}// 3.将前端数据发送给后端//   3.1 文章 id//   3.2 评论内容jQuery.ajax({url:"comment/add",type:"POST",data:{"aid":aid,"content":comment_content.val()},// 4.将后端返回的数据显示给用户success:function(body) {if(body.code==200 && body.data==1) {alert("评论已发表");// 刷新当前页面location.href = location.href;} else {alert("评论发表失败: " + body.msg);}}});
}

3.2 实现后端代码

/*** 发表评论* @return*/
@RequestMapping("/add")
public Object add(Long aid, String content, HttpServletRequest request) {// 1.参数效验if(aid == null || aid == 0 || !StringUtils.hasLength(content)) {// 非法参数return AjaxResult.fail(-1, "非法参数");}// 2.组装数据UserInfo userInfo = SessionUtil.getLoginUser(request);if(userInfo == null || userInfo.getId() <= 0) {return AjaxResult.fail(-2, "请先登录! ");}CommentInfo commentInfo = new CommentInfo();commentInfo.setAid(aid);commentInfo.setContent(content);commentInfo.setUid(userInfo.getId());// 3.将评论对象插入数据库boolean result = commentInfoService.save(commentInfo);// 4.将数据库执行结果返回给前端return AjaxResult.success(result ? 1 : 0);
}

发表评论的路由 /comment/add 需要在拦截器里边配置拦截, 因为只有登录了才能发表评论.

4. 实现删除评论

4.1 实现前端代码

// 删除评论
function del(cid) {if(!confirm("确定删除")) {return false;}// 1.参数效验if(cid == "" || cid <= 0) {alert("抱歉: 操作失败, 请刷新页面后重试! ");return false;}if(aid == "" || aid <= 0) {alert("抱歉: 删除评论失败, 请刷新页面后重试! ");return false;}// 2.发送数据给后端(aid,cid)jQuery.ajax({url:"/comment/del",type:"POST",data:{"cid":cid,"aid":aid},success:function(body) {if(body.code == 200 && body.data == 1) {alert("评论删除成功! ");// 刷新当前页面location.href = location.href;} else {alert("抱歉, 评论删除失败! " + body.msg);}}});
}

想要删除评论, 那么至少得传递两个参数给后端, 一个是 cid (评论 ID), 一个是 aid (文章 ID), cid 在前边加载评论列表的时候, 已经在返回数据 body 中的 comment 对象中拿到了, aid 呢 ,前面已经调用了工具方法 getURLParam 获取并保存 aid 全局变量中, 因此也可以直接拿到.

【注意】虽然是否能够删除评论需要拿着 aid 查询出具体的 articleinfo 对象, 再拿着这个对象的 uid 和登录人的 uid 进行比较, 相同才可以删除评论. 但是此处不能将 uid (用户人的 ID) 通过 ajax 发给后端, 一旦 uid 通过参数来接受登录人的 ID 了, 那么就有被篡改的风险, 别人可以写一个接口绕过你的 ajax 直接访问后端接口 (例如: postman), 这样就非常不安全, 所以 uid 可以从后端的 session 中获取.

4.2 实现后端代码

/*** 删除评论* @param cid* @param aid* @return*/
@RequestMapping("/del")
public Object del(Long cid, Long aid, HttpServletRequest request) {// 1.参数效验if(cid == null || cid <= 0 || aid == null || aid <= 0) {// 非法参数return AjaxResult.fail(-1, "非法参数! ");}// 2.效验权限UserInfo userInfo = SessionUtil.getLoginUser(request);if(userInfo == null || userInfo.getId() <= 0) {// 无效登录return AjaxResult.fail(-2, "请先登录! ");}// 拿到当前文章对应的作者身份信息 (uid)ArticleInfo articleInfo = articleService.getById(aid);if(articleInfo == null || articleInfo.getId() <= 0) {return AjaxResult.fail(-3, "非法的文章ID! ");}// 如果文章对应的 uid 和 session 中的 uid 不一致, 则不能删除if(articleInfo.getUid() != userInfo.getId()) {return AjaxResult.fail(-4, "非法操作! ");}boolean result = commentInfoService.removeById(cid);return AjaxResult.success(result ? 1 : 0);
}

删除评论的路由 /comment/del 也是需要在拦截器里边添加拦截的, 因为登陆之后才能删除评论.

另外评论表中还有一个发表评论时间的字段, 由于我个人是前端小白, 不知道如何将发表评论时间更好的展示在评论列表那里, 于是我就干脆不展示了, 根据个人喜好来实现即可.


至此, 评论功能就全部实现了~

相关文章:

文章详情页 - 评论功能的实现

目录 1. 准备工作 1.1 创建评论表 1.2 创建评论实体类 1.3 创建 mapper 层评论接口和对应的 xml 实现 1.4 准备评论的 service 层 1.5 准备评论的 controller 层 2. 总的初始化详情页 2.1 加载评论列表 2.1.1 实现前端代码 2.1.2 实现后端代码 2.2 查询当前登录用户的…...

使用贝叶斯滤波器通过运动模型和嘈杂的墙壁传感器定位机器人研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Day 69-70:矩阵分解

代码&#xff1a; package dl;import java.io.*; import java.util.Random;/** Matrix factorization for recommender systems.*/public class MatrixFactorization {/*** Used to generate random numbers.*/Random rand new Random();/*** Number of users.*/int numUsers…...

数据结构:树的存储结构

学习树之前&#xff0c;我们已经了解了二叉树的顺序存储和链式存储&#xff0c;哪么我们如何来存储普通型的树结构的数据&#xff1f;如下图1&#xff1a; 如图1所示&#xff0c;这是一颗普通的树&#xff0c;我们要如何来存储呢&#xff1f;通常&#xff0c;存储这种树结构的数…...

Vue前端渲染blob二进制对象图片的方法

近期做开发&#xff0c;联调接口。接口返回的是一张图片&#xff0c;是对二进制图片处理并渲染&#xff0c;特此记录一下。 本文章是转载文章&#xff0c;原文章&#xff1a;Vue前端处理blob二进制对象图片的方法 接口response是下图 显然&#xff0c;获取到的是一堆乱码&…...

Java的标记接口(Marker Interface)

Java中的标记接口&#xff08;Marker Interface&#xff09;是一个空接口&#xff0c;接口内什么也没有定义。它标识了一种能力&#xff0c;标识继承自该接口的接口、实现了此接口的类具有某种能力。 例如&#xff0c;jdk的com.sun.org.apache.xalan.internal.xsltc.trax.Temp…...

Kafka基础架构与核心概念

Kafka简介 Kafka是由Apache软件基金会开发的一个开源流处理平台&#xff0c;由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。架构特点是分区、多副本、多生产者、多订阅者&#xff0c;性能特点主要是…...

观察者模式与观察者模式实例EventBus

什么是观察者模式 顾名思义&#xff0c;观察者模式就是在多个对象之间&#xff0c;定义一个一对多的依赖&#xff0c;当一个对象状态改变时&#xff0c;所有依赖这个对象的对象都会自动收到通知。 观察者模式也称为发布订阅模式(Publish-Subscribe Design Pattern)&#xff0…...

科普 | OSI模型

本文简要地介绍 OSI 模型 1’ 2’ 3。 更新&#xff1a;2023 / 7 / 23 科普 | OSI模型 术语节点链路协议网络拓扑 概念作用结构应用层表示层会话层传输层网络层数据链路层物理层 数据如何流动OSI 和TCP/IP 的对应关系和协议参考链接 术语 节点 节点&#xff08; Node &#…...

redis相关异常之RedisConnectionExceptionRedisCommandTimeoutException

本文只是分析Letture类型的Redis 池化连接出现的连接超时异常、读超时异常问题。 1.RedisConnectionException 默认是10秒。 通过如下可以配置&#xff1a; public class MyLettuceClientConfigurationBuilderCustomizer implements LettuceClientConfigurationBuilderCusto…...

Merge the squares! 2023牛客暑期多校训练营4-H

登录—专业IT笔试面试备考平台_牛客网 题目大意&#xff1a;有n*n个边长为1的小正方形摆放在边长为n的大正方形中&#xff0c;每次可以选择不超过50个正方形&#xff0c;将其合并为一个更大的正方形&#xff0c;求一种可行的操作使所有小正方形都被合并成一个n*n的大正方形 1…...

STM32 串口学习(二)

要用跳线帽将PA9与RXD相连&#xff0c;PA10与TXD相连。 软件设计 void uart_init(u32 baud) {//UART 初始化设置UART1_Handler.InstanceUSART1; //USART1UART1_Handler.Init.BaudRatebound; //波特率UART1_Handler.Init.WordLengthUART_WORDLENGTH_8B; //字长为 8 位数据格式U…...

点大商城V2_2.5.0 全开源版 商家自营+多商户入驻 百度+支付宝+QQ+头条+小程序端+unipp开源前端安装测试教程

安装测试环境&#xff1a;Nginx 1.20PHP7.2MySQL 5.6 修复了无法上传开放平台问题 安装说明&#xff1a; 1、上传后端目录至网站 2、导入提供的数据库文件 3、修改数据库配置文件根目录下config.php&#xff0c;增加数据库用户名和密码 4、网站后台直接访问网址&#xff…...

“深入理解SpringBoot:从入门到精通“

标题&#xff1a;深入理解Spring Boot&#xff1a;从入门到精通 摘要&#xff1a;本文将介绍Spring Boot的基本概念和核心特性&#xff0c;并通过示例代码演示如何使用Spring Boot构建一个简单的Web应用程序。 1. 简介 Spring Boot是一个开源的Java框架&#xff0c;旨在简化基…...

PCB绘制时踩的坑 - SOT-223封装

SOT-223封装并不是同一的&#xff0c;细分的话可以分为两种常用的封装。尤其是tab脚的属性很容易搞错。如果你想着用tab脚连接有属性的铺铜&#xff0c;来提高散热效率&#xff0c;那么你一定要注意你购买的器件tab脚的属性。 第一种如下图&#xff0c;第1脚为GND&#xff0c;第…...

Go语法入门 + 项目实战

&#x1f442; Take me Hand Acoustic - Ccile Corbel - 单曲 - 网易云音乐 第3个小项目有问题&#xff0c;不能在Windows下跑&#xff0c;懒得去搜Linux上怎么跑了&#xff0c;已经落下进度了.... 目录 &#x1f633;前言 &#x1f349;Go两小时 &#x1f511;小项目实战 …...

QT控件通过qss设置子控件的对齐方式、大小自适应等

一些复杂控件&#xff0c;是有子控件的&#xff0c;每个子控件&#xff0c;都可以通过qss的双冒号选择器来选中&#xff0c;进行独特的样式定义。很多控件都有子控件&#xff0c;太多了&#xff0c;后面单独写一篇文章来介绍各个控件的子控件。这里就随便来几个例子 例如下拉列…...

基于java在线收银系统设计与实现

摘要 科技的力量总是在关键的地方改变着人们的生活&#xff0c;不仅如此&#xff0c;我们的生活也是离不开这样或者那样的科技改变&#xff0c;有的消费者没有时间去商场购物&#xff0c;那么电商和快递的结合让端口到消费者的距离不再遥远&#xff1b;有的房客因地域或者工作的…...

Linux--进程的新建状态

新建状态&#xff1a; 操作系统创建了进程的内核数据结构&#xff08;task_struct、mm_struct、页表&#xff09;&#xff0c;但是页表没有创建映射关系&#xff0c;而且磁盘里的程序的代码和数据未加载到物理内存...

区间dp,合并石子模板题

设有 N 堆石子排成一排&#xff0c;其编号为 1,2,3,…,N。 每堆石子有一定的质量&#xff0c;可以用一个整数来描述&#xff0c;现在要将这 N 堆石子合并成为一堆。 每次只能合并相邻的两堆&#xff0c;合并的代价为这两堆石子的质量之和&#xff0c;合并后与这两堆石子相邻的…...

C++代码格式化工具clang-format详细介绍

文章目录 clang-format思考代码风格指南生成您的配置运行 clang-format禁用一段代码的格式设置clang-format的设置预览 clang-format 我曾在许多编程团队工作过&#xff0c;这些团队名义上都有“编程风格指南”。该指南经常被写下来并放置在开发人员很少查看的地方。几乎在每种…...

CentOS 7安装PostgreSQL 15版本数据库

目录 一、何为PostgreSQL&#xff1f; 二、PostgreSQL安装 2.1安装依赖 2.2 执行安装 2.3 数据库初始化 2.4 配置环境变量 2.5 创建数据库 2.6 配置远程 2.7 测试远程 三、常用命令 四、用户创建和数据库权限 一、何为PostgreSQL&#xff1f; PostgreSQL是以加州大学…...

QGraphicsView实现简易地图2『瓦片经纬度』

前文链接&#xff1a;QGraphicsView实现简易地图1『加载离线瓦片地图』 地图采用GCJ02 Web 墨卡托投影&#xff0c;最小坐标&#xff1a;(-180.00000000000000,-85.05112877980655)&#xff0c;最大坐标&#xff1a;(180.00000000000000,85.05112877980655)。瓦片地图单张图片像…...

医学图像重建—第一章笔记

序言 本书涵盖内容&#xff1a; 2D parallel beam imaging 2D fan beam imaging 3D parallel ray imaging 3D parallel plane imaging 3D cone beam imaging 算法包括&#xff1a;analytical method&#xff0c;iterative method 应用于&#xff1a; X-ray CT single photon…...

python-pytorch基础之神经网络分类

这里写目录标题 生成数据函数定义数据集定义loader加载数据定义神经网络模型测试输出是否为2个输入数据&#xff0c;输出结果 训练模型函数计算正确率 训练数据并保存模型测试模型准备数据加载模型预测对比结果 生成数据函数 import randomdef get_rectangle():widthrandom.ra…...

【C++ 程序设计】实战:C++ 变量实践练习题

目录 01. 变量&#xff1a;定义 02. 变量&#xff1a;初始化 03. 变量&#xff1a;参数传递 04. 变量&#xff1a;格式说明符 ① 占位符 “%d” 改为格式说明符 “%llu” ② 占位符 “%d” 改为格式说明符 “%f” 或 “%e” 05. 变量&#xff1a;字节数统计 06. 变量&a…...

微软对Visual Studio 17.7 Preview 4进行版本更新,新插件管理器亮相

近期微软发布了Visual Studio 17.7 Preview 4版本&#xff0c;而在这个版本当中&#xff0c;全新设计的扩展插件管理器将亮相&#xff0c;并且可以让用户可更简单地安装和管理扩展插件。 据了解&#xff0c;目前用户可以从 Visual Studio Marketplace 下载各式各样的 VS 扩展插…...

Kafka 入门到起飞 - Kafka怎么做到保障消息不会重复消费的? 消费者组是什么?

Kafka怎么做到避免消息重复消费的&#xff1f; 消费者组是什么&#xff1f; 消费者&#xff1a; 1、订阅Topic&#xff08;主题&#xff09; 2、从订阅的Topic消费&#xff08;pull&#xff09;消息&#xff0c; 3、将消费消息的offset&#xff08;偏移量&#xff09;保存在K…...

MongoDB 的增、查、改、删

Monogo使用 增 单条增加 db.member.insertOne({"name":"张三","age":18,"create":new Date()}) db.member.insert({"name":"李四1","age":18,"create":new Date()}) db.member.insertOne(…...

mysql常用操作命令

mysql常用操作命令 mysql:单进程多线程模型,一个SQL语句无法利用多个cpu core 一:基本命令 0.查看当前连接数 show global status like Thread$; show variables like "%timeout%"; show variables like "log_%";1.查看当前连接状态 show processlist…...

营销网站设计方案/网站推广模式

本文实例讲述了Python本地与全局命名空间用法。分享给大家供大家参考。具体如下&#xff1a;x 1def fun(a):b3x4def sub(c):dbglobal xx 7print ("Nested Function\n")print locals()sub(5)print ("\nFunction\n")print locals()print locals()["x&…...

有限责任公司章程/seo入门基础知识

“小懒&#xff0c;为什么IDM下载视频没有声音啊&#xff1f;”“为什么下载的视频只有一小段呢&#xff1f;”一般遇到这类问题&#xff0c;大概率是用IDM下载了分段加密的视频诸如“爱优腾”这些大视频平台&#xff0c;为了防止咱下载他们的视频都会将一个视频分成无数小段&a…...

石家庄网站开发费用/网络营销外包收费

骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 747 Accepted Submission(s): 479 Problem Description在2n的一个长方形方格中,用一个1 2的骨牌铺满方格,输入n ,输出铺放方案的总数.例如n3时,为2 3方格&…...

查企业资质上什么网站/深圳网络营销策划

tar -zxvf pycharm-community-2022.1.2.tar.gz cd pycharm-community-2022.1.2/bin sh pycharm.sh启动&#xff1a; sh pycharm.sh 创建快捷方式 打开pycharm在工具中选创建桌面条目即可 Tools -> Create Desktop Entry...

wordpress 交易模板/百度最新人工智能

2019独角兽企业重金招聘Python工程师标准>>> Linux crontab命令 Linux 命令大全 Linux crontab是用来定期执行程序的命令。 当安装完成操作系统之后&#xff0c;默认便会启动此任务调度命令。 crond命令每分锺会定期检查是否有要执行的工作&#xff0c;如果有要执行…...

网页制作与网站建设宝典 pdf/网站建设是什么

0&#xff1a;引言 Zenfone2性价比高&#xff0c;但是原生的华硕系统&#xff0c;无法root,加上google那一套东西无法安装&#xff0c;所以开始了折腾过程&#xff0c;自行youtube,google后刷机成功&#xff0c;现在刷机详细过程和需要材料记录一番&#xff01; 注意&#xff1…...