【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用

【JavaEE】进阶 · 个人博客系统(4)

在这里插入图片描述

文章目录

  • 【JavaEE】进阶 · 个人博客系统(4)
    • 1. 增加博文
    • 1.1 预期效果
      • 1.1 约定前后端交互接口
      • 1.2 后端代码
      • 1.3 前端代码
      • 1.4 测试
    • 2. 我的博客列表页
      • 2.1 期待效果
      • 2.2 显示用户信息以及博客信息
        • 2.2.1 约定前后端交互接口
        • 2.2.2 后端代码
        • 2.2.3 前端代码
        • 2.2.4 测试
      • 2.3 删除文章
        • 2.3.1 约定前后端交互接口
        • 2.3.2 后端代码
        • 2.3.3 前端代码
        • 2.3.4 测试
      • 2.4 退出登录
        • 2.4.1 约定前后端交互接口
        • 2.4.2 后端代码
        • 2.4.3 前端代码
        • 2.4.4 测试
    • 3. 修改文章
      • 3.1 页面初始化
        • 3.1.1 约定前后端接口
        • 3.1.2 后端代码
        • 3.1.3 前端代码
        • 3.1.4 测试
      • 3.2 修改文章
        • 3.2.1 约定前后端交互接口
        • 3.2.2 后端代码
        • 3.2.3 前端代码
        • 3.2.4 测试
    • 4. 博客详情页
      • 4.1 期待效果
      • 4.2 约定前后端交换接口
      • 4.3 后端代码
      • 4.4 前端代码
      • 4.5 测试

【JavaEE】进阶 · 个人博客系统(4)

1. 增加博文

1.1 预期效果

a

用户在网页中编写标题和正文,点击提交,选择

  1. 输入摘要
  2. 取消,继续编写文章

提交成功后,选择

  1. 继续写文章
  2. 返回“我的博客列表页”

1.1 约定前后端交互接口

后端:

  1. /art/publish
  2. 将前端传递过来的数据保存到数据库
  3. 返回受影响行数

前端:

  1. /art/publish
  2. 标题,正文,摘要
  3. 当前登录用户sessionid

1.2 后端代码

在这里插入图片描述

  1. controller层

由于经常需要对字符串进行检查,我封装了一个方法:

  • 为什么前端检验完了,后端还检验呢?
    • 千万别相信“前端”,因为这个“前端”,可能不是浏览器正常的流程,也可能是通过postman等方式发送的请求,这个就可以绕开前端代码的校验~
    • 不用担心,因为
public class APPUtils {/*** 字符串全部都有长度才返回true* @param strings* @return*/public static boolean hasLength(String... strings) {for(String x : strings) {if(!StringUtils.hasLength(x)) {return false;}}return true;}
}

修改:

在这里插入图片描述

在这里插入图片描述

@RequestMapping("/publish")
public CommonResult publish(@RequestBody ArticleInfo articleInfo, HttpServletRequest request) {// 1. 获取当前用户详信息UserInfo userInfo = SessionUtils.getUser(request);articleInfo.setUid(userInfo.getId());articleInfo.setPhoto(userInfo.getPhoto());// 2. 校验参数if(!APPUtils.hasLength(articleInfo.getContent(), articleInfo.getSummary(), articleInfo.getTitle())) {return CommonResult.fail(-1, "非法参数!");}// 3. 提交到数据库中int rows = articleService.publish(articleInfo);// 4. 返回return CommonResult.success(rows);
}
  1. service层
@Autowired
private ArticleMapper articleMapper;public int publish(ArticleInfo articleInfo) {return articleMapper.insert(articleInfo);    
}
  1. mapper层
@Insert("insert into articleinfo (title, content, summary, uid, photo) values (#{title}, #{content}, #{summary}, #{uid}, #{photo})")
int insert(ArticleInfo articleInfo);
  1. 拦截器配置
    • 拦截,不排除此接口

1.3 前端代码

在这里插入图片描述

function publish() {var title = jQuery("#text");var content = jQuery("#content");// 1. 参数校验if (title.val().trim() == "") {alert("标题不能为空!");title.focus();return false;}if (content.val().trim() == "") {alert("正文不能为空!");content.focus();return false;}// 2. 输入摘要var summary = prompt("请输入摘要:");if(summary == "") {return false;}// 3. 发送请求jQuery.ajax({url: "/art/publish",method: "POST",contentType: "application/json; charset=utf8",data: JSON.stringify({title: title.val().trim(),content: content.val().trim(),summary: summary.val().trim(),}),// 3. 处理响应success: function (body) {if (body.code == 200 && body.data == 1) {if(confirm("发布成功!请问是否继续创作?")) {location.href = location.href;}else {location.href = "myblog_lists.html";}} else {alert("发布失败:" + body.msg);}},});
}

1.4 测试

在这里插入图片描述

在这里插入图片描述

为了避免写文章过程中session过去,我将session设置为永不过期:

在这里插入图片描述

2. 我的博客列表页

2.1 期待效果

在这里插入图片描述

  1. 左侧窗口显示用户信息
  2. 右侧窗口显示用户创作的博文简介
    1. 标题
    2. 时间以及阅读量
    3. 摘要
    4. 查看正文,修改文章,删除文章按钮
  3. 右上角
    1. 点击主页跳转到所有人的博客列表页
    2. 点击写博客跳转到博客创作页
    3. 点击退出登录,后端删除登录记录,跳转到登录页面

2.2 显示用户信息以及博客信息

2.2.1 约定前后端交互接口

后端:

  1. /article/get_mylist
  2. 通过当前登录用户查询博客
  3. 返回用户信息以及博客信息的组合

前端:

  1. /article/get_mylist
  2. get
  3. 接受响应,投喂给页面

2.2.2 后端代码

  1. controller层
@RequestMapping("/get_mylist")
public CommonResult getMylist(HttpServletRequest request) {// 1. 获取当前登录用户UserInfo userInfo = SessionUtils.getUser(request);// 2. 通过此用户发布的所有文章List<ArticleInfo> list = articleService.getListByUid(userInfo.getId());// 3. 标题 / 正文太长 处理ArticleUtils.substringList(list);// 4. 返回给前端Map<String, Object> map = new HashMap<>();map.put("user", userInfo);map.put("list", list);return CommonResult.success(map);
}
// 文章工具类
public class ArticleUtils {//标题截取长度private static final int _TITLE_LENGTH = 40;//摘要截取长度private static final int _SUMMARY_LENGTH = 160;public static void substringList(List<ArticleInfo> list) {if(list != null && list.size() != 0) {// 并发处理 list 集合list.stream().parallel().forEach((art) -> {//标题截取if(art.getTitle().length() > _TITLE_LENGTH) {art.setTitle(art.getTitle().substring(0, _TITLE_LENGTH) + "...");}//摘要截取if(art.getSummary().length() > _SUMMARY_LENGTH) {art.setSummary(art.getSummary().substring(0, _SUMMARY_LENGTH) + "...");}});}}
}
  1. service层
public List<ArticleInfo> getListByUid(int uid) {return articleMapper.getListByUid(uid);
}
  1. mapper层
@Select("select * from articleinfo where uid = #{uid} order by id desc")
List<ArticleInfo> getListByUid(@Param("uid") int uid); //越晚发布排在越前
  1. 拦截器配置
    • 不排除此接口
  2. 时间格式配置

可以接受数据库时间的类型一般是:

  1. Date
  2. LocalDataTime
  3. TimeStamp

网络资料

LocalDateTime和Date是Java中表示日期和时间的两种不同的类,它们有一些区别和特点。

  1. 类型:LocalDateTime是Java 8引入的新类型,属于Java 8日期时间API(java.time包)。而Date是旧版Java日期时间API(java.util包)中的类。

  2. 不可变性:LocalDateTime是不可变的类型,一旦创建后,其值是不可变的。而Date是可变的类型,可以通过方法修改其值。

  3. 线程安全性:LocalDateTime是线程安全的,多个线程可以同时访问和操作不同的LocalDateTime实例。而Date是非线程安全的,如果多个线程同时访问和修改同一个Date实例,可能会导致不可预期的结果。

  4. 时间精度:LocalDateTime提供了纳秒级别的时间精度,可以表示更加精确的时间。而Date只能表示毫秒级别的时间精度。

  5. 时区处理:LocalDateTime默认不包含时区信息,表示的是本地日期和时间。而Date则包含时区信息,它的实际值会受到系统默认时区的影响。

而TimeStamp就是long类型的时间戳的包装~

对于时间格式的控制:

  1. json的构造本身是通过getter去获取的,所以可以重写getter来控制显示效果

  2. 全局配置:

    在这里插入图片描述

    但是这只适合jdk8之前的Date类型

  3. 局部配置:

    • 对于时间类型的属性,是可以通过注解@JsonFormat来配置的:

    在这里插入图片描述

2.2.3 前端代码

左:

在这里插入图片描述

右:

在这里插入图片描述

jQuery.ajax({type: "get",url: "/art/get_mylist",success: function (body) {if (body.code == 200) {// 1. 改变左侧窗口jQuery(".card img").attr("src", body.data.user.photo);jQuery(".card h3").text(body.data.user.name);if(body.data.user.git.trim() != "") {jQuery(".card a").attr("href", body.data.user.git);}jQuery("#count").text(body.data.list.length);// 2. 显示文章,构造博客html元素for (var blog of body.data.list) {console.log(body.title);var art ='<div class="blog"><div class="title">' + blog.title + "</div>";art +='<div class="date">' +blog.createtime +" 阅读量:" +blog.rcount +"</div>";art += '<div class="content">' + blog.summary + "</div>";art += '<div class="thing">';art +='<a href="blog_detail.html?aid=' + blog.id + '">查看正文</a>';art +='<a href="myblog_update.html?aid=' + blog.id + '">修改文章</a>';art +='<div id="del" style="background-color: rgba(255, 0, 0, 0.6)" οnclick="del(' +blog.id +')">删除文章</div>';art += "</div></div>";// 3. 追加到div.articlejQuery(".article").append(jQuery(art));}}},
});

你也可以,以标签为单位去设置属性以及嵌套,这有逻辑的构建;而我这里是单纯的拼接字符串,用jQuery(str),构造html元素

2.2.4 测试

在这里插入图片描述

2.3 删除文章

2.3.1 约定前后端交互接口

后端:

  1. /art/delete
  2. 根据当前登录用户id,和删除文章对应的作者id,判断是否有权限删除,有才能删除
  3. 返回受影响行数

前端:

  1. /art/delete
  2. post
  3. JSON:id(文章id)
  4. 如果受影响行数为1,刷新页面

2.3.2 后端代码

  1. controller层
@RequestMapping("/delete")
public CommonResult delete(@RequestBody ArticleInfo articleInfo, HttpServletRequest request) {// 1. 获取当前登录用户的idint uid = SessionUtils.getUser(request).getId();// 2. 设置到文章对象里articleInfo.setUid(uid);// 3. 删除int rows = articleService.delete(articleInfo);// 4. 返回return CommonResult.success(rows);
}
  1. service层
public int delete(ArticleInfo articleInfo) {return articleMapper.delete(articleInfo);
}
  1. mapper层
@Delete("delete from articleinfo where id = #{id} and uid = #{uid}")
// 查找文章和检测权限在一步搞定
int delete(ArticleInfo articleInfo);
  1. 拦截器配置
    • 拦截,不排除

2.3.3 前端代码

function del(aid) {// 0. 参数校验if (parseInt(aid) == NaN || aid <= 0) {return false;}jQuery.ajax({method: "post",url: "/art/delete",contentType: "application/json; charset=utf8",data: JSON.stringify({id: aid,}),success: function (body) {if (body.code == 200 && body.data == 1) {location.href = location.href;} else {alert("删除失败!\n");}},});
}

2.3.4 测试

在这里插入图片描述

2.4 退出登录

2.4.1 约定前后端交互接口

后端:

  1. /user/logout
  2. 根据当前用户进行删session操作
  3. 无返回值

前端:

  1. /user/logout
  2. a标签的get

2.4.2 后端代码

  1. controller层
@RequestMapping("/logout")
public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {// 设置为null也可以,但这是因为我们的判断原理的原因//SessionUtils.setUser(request, null);// 调用工具类里的注销方法SessionUtils.remove(request);response.sendRedirect("blog_login.html");
}
/*** 注销* @param request*/
public static void remove(HttpServletRequest request) {HttpSession session = request.getSession(false);if(session != null && session.getAttribute(ApplicationVariable.SESSION_KEY) != null) {session.removeAttribute(ApplicationVariable.SESSION_KEY);}
}
  1. 拦截器配置
    • 拦截,不排除

2.4.3 前端代码

<a href="/user/logout">退出登录</a>

2.4.4 测试

在这里插入图片描述

3. 修改文章

在这里插入图片描述
在这里插入图片描述

预期效果就是:原有数据显示出来,供用户修改

3.1 页面初始化

3.1.1 约定前后端接口

后端:

  1. /art/get_art
  2. 根据uid和aid查询文章
  3. 返回文章信息

前端:

  1. /art/get_art
  2. post,json,aid
  3. 将数据投喂到网页

3.1.2 后端代码

  1. controller层
@RequestMapping("/get_art")
public CommonResult getArt(@RequestBody ArticleInfo articleInfo, HttpServletRequest request) {// 1. 获取当前登录用户的idint uid = SessionUtils.getUser(request).getId();// 2. 设置到文章对象里articleInfo.setUid(uid);// 3. 查询文章ArticleInfo art = articleService.getArt(articleInfo);// 4. 返回(查询不到一个对象,是null;如果查询不到对象集合,返回的是空集合)return art == null ? CommonResult.fail(-1, "查询不到!") : CommonResult.success(art);
}
  1. service层
public ArticleInfo getArt(ArticleInfo articleInfo) {return articleMapper.getArticleCheck(articleInfo);
}
  1. mapper层
@Select("select * from articleinfo where id = #{id} and uid = #{uid}")
ArticleInfo getArticleCheck(ArticleInfo articleInfo);//检查权限的查询文章@Select("select * from articleinfo where id = #{id}")
ArticleInfo getArticle(ArticleInfo articleInfo);
  1. 拦截器配置
    • 拦截,不排除

3.1.3 前端代码

<script>var aid = getParamValue("aid");// 1. 校验参数function init() {if (aid == null || aid <= 0) {alert("非法参数!");location.href = "myblog_lists.html";return false;}// 2. 查询文章jQuery.ajax({url: "/art/get_art",method: "post",contentType: "application/json; charset=utf8",data: JSON.stringify({id: aid,}),success: function (body) {if (body.code == 302) {location.href = body.msg;return false;}if (body.code == 200) {jQuery("#text").val(body.data.title);jQuery("#content").val(body.data.content);jQuery("#summary").val(body.data.summary);//用隐藏输入框保存摘要信息} else {alert("发布失败:" + body.msg);}},});}init();
</script>

在这里插入图片描述

注意:

  1. 如果直接写代码的话,而不是调用方法,默认页面跟代码一起加载,而调用方法是页面加载后调用此init方法
    • 如果不采取这种方式的话,会导致请求返回的页面,被拦截器拦下
  2. 为什么还是用json而不是用querystring直接发送请求
    • 习惯吧,因为json比较通用,如果还需要其他信息,querystring不方便
  3. 修改页跟添加页是一样的,为什么不重用?
    • 重用会导致一些没有必要的判断,不符合单一设计原则,麻烦/乱/开发不舒适,耦合度高…

3.1.4 测试

在这里插入图片描述

3.2 修改文章

3.2.1 约定前后端交互接口

后端:

  1. /art/update
  2. 接受文章数据
  3. 返回受影响行数

前端:

  1. /art/update
  2. post,json,上传文章数据
  3. 成功则跳转到我的博客列表页

3.2.2 后端代码

  1. controller层
@RequestMapping("/update")
public CommonResult update(@RequestBody ArticleInfo articleInfo, HttpServletRequest request) {// 0. 确认用户int uid = SessionUtils.getUser(request).getId();articleInfo.setUid(uid);// 1. 校验参数if(!APPUtils.hasLength(articleInfo.getContent(), articleInfo.getSummary(), articleInfo.getTitle())) {return CommonResult.fail(-1, "非法参数!");}// 2. 修改int rows = articleService.update(articleInfo);// 3. 返回return CommonResult.success(rows);
}
  1. service层
public int update(ArticleInfo articleInfo) {return articleMapper.updateArticle(articleInfo);
}
  1. mapper层
    • 必须是有权限才能修改
    • 更新时间修改为当下
@Update("update articleinfo set content = #{content}, title = #{title}, summary = #{summary}, updatetime = now() where id = #{id} and uid = #{uid}")
int updateArticle(ArticleInfo articleInfo);
  1. 拦截器配置
    • 拦截,不排除

3.2.3 前端代码

在这里插入图片描述

function update() {if (aid == null || aid <= 0) {alert("非法参数!");location.href = "myblog_lists.html";return false;}var title = jQuery("#text");var content = jQuery("#content");// 1. 参数校验if (title.val().trim() == "") {alert("标题不能为空!");title.focus();return false;}if (content.val().trim() == "") {alert("正文不能为空!");content.focus();return false;}// 2. 输入摘要var summary = prompt("请输入摘要:", jQuery("#summary").val());if (summary.trim() == "") {return false;}jQuery("#summary").val(summary);// 3. 发送请求jQuery.ajax({url: "/art/update",method: "POST",contentType: "application/json; charset=utf8",data: JSON.stringify({id: aid,title: title.val().trim(),content: content.val().trim(),summary: summary.trim(),}),// 3. 处理响应success: function (body) {if (body.code == 302) {location.href = body.msg;return false;}if (body.code == 200 && body.data == 1) {location.href = "myblog_lists.html";} else {alert("修改失败:" + body.msg);}},});
}

3.2.4 测试

4. 博客详情页

4.1 期待效果

在这里插入图片描述

  1. 根据是否登录,改变导航栏
  2. 根据querystring中的aid,显示对应的博文,和作者信息
  3. 每次访问成功,阅读量加1(本次显示是加1之前)
  4. 作者的文章总数通过后端计算
  5. 正文以html的样式渲染出来

这样的复杂查询可以用到并发编程:

  • 【JavaEE】Callable接口(NO.6线程创建方法)-JUC的常见类-与线程安全有关集合类_s:103的博客-CSDN博客
  • 用有返回值的线程创建方式(获取的时候若未结束,等待…)

4.2 约定前后端交换接口

后端:

  1. /art/detail
  2. 通过aid,找到文章
  3. 通过文章,uid找到作者,查询总文章数,通过aid修改文章阅读量
  4. 返回:
    1. “login”,true/false,true代表登录中
    2. “count”,文章数
    3. “user”,用户
    4. “art”,文章

前端:

  1. /art/detail
  2. json,aid
  3. 接受响应,投喂给代码

4.3 后端代码

  1. controller层
    1. 查询文章信息
    2. 校验文章是否存在
    3. 根据uid查询用户总文章数的任务
    4. 根据uid查询用户信息的任务
    5. 根据aid更新阅读量的任务
    6. 线程池执行任务
    7. 构造响应数据,并返回
@Autowired
private ArticleService articleService;
@Autowired
private UserService userService;
@RequestMapping("/detail")
public CommonResult detail(@RequestBody ArticleInfo articleInfo, HttpServletRequest request) throws ExecutionException, InterruptedException {// 1. 查询文章信息ArticleInfo art = articleService.getArtByAid(articleInfo);// 2. 校验文章是否存在if(art == null) {return CommonResult.fail(-1, "非法参数!");}// 3. 根据uid查询用户总文章数的任务FutureTask<Integer> task1 = new FutureTask<Integer>(() -> {return articleService.getArtNumberByUid(art.getUid());});// 4. 根据uid查询用户信息的任务FutureTask<UserInfo> task2 = new FutureTask<UserInfo>(() -> {return userService.getUserByUid(art.getUid());});// 5. 根据aid更新阅读量的任务FutureTask<Integer> task3 = new FutureTask<Integer>(() -> {return articleService.incrementRCount(art.getId());});// 6. 线程池执行任务APPUtils.THREAD_POOL.submit(task1);APPUtils.THREAD_POOL.submit(task2);APPUtils.THREAD_POOL.submit(task3);// 7. 构造响应数据,并返回Map<String, Object> map = new HashMap<>();map.put("login", SessionUtils.getUser(request) != null);map.put("count", task1.get());map.put("user", task2.get());map.put("art", art);return CommonResult.success(map);
}

在这里插入图片描述

  1. service层

ArticleService:

public int getArtNumberByUid(int uid) {return articleMapper.getArtNumberByUid(uid);
}public int incrementRCount(int aid) {return articleMapper.incrementRCount(aid);
}

UserService:

public UserInfo getUserByUid(int uid) {return userMapper.getUserByUid(uid);
}
  1. mapper层

ArticleMapper:

@Select("select count(*) from articleinfo where uid=#{uid}")
int getArtNumberByUid(@Param("uid") int uid);@Update("update articleinfo set rcount = rcount + 1 where id = #{aid}")
int incrementRCount(@Param("aid") int aid);

UserMapper:

@Select("select * from userinfo where id = #{uid}")
UserInfo getUserByUid(@Param("uid") int uid);
  1. 拦截器配置
    • 排除拦截
    • editor.md是个目录,要排除整个目录才对,不然后面渲染不上去,之前可以渲染是因为我们处于登录状态~
    • 因为详情页不需要登录~

在这里插入图片描述

4.4 前端代码

  1. 导航栏

在这里插入图片描述

  • 网页图标

在这里插入图片描述

  1. 右侧用户卡片

在这里插入图片描述

  1. 右侧文章信息

在这里插入图片描述

var aid = getParamValue("aid");
function init() {if (aid == null || aid <= 0) {alert("非法参数!");return false;}jQuery.ajax({method: "post",url: "/art/detail",contentType: "application/json; charset=utf8",data: JSON.stringify({id: aid,}),success: function (body) {if (body.code == 200) {// 1. 导航栏显示if (body.data.login == false) {jQuery("#icon").attr("href", "img/logo2.png");jQuery(".navigation img").attr("src", " img/logo2.png");jQuery(".navigation .space").css("width", "75%");jQuery(".title").text("未登录");jQuery("#add").hide();jQuery("#logout").text("登录");jQuery("#logout").attr("href", "blog_login.html");}// 2. 文章数显示jQuery("#count").text(body.data.count);// 3. 用户信息显示jQuery(".card img").attr("src", body.data.user.photo);jQuery(".card h3").text(body.data.user.name);if (body.data.user.git.trim() != "") {jQuery(".card a").attr("href", body.data.user.git);}// 4. 文章信息显示jQuery(".article h3").text(body.data.art.title);jQuery(".article .date").text(body.data.art.createtime + " 阅读量:" + body.data.art.rcount);editormd.markdownToHTML("pc", {markdown: body.data.art.content,});} else {alert("查看失败:" + body.msg);}},});
}
init();

4.5 测试

在这里插入图片描述


文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆

代码:myblog_system/src · 游离态/马拉圈2023年9月 - 码云 - 开源中国 (gitee.com)


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

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

相关文章

Kotlin管道Channel在receiveAsFlow时debounce与flow差异

Kotlin管道Channel在receiveAsFlow时debounce与flow差异 import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.coroutine…

kafka学习-概念与简单实战

目录 1、核心概念 消息和批次 Topic和Partition Replicas Offset broker和集群 生产者和消费者 2、开发实战 2.1、消息发送 介绍 代码实现 2.2、消息消费 介绍 代码实现 2.3、SpringBoot Kafka pom application.yaml KafkaConfig producer consumer 1、核心…

【Spring MVC】统一功能处理

一、登录验证 登录验证通过拦截器实现&#xff0c;拦截器就是在用户访问服务器时&#xff0c;预先拦截检查一下用户的访问请求。 没有拦截器时&#xff0c;用户访问服务器的流程是&#xff1a;用户–>controller–>service–>Mapper。有拦截器时&#xff0c;用户访问…

RouterOS-配置PPPoEv4v6 Server

1 接口 ether3 出接口 ether4 内网接口 2 出接口 出接口采用PPPoE拨号SLAAC获取前缀&#xff0c;手动配置后缀 2.1 选择出接口interface&#xff0c;配置PPPoE client模式 2.2 配置PPPoE client用户名和密码 2.3 从PPPoE client获取前缀地址池 2.4 给出接口选择前缀并配置…

第10章_索引优化与查询优化(覆盖索引, 索引下推等)

4. 子查询优化 MySQL 从 4.1 版本开始支持子查询&#xff0c;使用子查询可以进行 SELECT 语句的嵌套查询&#xff0c;即一个 SELECT 查询的结果作为另一个SELECT 语句的条件。 子查询可以一次性完成很多逻辑上需要多个步骤才能完成的 SQL 操作 。 子查询是 MySQL 的一项重…

Vue + Element UI 前端篇(七):功能组件封装

组件封装 为了避免组件代码的臃肿&#xff0c;这里对主要的功能部件进行封装&#xff0c;保证代码的模块化和简洁度。 组件结构 组件封装重构后&#xff0c;试图组件结构如下图所示 代码一览 Home组件被简化&#xff0c;包含导航、头部和主内容三个组件。 Home.vue <te…

vue优化首屏加载时间优化-cdn引入第三方包

前言 为什么要进行首屏加载优化&#xff0c;因为随着我们静态资源和第三方包和代码增加&#xff0c;压缩之后包会越来越大 随着网络的影响&#xff0c;在我们第一输入url请求资源时候&#xff0c;网络阻塞&#xff0c;加载时间长&#xff0c;用户体验不好 仔细观察后就会发现…

YOLOV8实例分割——详细记录环境配置、自定义数据处理到模型训练与部署

前言 Ultralytics YOLOv8是一种前沿的、最先进的&#xff08;SOTA&#xff09;模型&#xff0c;它在前代YOLO版本的成功基础上进行了进一步的创新&#xff0c;引入了全新的特性和改进&#xff0c;以进一步提升性能和灵活性。作为一个高速、精准且易于操作的设计&#xff0c;YO…

【计算机网络】http协议

目录 前言 认识URL URLEncode和URLDecode http协议格式 http方法 GET POST GET与POST的区别 http状态码 http常见header 简易的http服务器 前言 我们在序列化和反序列化这一章中&#xff0c;实现了一个网络版的计算器。这个里面设计到了对协议的分析与处…

STL常用容器 (C++核心基础教程之STL容器详解)String的API

在C的标准模板库&#xff08;STL&#xff09;中&#xff0c;有多种容器可供使用。以下是一些常见的容器类型&#xff1a; 序列容器&#xff08;Sequential Containers&#xff09;&#xff1a; std::vector&#xff1a;动态数组&#xff0c;支持快速随机访问。 std::list&…

宠物电商Chewy第二季度销售额28亿美元,同比增长14.3%

美国宠物电商Chewy公布2023年第二季度财报。报告显示&#xff0c;其Q2季度销售额同比增长14.3%至28亿美元&#xff0c;超出市场预期。 以下为Chewy期内业绩概要&#xff1a; 1.毛利率28.3%&#xff0c;同比增长20个基点 2.净利润有所收窄&#xff0c;同比下降15.2%至1890万美…

9.2.tensorRT高级(4)封装系列-自动驾驶案例项目self-driving-深度估计

目录 前言1. 深度估计总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 高级-自动驾驶案例项目self-driving-深度估…

Mybatis学习|Mybatis缓存:一级缓存、二级缓存

Mybatis缓存 MyBatis包含一个非常强大的查询缓存特性&#xff0c;它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。 MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存 默认情况下&#xff0c;只有一级缓存开启。(SqlSession级别的缓存&#xff0c;也称为本地…

Leetcode 1572.矩阵对角线元素之和

给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 示例 1&#xff1a; 输入&#xff1a;mat [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;25 解释&#xff1a;对角线的和为&#xff…

qt.qpa.plugin:找不到Qt平台插件“wayland“|| (下载插件)Ubuntu上解决方案

相信大家也都知道这个地方应该做什么&#xff0c;当然是下载这个qt平台的插件wayland,但是很多人可能不知道怎么下载这个插件。 那么我现在要说的这个方法就是针对这种的。 sudo apt install qtwayland5完事儿了奥兄弟们。 看看效果 正常了奥。

JVM类的加载相关的问题

JVM类的加载相关的介绍 学习类的加载的加载过程对深入理解JVM有十分重要的作用&#xff0c;下面就跟我一起学习JVM类的加载过程吧&#xff01; 文章目录 JVM类的加载相关的介绍一、类的加载过程二、双亲委派机制1、类加载器的种类2、为什么JVM要分成不同的类的加载器3、类的加…

机器人中的数值优化(十)——线性共轭梯度法

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

HDFS 架构剖析

目录 一、HDFS 架构整体概述 二、HDFS 集群角色介绍 2.1 整体概述 2.2 主角色&#xff1a;namenode 2.3 从角色&#xff1a;datanode 2.4 主角色辅助角色&#xff1a; secondarynamenode 三、HDFS 重要特性 3.1 主从架构 3.2 分块存储机制 3.3 副本机制 3.4 …

JVM详细教程

JVM 前言 还在完善中先发布 JVM虚拟机厂家多钟多样&#xff0c;具体实现细节可能不一样&#xff0c;这里主要讲的是虚拟机的规范&#xff0c;以下内容融合了各个平台发布的内容和周志明老师的《深入理解java虚拟机》 JVM概述 如何理解jvm跨平台&#xff1f; 编译成汇编代码…

Vue+elementUI 导出word打印

import JSZipUtils from "jszip-utils"; import JSZip from "pizzip"; import Docxtemplater from "docxtemplater"; npm安装以上依赖 首先维护个word模板 导出方法 //导出wordskipOutWord(row) {var printData rowconst data JSON.parse(JS…