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

博客系统-SpringBoot版本

相比于之前使用Servlet来完成的博客系统,SpringBoot版本的博客系统功能更完善,使用到的技术更接近企业级,快来看看吧~

目录

1.项目介绍

2.数据库准备

3.实体化类

4.返回格式

5.登录和注册功能

6.登出(注销)功能

7.判定是否登录

8.添加、修改、查询、删除文章

9.查询文章列表、分页、展示阅读次数

查询文章列表

展示阅读次数

分页功能

10.拦截器

11.统一异常处理和统一数据返回格式

统一异常处理

统一数据返回格式

12.加盐处理


1.项目介绍

本项目集成了用户注册、用户登录、用户登出(注销)、验证登录状态、添加文章、查询文章、修改文章、展示阅读次数、文章列表查询、删除文章、分页功能。

其中,使用了统一功能处理返回的数据,对密码进行了加盐加密操作,使用拦截器完成验证用户登录状态。

并且使用分层思想:

2.数据库准备

-- 创建数据库
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8mb4;-- 使用数据数据
use mycnblog;-- 创建表[用户表]
drop table if exists  userinfo;
create table userinfo(id int primary key auto_increment,username varchar(100) not null,password varchar(65) not null,photo varchar(500) default '',createtime timestamp default current_timestamp,updatetime timestamp default current_timestamp,`state` int default 1
) default charset 'utf8mb4';-- 创建文章表
drop table if exists  articleinfo;
create table articleinfo(id int primary key auto_increment,title varchar(100) not null,content text not null,createtime timestamp default current_timestamp,updatetime timestamp default current_timestamp,uid int not null,rcount int not null default 1,`state` int default 1
)default charset 'utf8mb4';-- 添加一个用户信息
INSERT INTO `mycnblog`.`userinfo` (`id`, `username`, `password`, `photo`, `createtime`, `updatetime`, `state`) VALUES 
(1, 'admin', 'admin', '', '2024-2-12 17:10:48', '2024-2-12 17:10:48', 1);-- 文章添加测试数据
insert into articleinfo(title,content,uid)values('Java','Java正文',1);

3.实体化类

在createtime和updatetime之前加上时间格式化注释JsonFormat,可以统一时间格式。

4.返回格式

在和前端进行交互的时候,我们新建一个类来完成对所有返回的结果的规定。

包括了返回的状态码code,返回的信息msg,返回的数据data。并且重载success和fail方法。

每个controller返回给前端的数据就是一个AjaxResult success()或者AjaxResult fail();

@Data
public class AjaxResult implements Serializable {private Integer code;private String msg;private Object data;public static AjaxResult success(Object data) {AjaxResult ajaxResult = new AjaxResult();ajaxResult.setCode(200);ajaxResult.setMsg("");ajaxResult.setData(data);return ajaxResult;}public static AjaxResult success(Object data, String msg) {AjaxResult ajaxResult = new AjaxResult();ajaxResult.setCode(200);ajaxResult.setMsg(msg);ajaxResult.setData(data);return ajaxResult;}public static AjaxResult fail(Integer code, String msg) {AjaxResult ajaxResult = new AjaxResult();ajaxResult.setCode(code);ajaxResult.setMsg(msg);ajaxResult.setData("");return ajaxResult;}public static AjaxResult fail(Integer code, String msg, Object data) {AjaxResult ajaxResult = new AjaxResult();ajaxResult.setCode(code);ajaxResult.setMsg(msg);ajaxResult.setData(data);return ajaxResult;}
}

5.登录和注册功能

    <insert id="reg">insert into userinfo(username, password) value (#{username},#{password})</insert><select id="login" resultType="com.example.spring_myblogsystem.entity.UserInfo">select * from userinfowhere username = #{username}</select>
@Mapper
public interface UserMapper {int reg(UserInfo userInfo);UserInfo login(@Param("username") String username);
}
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public int reg(UserInfo userInfo) {return userMapper.reg(userInfo);}public UserInfo login(String username) {return userMapper.login(username);}
}

@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/reg")public AjaxResult reg(UserInfo userInfo) {if (userInfo == null || !StringUtils.hasLength(userInfo.getUsername()) || !StringUtils.hasLength(userInfo.getUsername())) {return AjaxResult.fail(-1, "参数非法");}userInfo.setPassword(PasswordTooles.encrypt(userInfo.getPassword()));int result = userService.reg(userInfo);return AjaxResult.success(result);}@RequestMapping("/login")public AjaxResult login(String username, String password, HttpServletRequest request) {if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return AjaxResult.fail(-1, "参数非法");}UserInfo userInfo = userService.login(username);if (userInfo == null || userInfo.getId() <= 0) {return AjaxResult.fail(-2, "用户名或密码错误");}if (PasswordTooles.decrypt(password, userInfo.getPassword())) {return AjaxResult.fail(-2, "用户名或密码错误");}HttpSession session = request.getSession();session.setAttribute(ApplicationVariale.SESSION_USERINFO_KEY,userInfo);return AjaxResult.success(1);}

在登录过程中,用到了session来判定登录状态,所以在传形参的时候,不光是要传用户名和密码,还需要把request也一起传输过去,用来设置当前session。因为session有多个地方需要使用,所以把session单独拿出来定义:

public class ApplicationVariale {public static final String SESSION_USERINFO_KEY = "SESSION_KEY_USERINFO";}

6.登出(注销)功能

只需要使用removeAttribute来移除session就可以实现注销功能。

    @RequestMapping("/logout")public AjaxResult logout(HttpServletRequest request) {HttpSession session = request.getSession(false);session.removeAttribute(ApplicationVariale.SESSION_USERINFO_KEY);return AjaxResult.success(1);}

7.判定是否登录

在某些页面,需要判定用户是否登录了,比如在博客正文的页面,就需要根据用户登录情况来显示不同的按钮。未登录则显示登录按钮,已经登录了则显示博客主页按钮。

    @RequestMapping("/islogin")public AjaxResult isLogin(HttpServletRequest request) {if (UserSessionTools.getLoginUser(request) == null) {return AjaxResult.success(0);}return AjaxResult.success(1);}

并且因为判定登录功能可能会多次使用到,所以把相关的功能写到common中,方便调用。传递的参数是request,用来判定当前session的情况。

public class UserSessionTools {public static UserInfo getLoginUser(HttpServletRequest request) {HttpSession session = request.getSession(false);if (session != null && session.getAttribute(ApplicationVariale.SESSION_USERINFO_KEY) != null) {return (UserInfo) session.getAttribute(ApplicationVariale.SESSION_USERINFO_KEY);}return null;}
}

8.添加、修改、查询、删除文章

    <insert id="add">insert into articleinfo(title,content,uid)values(#{title},#{content},#{uid})</insert><update id="update">update articleinfo set title=#{title},content=#{content},updatetime=#{updatetime}where id=#{id} and uid=#{uid}</update><select id="getDetailByIdAndUid" resultType="com.example.spring_myblogsystem.entity.ArticleInfo">select * from articleinfo where id=#{id} and uid=#{uid}</select><delete id="del">delete from articleinfo where id = #{id} and uid = #{uid}</delete>
@Mapper
public interface ArticleMapper {int add(ArticleInfo articleInfo);ArticleInfo getDetailByIdAndUid(@Param("id")Integer id,@Param("uid")Integer uid);int update(ArticleInfo articleInfo);int del(@Param("id") Integer id, @Param("uid") Integer uid);
@Service
public class ArticleService {@Autowiredprivate ArticleMapper articleMapper;public int add(ArticleInfo articleInfo){return articleMapper.add(articleInfo);}public ArticleInfo getDetailByIdAndUid(Integer id,Integer uid){return articleMapper.getDetailByIdAndUid(id,uid);}public int update(ArticleInfo articleInfo){return articleMapper.update(articleInfo);}public int del(Integer id, Integer uid) {return articleMapper.del(id, uid);}
@RestController
@RequestMapping("/art")
public class ArticleController {@Autowiredprivate ArticleService articleService;@RequestMapping("/add")public AjaxResult add(ArticleInfo articleInfo, HttpServletRequest request){if (articleInfo == null ||!StringUtils.hasLength(articleInfo.getTitle()) ||!StringUtils.hasLength(articleInfo.getContent())){return AjaxResult.fail(-1,"参数异常");}UserInfo userInfo = UserSessionTools.getLoginUser(request);articleInfo.setUid(userInfo.getId());int result = articleService.add(articleInfo);return AjaxResult.success(result);}@RequestMapping("/getdetailbyid")public AjaxResult getDetailByIdAndUid(Integer id,HttpServletRequest request){if(id == null || id <=0){return AjaxResult.fail(-1,"参数非法");}UserInfo userInfo = UserSessionTools.getLoginUser(request);return AjaxResult.success(articleService.getDetailByIdAndUid(id, userInfo.getId()));}@RequestMapping("/update")public AjaxResult update(ArticleInfo articleInfo,HttpServletRequest request){if(articleInfo == null || articleInfo.getId() <= 0 || !StringUtils.hasLength(articleInfo.getContent()) || !StringUtils.hasLength(articleInfo.getTitle())){return AjaxResult.fail(-1,"参数有误");}UserInfo userInfo = UserSessionTools.getLoginUser(request);articleInfo.setUid(userInfo.getId());articleInfo.setUpdatetime(userInfo.getUpdatetime());return AjaxResult.success(articleService.update(articleInfo));}@RequestMapping("/del")public AjaxResult del(Integer id, HttpServletRequest request) {if (id == null || id <= 0) {return AjaxResult.fail(-1, "参数错误");}UserInfo userInfo = UserSessionTools.getLoginUser(request);int result = articleService.del(id, userInfo.getId());return AjaxResult.success(result);}

可以看到,几乎所有的方法都是先对传入的参数进行非空校验,再对session的情况进行判定。实现都很简单。

在getDetailByIdAndUid和del中,一次性传入了文章id和uid。这是为了校验当前查看文章的用户是文章的作者,只有这种情况才能够对文章进行后续的修改和删除。

9.查询文章列表、分页、展示阅读次数

相比于前面的增删查改操作来说,这个部分要复杂很多。

查询文章列表

    <select id="getListByUid" resultType="com.example.spring_myblogsystem.entity.ArticleInfo">select * from articleinfowhere uid = #{uid}order by id desc;</select>
List<ArticleInfo> getListByUid(@Param("uid") Integer id);
public List<ArticleInfo> getListByUid(Integer id) {return articleMapper.getListByUid(id);}
    @RequestMapping("/mylist")public AjaxResult mylist(HttpServletRequest request) {UserInfo userInfo = UserSessionTools.getLoginUser(request);List<ArticleInfo> list = articleService.getListByUid(userInfo.getId());//todo:将文章正文截取成文章摘要for (ArticleInfo item : list) {String content = StringTools.subLength(item.getContent(), 200);item.setContent(content);}return AjaxResult.success(list);}

展示阅读次数

定义一个先rcount变量,记录文章的阅读次数。先做查询操作,等前面页面刷新时,rcount自增1并且存储到数据库中。

    <update id="addRcount">update articleinfoset rcount=rcount + 1where id = #{id}</update>
    public Integer getCount() {return articleMapper.getCount();}
    @RequestMapping("/getcount")public AjaxResult getCount() {return AjaxResult.success(articleService.getCount());}

分页功能

分页功能也就是实现这四个功能。

我们先定义几个变量:

  • pageIndex:记录页面当前的页码(从1开始)
  • pageSize:记录每页最大条数
  • pageCount:记录总页数
  • offset:数据库中从第几条开始查询

首页功能很好实现,规定当前页码是1,offset只需要是0开始就行了。

当设置pageSize为2时,总页数和offset都可以被算出来。同时需要再数据库中查询两次,一次是根据相关的参数查询文章,另一次是查询一共有多少条文章。

    <select id="getListByPage" resultType="com.example.spring_myblogsystem.entity.ArticleInfo">select * from articleinfoorder by id desclimit #{pageSize} offset #{offset}</select>    <select id="getCount" resultType="java.lang.Integer">select count(id)from articleinfo</select>

例如当前是第一页,查询的文章为从第0条开始查询,当前页码为1,offset为0。

如果到了第二页,查询的文章从第2条开始查询,当前页码为1,offset为2。

也就是说,offset有如下公式:offset = (pageIndex - 1)× pageSize 

    @RequestMapping("/getlistbypage")public AjaxResult getListByPage(Integer pageSize, Integer pageIndex) {if (pageSize == null || pageSize == 0) {pageSize = 2;}if (pageIndex == null || pageIndex <= 1) {pageIndex = 1;}int offset = (pageIndex - 1) * pageSize;List<ArticleInfo> list = articleService.getListByPage(pageSize, offset);list.stream().parallel().forEach((item -> {item.setContent(StringTools.subLength(item.getContent(), 150));}));return AjaxResult.success(list);}

同时用一个list来存储相关的文章,通过list.stream.forEach来遍历,并且可以使用parallel()多线程处理,效率更快。

处理完了首页、上一页和下一页,末页需要用到getCount,获取到一共有多少条文章,然后再根据这个数字来判定总页数,通过getCount/pageSize就可以得到。得到总页数后,再传回数据库查询,得到末页的文章。

10.拦截器

虽然前面已经对session做了判定,判断用户是否登录,但是我们用一个统一的拦截器来完成对代码的过滤等等。

比如在登入一个页面时,如果要求用户密码、权限等的验证,就可以用自定义的拦截器进行密码验证和权限限制。对符合的登入者才跳转到正确页面。这样如果有新增权限的话,不用在controller里修改任何代码,直接在interceptor里修改就行了。

Spring中的拦截器是通过动态代理的方式实现和环绕通知的方式实现的,并且是作用域controller之前,先把相关的请求预处理完,再进行程序的正常流程。

@Configuration
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session = request.getSession(false);if (session != null && session.getAttribute(ApplicationVariale.SESSION_USERINFO_KEY) != null) {return true;}response.sendRedirect("/login.html");return false;}
}

需要实现一个LoginInterceptor并且implements HandlerInterceptor

重写preHandle方法,来判定用户是否登录的功能,并且把需要登录才能访问的内容添加到MyConfig中。

首先添加所有的路径,然后把不需要的路径排除掉,就是拦截器拦截的内容。简单的理解为,用户需要登录才能够访问的内容都被拦截器拦截了,不需要登录就能够访问的则不添加到拦截器中。

11.统一异常处理和统一数据返回格式

统一异常处理

对于异常处理来说,最简单直接的方式就是使用 try catch 代码块来捕获系统异常。但是这种处理方式需要我们编写大量的代码,而且异常信息不易于统一维护,增加了开发工作量,甚至可能还会出现异常没有被捕获的情况。为了能够高效的处理好各种系统异常,我们需要在项目中统一集中处理我们的异常。

@RestControllerAdvice
public class MyExceptionAdvice {@ExceptionHandler(Exception.class)public AjaxResult doException(Exception e) {return AjaxResult.fail(-1, e.getMessage());}
}

@ControllerAdvice 表示控制器通知类,@ExceptionHandler 是异常处理器,两个结合表示当出现异常的时候执行某个通知, 也就是执行某个方法事件。

统一数据返回格式

在所有的controller中,我们返回给前端的都是一个AjaxResult对象,也就是包含了code、msg、data三个属性的变量。但是如果某个controller中返回的是错误的,假设返回的是1,那么就会出现错误。我们可以规定统一返回的一种格式,有助于帮助前后端程序员沟通。

//统一返回数据格式的封装
//当返回的数据不是AjaxResult的时候转换成AjaxResult
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {@Autowiredprivate ObjectMapper objectMapper;@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}@SneakyThrows@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {if (body instanceof AjaxResult) {return body;}if (body instanceof String) {return objectMapper.writeValueAsString(AjaxResult.success(body));}return null;}
}

统⼀的数据返回格式可以使用 @ControllerAdvice + ResponseBodyAdvice 的方式实现。

12.加盐处理

用户输入的密码到数据库中时,非常不安全,很容易被破解。所以当我们储存到数据库中时,最好存储的是加密的密码。所以我们在服务器中需要完成对密码的加密。通过加盐的方式来处理。

密码如何加盐加密?icon-default.png?t=N7T8http://t.csdnimg.cn/9q7lU

public class PasswordTooles {public static String encrypt(String password) {//产生盐值String salt = UUID.randomUUID().toString().replace("-", "");//使用盐值+明文密码得到加密的密码String finalPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());//将盐值和加密的密码共同返回String dbPassword = salt + "$" + finalPassword;return dbPassword;}//验证加盐加密密码public static boolean decrypt(String password, String dbPassword) {boolean result = false;if (StringUtils.hasLength(password) && StringUtils.hasLength(dbPassword) && dbPassword.length() == 65 && dbPassword.contains("$")) {String[] passwordArr = dbPassword.split("\\$");String salt = passwordArr[0];String checkPassword = encrypt(password);if (dbPassword.equals(checkPassword)) {result = true;}}return result;}
}

相关文章:

博客系统-SpringBoot版本

相比于之前使用Servlet来完成的博客系统&#xff0c;SpringBoot版本的博客系统功能更完善&#xff0c;使用到的技术更接近企业级&#xff0c;快来看看吧~ 目录 1.项目介绍 2.数据库准备 3.实体化类 4.返回格式 5.登录和注册功能 6.登出&#xff08;注销&#xff09;功能…...

详细分析Redis中数值乱码的根本原因以及解决方式

目录 前言1. 问题所示2. 原理分析3. 拓展 前言 对于这方面的相关知识推荐阅读&#xff1a; Redis框架从入门到学精&#xff08;全&#xff09;Java关于RedisTemplate的使用分析 附代码java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09; …...

网络专栏目录

大家好我是苏麟 , 这是网络专栏目录 . 图解网络 资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) 图解网络目录 基础篇 基础篇 TCP/IP网络模型有几层? : TCP/IP网络模型 键入网址到页面显示,期间发生了什么? : 键入网址到页面显示,期间发生了什么 现阶…...

【Python网络编程之Ping命令的实现】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Python开发技术 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; Python网络编程之Ping命令的实现 代码见资源&#xff0c;效果图如下一、实验要求二、协议原理2…...

OpenHarmony轻量级驱动开发

OpenHarmony轻量级驱动开发 思维导图: https://download.csdn.net/download/lanlingxueyu/88817155 GPlO(General-purpose input/output)即通用型输入输出 描述 GPlO(General-purpose input/output)即通用型输入输出。通俗地说,GPlO口就是一些引脚可以通过它们输出高低…...

C语言如何输⼊字符数组?

一、问题 在程序中&#xff0c;scanf()函数可以输⼊任意类型的数据&#xff0c;gets()函数只能输⼊字符串等&#xff0c;但是如何更好地输⼊字符数组呢&#xff1f; 二、解答 我们知道如何使⽤格式输⼊函数 scanf()&#xff0c;那么可以使⽤%c 格式符逐个输⼊字符。这样输⼊有…...

人脸追踪案例及机器学习认识

1.人脸追踪机器人初制 用程序控制舵机运动的方法与机械臂项目完全相同。 由于摄像头的安装方式为上下倒转安装&#xff0c;我们在编写程序读取图像时需使用 flip 函数将 图像上下翻转。 现在&#xff0c;只需要使用哈尔特征检测得到人脸在图像中的位置&#xff0c;再指示舵机运…...

鸿蒙开发理论之页面和自定义组件生命周期

1、自定义组件和页面的关系 页面&#xff1a;即应用的UI页面。可以由一个或者多个自定义组件组成&#xff0c;Entry装饰的自定义组件为页面的入口组件&#xff0c;即页面的根节点&#xff0c;一个页面有且仅能有一个Entry。只有被Entry装饰的组件才可以调用页面的生命周期。自…...

docker-compose部署gitlab和jenkins

通过docker-compose部署gitlab和jenkins&#xff0c;方便后续工作 注意&#xff1a; gitlab占用资源较多&#xff0c;最好系统内存在8G以上&#xff0c;CPU4核心以上&#xff0c;否则gitlab有可能报错无法启动。docker版本用最新版本&#xff0c;低版本的docker可能会导致doc…...

Pytorch 复习总结 1

Pytorch 复习总结&#xff0c;仅供笔者使用&#xff0c;参考教材&#xff1a; 《动手学深度学习》 本文主要内容为&#xff1a;Pytorch 张量的常见运算、线性代数、高等数学、概率论。 Pytorch 张量的常见运算、线性代数、高等数学、概率论 部分 见 Pytorch 复习总结 1&…...

谷歌免费开放模糊测试框架OSS-Fuzz(物联网、车联网、供应链安全、C/C++)

目录 模糊测试的智能化和自动化 模糊测试不能代替安全设计原则 AI驱动的漏洞修补...

华为配置内部人员接入WLAN网络示例(802.1X认证)

配置内部人员接入WLAN网络示例&#xff08;802.1X认证&#xff09; 组网图形 图1 配置802.1X认证组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 用户接入WLAN网络&#xff0c;使用802.1X客户端进行认证&#xff0c;输入正确的用户名和密…...

EXCEL中如何调出“数据分析”的菜单

今天发现&#xff0c;原来WPS还是和EXCEL比&#xff0c;还是少了“数据分析”这个日常基本做统计的菜单&#xff0c;只好用EXCEL了&#xff0c;但奇怪发现我的EXCEL中没发现这个菜单&#xff0c;然后查了下&#xff0c;才发现&#xff0c;要用如下的方法打开&#xff1a; 1&…...

基于Qt的人脸识别项目(功能:颜值检测,口罩检测,表情检测,性别检测,年龄预测等)

完整代码链接在文章末尾 效果展示 代码讲解(待更新) qt图片文件上传 #include <QtWidgets> #include <QFileDialog>...

书生谱语-大语言模型测试demo

课程内容简介 通用环境配置 开发机 InterStudio 配置公钥 在本地机器上打开 Power Shell 终端。在终端中&#xff0c;运行以下命令来生成 SSH 密钥对&#xff1a; ssh-keygen -t rsa您将被提示选择密钥文件的保存位置&#xff0c;默认情况下是在 ~/.ssh/ 目录中。按 Enter …...

2024-02-12 Unity 编辑器开发之编辑器拓展3 —— EditorGUI

文章目录 1 GUILayout2 EditorGUI 介绍3 文本、层级、标签、颜色拾取3.1 LabelField3.2 LayerField3.3 TagField3.4 ColorField3.5 代码示例 4 枚举选择、整数选择、按下按钮4.1 EnumPopup / EnumFlagsField4.2 IntPopup4.3 DropdownButton4.4 代码示例 5 对象关联、各类型输入…...

shell脚本编译与解析

文章目录 shell变量全局变量&#xff08;环境变量&#xff09;局部变量设置PATH 环境变量修改变量属性 启动文件环境变量持久化 ./和. 的区别脚本编写判断 和循环命令行参数传入参数循环读取命令行参数获取用户输入 处理选项处理简单选项处理带值选项 重定向显示并且同时输出到…...

第64讲个人中心用户操作菜单实现

静态页面 <!-- 用户操作菜单开始 --><view class"user_menu"><!-- 订单管理开始 --><view class"order_wrap"><view class"order_title">我的订单</view><view class"order_content"><n…...

线性代数的本质——1 向量

向量是线性代数中最为基础的概念。 何为向量&#xff1f; 从物理上看&#xff0c; 向量就是既有大小又有方向的量&#xff0c;只要这两者一定&#xff0c;就可以在空间中随便移动。 从计算机应用的角度看&#xff0c;向量和列表很接近&#xff0c;可以用来描述某对象的几个不同…...

工业以太网交换机引领现代工厂自动化新潮流

随着科技的飞速发展&#xff0c;现代工厂正迎来一场前所未有的自动化变革&#xff0c;而工业以太网交换机的崭新角色正是这场变革的关键组成部分。本文将深入探讨工业以太网交换机与现代工厂自动化的紧密集成&#xff0c;探讨这一集成如何推动工业生产的智能化、效率提升以及未…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

【深尚想】TPS54618CQRTERQ1汽车级同步降压转换器电源芯片全面解析

1. 元器件定义与技术特点 TPS54618CQRTERQ1 是德州仪器&#xff08;TI&#xff09;推出的一款 汽车级同步降压转换器&#xff08;DC-DC开关稳压器&#xff09;&#xff0c;属于高性能电源管理芯片。核心特性包括&#xff1a; 输入电压范围&#xff1a;2.95V–6V&#xff0c;输…...

在Zenodo下载文件 用到googlecolab googledrive

方法&#xff1a;Figshare/Zenodo上的数据/文件下载不下来&#xff1f;尝试利用Google Colab &#xff1a;https://zhuanlan.zhihu.com/p/1898503078782674027 参考&#xff1a; 通过Colab&谷歌云下载Figshare数据&#xff0c;超级实用&#xff01;&#xff01;&#xff0…...

嵌入式面试常问问题

以下内容面向嵌入式/系统方向的初学者与面试备考者,全面梳理了以下几大板块,并在每个板块末尾列出常见的面试问答思路,帮助你既能夯实基础,又能应对面试挑战。 一、TCP/IP 协议 1.1 TCP/IP 五层模型概述 链路层(Link Layer) 包括网卡驱动、以太网、Wi‑Fi、PPP 等。负责…...