从 0 开始实现一个博客系统 (SSM 项目)
相关技术
Spring + Spring Boot + Spring MVC + MyBatis
Html + Css + JS
pom 文件我就不放出来了, 之前用的 jdk8 做的, MySQL 用的 5.7, 都有点老了, 你们自己看着配版本就好
实现功能
- 用户注册 - 密码加盐加密 (md5 加密)
- 前后端用户信息存储 - 令牌技术
- 用户登录 - (使用 拦截器 做登录校验)
- 博客的增删改查
- 后端数据返回前端, 采用 SpringBoot 做统一功能处理和统一异常处理
数据库设计
- 用户表
- 博客表
前端页面
博客登录页 (blog_login.html)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><me_ta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>博客登陆页</title><link rel="stylesheet" href="css/common.css"><link rel="stylesheet" href="css/login.css"></head><body><div class="nav"><img src="pic/logo2.jpg" alt=""><span class="blog-title">我的博客系统</span><div class="space"></div><a class="nav-span" href="blog_list.html">主页</a><a class="nav-span" href="blog_edit.html">写博客</a></div><div class="container-login"><div class="login-dialog"><h3>登陆</h3><div class="row"><span>用户名</span><input type="text" name="username" id="username"></div><div class="row"><span>密码</span><input type="password" name="password" id="password"></div><div class="row"><button id="submit" onclick="login()">提交</button></div></div></div><script src="js/jquery.min.js"></script><script>function login() {// 发送 ajax 请求, 获取 token$.ajax({type: "post",url: "/user/login",data: {"userName": $("#username").val(),"password": $("#password").val()},success: function(result) {if(result.code == 200 && result.data != null) {// 存储 token 到本地localStorage.setItem("user_token", result.data);location.href = "blog_list.html";}else{alert("用户名或密码错误");}}});}</script>
</body></html>
用户登录成功之后, 会将用户信息, 生成令牌, 存储到 request 中, 前后端都能从中获取当前登录用户的信息
博客列表页 (blog_list.html)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>博客列表页</title><link rel="stylesheet" href="css/common.css"><link rel="stylesheet" href="css/list.css"></head>
<body><div class="nav"><img src="pic/logo2.jpg" alt=""><span class="blog-title">我的博客系统</span><div class="space"></div><a class="nav-span" href="blog_list.html">主页</a><a class="nav-span" href="blog_edit.html">写博客</a><a class="nav-span" href="#" onclick="logout()">注销</a></div><div class="container"><div class="left"><div class="card"><img src="pic/doge.jpg" alt=""><h3></h3><a href="#"></a><div class="row"><span>文章</span><span>分类</span></div><div class="row"><span>2</span><span>1</span></div></div></div><div class="right"></div></div><script src="js/jquery.min.js"></script><script src="js/common.js"></script><script>//显示用户信息var userUrl = "/user/getUserInfo";getUserInfo(userUrl);// 获取所有的博客信息$.ajax({type: "get",url: "/blog/getList",success: function(result) {console.log("result:" + result);if(result.code == 200 && result.data != null) {var finalHtml = "";for(var blog of result.data) {finalHtml += '<div class="blog">';finalHtml += '<div class="title">'+blog.title+'</div>';finalHtml += '<div class="date">'+blog.createTime+'</div>';finalHtml += '<div class="desc">'+blog.content+'</div>';finalHtml += '<a class="detail" href="blog_detail.html?blogId='+blog.id+'">查看全文>></a>';finalHtml += '</div>';}$(".right").html(finalHtml);}},error: function(error) {console.log("error:" + error);location.href = "blog_login.html";if(error != null && error.state == 401) {location.href = "blog_login.html";}}});</script>
</body>
</html>
当前页面会自动调用一个 ajax 请求, 用以获取数据库中 所有未删除博客 的信息进行展示 (博客正文会裁取前100字进行显示)
博客详情页 (blog_detail.html)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>博客详情页</title><link rel="stylesheet" href="css/common.css"><link rel="stylesheet" href="css/detail.css"></head><body><div class="nav"><img src="pic/logo2.jpg" alt=""><span class="blog-title">我的博客系统</span><div class="space"></div><a class="nav-span" href="blog_list.html">主页</a><a class="nav-span" href="blog_edit.html">写博客</a><a class="nav-span" href="#" onclick="logout()">注销</a></div><div class="container"><div class="left"><div class="card"><img src="pic/doge.jpg" alt=""><h3></h3><a href="#"></a><div class="row"><span>文章</span><span>分类</span></div><div class="row"><span>2</span><span>1</span></div></div></div><div class="right"><div class="content"><div class="title"></div><div class="date"></div><div class="detail" id="detail" style="background-color: transparent;"></div><!-- <div class="operating"><button onclick="window.location.href='blog_update.html'">编辑</button><button onclick="deleteBlog()">删除</button></div> --></div></div></div><!-- 引入 editor.md 的依赖 --><link rel="stylesheet" href="blog-editormd/css/editormd.css" /><script src="js/jquery.min.js"></script><script src="blog-editormd/lib/marked.min.js"></script><script src="blog-editormd/lib/prettify.min.js"></script><script src="blog-editormd/editormd.js"></script><script src="js/common.js"></script><script>// 获取博客详情$.ajax({type: "get",url: "/blog/getBlogDetail"+location.search,success: function(result) {console.log(result);if(result.code == 200 && result.data != null) {console.log("abc" + result);var blog = result.data;$(".right .content .title").text(blog.title);$(".right .content .date").text(blog.createTime);// $(".right .content .detail").text(blog.content);editormd.markdownToHTML("detail", {markdown: blog.content,});// 是否显示 编辑/删除 按钮if(blog.isLoginUser == true) {var html = "";html += '<div class="operating">';html += '<button onclick="window.location.href=\'blog_update.html'+location.search+'\'">编辑</button>';html += '<button onclick="deleteBlog()">删除</button>';html += '</div>';$(".content").append(html);}}},error: function(error) {if(error != null && error.status == 401) {location.href = "blog_list.html";}}});//显示博客作者信息var userUrl = "/user/getAuthorInfo" + location.search;getUserInfo(userUrl);function deleteBlog() {$.ajax({type: "post",url: "/blog/delete" + location.search,success: function(result) {if(result.code == 200 && result.data != null && result.data == true) {location.href = "blog_list.html";}}});}</script>
</body></html>
对于每篇博客, 会显示博客信息 (标题, 最后一次的修改时间, 博客正文), 和博客作者的信息 (用户名) (TODO: 作者头像, 作者的总文章数量, 博客的分类所属)
页面会自动校验登录用户是否为当前博客的作者, 如果是, 那么可以对当前博客进行编辑和删除, 如果不是, 这两个按钮不会显示
博客编辑页 (blog_edit.html)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>博客编辑页</title><link rel="stylesheet" href="css/common.css"><link rel="stylesheet" href="css/edit.css"><link rel="stylesheet" href="blog-editormd/css/editormd.css" /></head><body><div class="nav"><img src="pic/logo2.jpg" alt=""><span class="blog-title">我的博客系统</span><div class="space"></div><a class="nav-span" href="blog_list.html">主页</a><a class="nav-span" href="blog_edit.html">写博客</a><a class="nav-span" href="#" onclick="logout()">注销</a></div><div class="content-edit"><div class="push"><input type="text" name="" id="title"><input type="button" value="发布文章" id="submit" onclick="submit()"></div><!-- markdown 插件 html代码 --><div id="editor"><textarea style="display:none;" id="content" name="content">##在这里写下一篇博客</textarea></div></div><script src="js/jquery.min.js"></script><script src="blog-editormd/editormd.min.js"></script><script src="js/common.js"></script><script type="text/javascript">$(function () {var editor = editormd("editor", {width: "100%",height: "550px",path: "blog-editormd/lib/"});});function submit() {$.ajax({type: "post",url: "/blog/add",data: {title: $("#title").val(),content: $("#content").val()},success: function(result) {if(result.code == 200 && result.data != null && result.data == true) {location.href = "blog_list.html";}else {alert("博客发布失败!");}}});}</script>
</body></html>
博客编辑页使用了 gittee 上的一个开源 markdown 组件
对于未有博客的 “写博客” , 调用的是 “插入操作”
对于已有博客的 “编辑博客” , 调用的是 “更新操作”
“删除博客” 操作是逻辑删除, 即修改数据库的某一字段, 所以调用的也是 “更新操作”
前端页面共同的 js (common.js)
$(document).ajaxSend(function(e, xhr, opt) {// 获取本地存储中的 tokenvar user_token = localStorage.getItem("user_token");// 将 token 设置到每个 ajax 请求的 header 中xhr.setRequestHeader("user_token_header", user_token);
});// 获取用户信息
function getUserInfo(url) {$.ajax({type: "post",url: url,success: function(result) {if(result.code == 200 && result.data != null) {$(".left .card h3").text(result.data.userName);$(".left .card a").attr("href", result.data.githubUrl);}}});
}// 用户退出
function logout() {localStorage.removeItem("user_token");location.href = "blog_login.html";
}
主要就是获取当前登录用户的信息, 以及退出登录的逻辑
后端代码
项目的基本框架
实体类
BlogInfo
@Data
public class BlogInfo {private Integer id;private String title;private String content;private Integer userId;private Integer deleteFlag;private Date createTime;private Date updateTime;private Boolean isLoginUser = false;// 返回 String 类型的数据 (BlogInfo 里面存储的是 Date 类型数据)public String getCreateTime() {return DateUtils.formateDate(createTime);}public String getUpdateTime() {return DateUtils.formateDate(updateTime);}
}
对应数据的 blog 表
UserInfo
@Data
public class UserInfo {private Integer id;private String userName;private String password;private String githubUrl;private Integer deleteFlag;private Date createTime;private Date updateTime;
}
对应数据的 user 表
Result
@Data
public class Result {private int code; //200成功 -1失败 -2未登录private String errMsg;private Object data;public static Result success(Object data) {Result result = new Result();result.setCode(Constant.SUCCESS_CODE);result.setErrMsg("");result.setData(data);return result;}public static Result fail(String errMsg) {Result result = new Result();result.setCode(Constant.FAIL_CODE);result.setErrMsg(errMsg);result.setData(null);return result;}public static Result fail(String errMsg, Object data) {Result result = new Result();result.setCode(Constant.FAIL_CODE);result.setErrMsg(errMsg);result.setData(data);return result;}public static Result unlogin() {Result result = new Result();result.setCode(Constant.FAIL_CODE);result.setErrMsg("用户未登录");result.setData(null);return result;}public static Result unlogin(String errMsg) {Result result = new Result();result.setCode(Constant.UNLOGIN_CODE);result.setErrMsg("用户未登录");result.setData(null);return result;}
}
用于统一数据格式返回 (不知道可以看一下我的另一篇博客 Spring Boot统一功能处理(拦截器, 统一数据返回格式, 统一异常处理) )
Constant 类 (常量值存储)
public class Constant {public final static Integer SUCCESS_CODE = 200;public final static Integer FAIL_CODE = -1;public final static Integer UNLOGIN_CODE = -2;public final static String USER_TOKEN_HEADER = "user_token_header";public final static String USER_CLAIM_ID = "id";public final static String USER_CLAIM_NAME = "name";
}
Mapper 类
通过 MyBatis 操作数据库
BlogMapper
@Mapper
public interface BlogMapper {// 查询博客列表@Select("select * from blog where delete_flag = 0 order by create_time desc")List<BlogInfo> selectAllBlog();// 根据博客 ID, 查询博客信息@Select("select * from blog where delete_flag = 0 and id = #{blogId}")BlogInfo selectById(@Param("blogId") Integer blogId);// 根据博客 ID, 修改/删除 博客信息Integer updateBlog(BlogInfo blogInfo);// 插入博客@Insert("insert into blog(title, content, user_id) values(#{blogInfo.title}, #{blogInfo.content}, #{blogInfo.userId})")Integer insertBlog(@Param("blogInfo") BlogInfo blogInfo);
}
数据库操作 blog 表
UserMapper
@Mapper
public interface UserMapper {// 根据用户名, 查询用户信息@Select("select * from user where user_name = #{userName} and delete_flag = 0")UserInfo selectByName(@Param("userName") String userName);// 根据用户 ID, 查询用户信息@Select("select * from user where id = #{userId} and delete_flag = 0")UserInfo selectById(@Param("userId") Integer userId);}
数据库操作 user 表
用户登录页
登录功能
登录页面点击登录按钮后, 触发 controller 层的 login 接口
@Autowiredprivate UserService userService;// 登录接口@RequestMapping("/login")public Result login(String userName, String password) {// 1.对参数进行校验// 2.对密码进行校验// 3.如果校验成功, 生成 tokenif(!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {
// throw new UnsupportedOperationException("用户名或密码不能为空");return Result.fail("用户名或密码不能为空");}// 获取用户信息UserInfo userInfo = userService.queryUserByName(userName);if(userInfo == null || userInfo.getId() <= 0) {return Result.fail("用户不存在");}// 密码校验if(!SecurityUtils.verify(password, userInfo.getPassword())) {return Result.fail("密码错误");}// 用户信息正确, 生成 tokenMap<String, Object> claim = new HashMap<>();claim.put(Constant.USER_CLAIM_ID, userInfo.getId());claim.put(Constant.USER_CLAIM_NAME, userInfo.getUserName());return Result.success(JWTUtils.getToken(claim));}
login 接口先对前端数据进行判空校验, 然后根据用户名 查询数据库中是否有对应的信息, 将获取信息与输入信息进行比对, 返回登录判定信息 (登录成功生成 token 令牌)
获取用户信息:
密码校验:
生成 token 令牌:
用户注销
用户注销是个前端功能
在 common.js 里面
function logout() {localStorage.removeItem("user_token");location.href = "blog_login.html";
}
博客列表页
博客列表页获取所有未删除博客的信息进行展示
调用接口 getList
@Autowired
private BlogService blogService;@RequestMapping("/getList")
public List<BlogInfo> queryBlogList() {return blogService.queryBlogList();
}
博客列表页左侧登录用户信息栏, 获取当前登录用户的信息进行展示
调用接口 getUserInfo
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;// 获取当前登录用户的信息@RequestMapping("/getUserInfo")public UserInfo getUserInfo(HttpServletRequest request) {// 1. 获取 token, 从 token 中获取 IDString user_token = request.getHeader(Constant.USER_TOKEN_HEADER);Integer userId = JWTUtils.getUserIdFromToken(user_token);// 2. 根据 ID, 获取用户信息if(userId == null || userId <= 0) {return null;}UserInfo userInfo =userService.queryUserByID(userId);userInfo.setPassword("");return userInfo;}
}
博客详情页
博客详情页右侧获取博客详情信息
调用接口 getBlogDetail
@Slf4j
@RestController
@RequestMapping("/blog")
public class BlogController {@Autowiredprivate BlogService blogService;// 根据博客id获取博客信息@RequestMapping("/getBlogDetail")public BlogInfo getBlogDetail(Integer blogId, HttpServletRequest request) {BlogInfo blogInfo = blogService.getBlogDetail(blogId);// 获取登录用户信息String user_token = request.getHeader(Constant.USER_TOKEN_HEADER);Integer userId = JWTUtils.getUserIdFromToken(user_token);// 判断登录用户是否为作者if(userId != null && userId == blogInfo.getUserId()) {blogInfo.setIsLoginUser(true);}else {blogInfo.setIsLoginUser(false);}return blogInfo;}
}
博客详情页左侧获取博客作者信息
调用接口 getAuthorInfo
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;// 根据博客 ID, 获取作者信息@RequestMapping("/getAuthorInfo")public UserInfo getAuthorInfo(Integer blogId) {// 校验博客 ID 是否正确if(blogId == null || blogId <= 0) {return null;}UserInfo userInfo = userService.queryAuthorInfoByBlogId(blogId);userInfo.setPassword("");return userInfo;}
}
博客详情页中, 编辑和删除功能
调用接口 update & delete
@Slf4j
@RestController
@RequestMapping("/blog")
public class BlogController {@Autowiredprivate BlogService blogService;// 编辑博客@RequestMapping("/update")public Boolean update(Integer blogId, String title, String content) {log.error("blogId:{}, title:{}, content:{}", blogId, title, content);if(blogId == null || !StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {log.error("update, 参数非法");return false;}BlogInfo blogInfo = new BlogInfo();blogInfo.setId(blogId);blogInfo.setTitle(title);blogInfo.setContent(content);log.error("blogInfo:{}", blogInfo);Integer result = blogService.updateBlog(blogInfo);if(result < 1) return false;return true;}// 删除博客(逻辑删除)@RequestMapping("/delete")public Boolean delete(Integer blogId) {BlogInfo blogInfo = new BlogInfo();blogInfo.setId(blogId);blogInfo.setDeleteFlag(1);log.error("blogInfo:{}", blogInfo);Integer result = blogService.updateBlog(blogInfo);if(result < 1) return false;return true;}
}
博客编辑页
博客撰写后存入数据库
调用接口 add
@Slf4j
@RestController
@RequestMapping("/blog")
public class BlogController {@Autowiredprivate BlogService blogService;// 添加博客@RequestMapping("/add")public Boolean publishBlog(String title, String content, HttpServletRequest request) {// 1.参数校验if(!StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {return false;}// 2.获取当前用户String user_token = request.getHeader(Constant.USER_TOKEN_HEADER);Integer userId = JWTUtils.getUserIdFromToken(user_token);if(userId == null || userId <= 0) {return false;}// 3.博客发布BlogInfo blogInfo = new BlogInfo();blogInfo.setUserId( userId);blogInfo.setContent(content);blogInfo.setTitle(title);Integer result = blogService.publishBlog(blogInfo);return result<=0 ? false:true;}
}
相关文章:

从 0 开始实现一个博客系统 (SSM 项目)
相关技术 Spring Spring Boot Spring MVC MyBatis Html Css JS pom 文件我就不放出来了, 之前用的 jdk8 做的, MySQL 用的 5.7, 都有点老了, 你们自己看着配版本就好 实现功能 用户注册 - 密码加盐加密 (md5 加密)前后端用户信息存储 - 令牌技术用户登录 - (使用 拦截…...
C++标准模板(STL)- C 内存管理库 - 分配并清零内存 (std::calloc)
C 内存管理库 分配并清零内存 std::calloc void* calloc( std::size_t num, std::size_t size ); 分配 num 个大小为 size 的对象的数组,并初始化所有位为零。 若分配成功,则返回指向为任何对象类型适当对齐的,被分配内存块最低…...
嵌入式开发面试问题总结(持续更新)
面试问题总结 c/c 封装、继承和多态 封装:将属性和方法封装起来,并加以权限区分。继承:子类继承父类的特征和行为,复用了从基类复制而来的数据成员和成员函数(基类私有成员无法被访问),其中构…...

意外发现openGauss兼容Oracle的几个条件表达式
意外发现openGauss兼容Oracle的几个条件表达式 最近工作中发现openGauss在兼容oracle模式下,可以兼容常用的两个表达式,因此就随手测试了一下。 查看数据库版本 [ommopenGauss ~]$ gsql -r gsql ((openGauss 6.0.0-RC1 build ed7f8e37) compiled at 2…...
使用Keepalived提高吞吐量和负载均衡ip_hash.
一 . Nginx使用Keepalived提高吞吐量案例 Keepalived[表示把连接保持一定长连接数来提高吞吐量] 1.1没有使用keepalived参数 upstream tomcats {server 192.168.28.102:8080; } server {listen 88;server_name www.tomcats.com;location / {proxy_pass http://to…...

网络故障与排除(一)
一、Router-ID冲突导致OSPF路由环路 路由器收到相同Router-ID的两台设备发送的LSA,所以查看路由表看到的OSPF缺省路由信息就会不断变动。而当C1的缺省路由从C2中学到,C2的缺省路由又从C1中学到时,就形成了路由环路,因此出现路由不…...

C++之运算符重载
1、运算符重载 //Complex.h #ifndef _COMPLEX_H_ #define _COMPLEX_H_class Complex { public:Complex(int real_, int imag_);Complex();~Complex();Complex& Add(const Complex& other); void Display() const;Complex operator(const Complex& other);privat…...
使用springdoc-openapi-starter-webmvc-ui后访问swagger-ui/index.html 报错404
按照官网说明,引入 springdoc-openapi-starter-webmvc-ui后应该就可以直接访问swagger-ui.html或者swagger-ui/index.html就可以出现swagger页面了,但是我引入后,访问提示报错404. 在我的项目中,有其他依赖间接引入了org.webjars…...

深入理解计算机系统 家庭作业4.52
练习题4.3 p.254 \sim\seq\seq-full.hcl文件内已经说的很清楚了哪些不能更改,哪些是题目要求更改的控制逻辑块. 依据家庭作业4.51的答案,在seq-full.hcl文件内更改对应的HCL描述即可 以下答案注释了#changed的就是更改部分 #/* $begin seq-all-hcl */ ######################…...

深度学习:手撕 RNN(2)-RNN 的常见模型架构
本文首次发表于知乎,欢迎关注作者。 上一篇文章我们介绍了一个基本的 RNN 模块。有了 这个 RNN 模块后,就像搭积木一样,以 RNN 为基本单元,根据不同的任务或者需求,可以构建不同的模型架构。本节介绍的所有结构&#…...

【Linux进程篇】Linux进程管理——进程创建与终止
W...Y的主页 😊 代码仓库分享💕 目录 进程创建 fork函数初识 写时拷贝 fork常规用法 fork调用失败的原因 进程终止 进程退出场景 _exit函数 exit函数 return退出 进程创建 fork函数初识 在linux中fork函数时非常重要的函数,它从已…...

Python爬虫实战(实战篇)—17获取【CSDN某一专栏】数据转为Markdown列表放入文章中
文章目录 专栏导读背景结果预览1、页面分析2、通过返回数据发现适合利用lxmlxpath3、进行Markdown语言拼接总结 专栏导读 在这里插入图片描述 🔥🔥本文已收录于《Python基础篇爬虫》 🉑🉑本专栏专门针对于有爬虫基础准备的一套基…...
Go语言-big.Int
文章目录 Go 语言 big.Int应用场景:大整数位运算使用举例: go sdk中crypto/ecdsa 椭圆曲线生成私钥相关结构中就有使用 Go 语言 big.Int Go 语言 big.Int 参考URL: https://blog.csdn.net/wzygis/article/details/82867793 math/big 作为 Go 语言提供的…...
getContentView(mBinding.getRoot()); 会导致内存泄露吗?里面有SurfaceView ViewBinding
在上述代码中,ActivityTestingBinding 是一个 Data Binding 库生成的类,用于绑定 XML 布局到 Activity 中。inflate(getLayoutInflater()) 用于将布局文件解析并转换为对应的视图层次结构。然后 getWindow().setFlags() 设置窗口属性,保持屏幕…...

基于transformers框架实践Bert系列6-完形填空
本系列用于Bert模型实践实际场景,分别包括分类器、命名实体识别、选择题、文本摘要等等。(关于Bert的结构和详细这里就不做讲解,但了解Bert的基本结构是做实践的基础,因此看本系列之前,最好了解一下transformers和Bert…...

cesium绘制编辑区域
npm 安装也是可以的 #默认安装最新的 yarn add cesium#卸载插件 yarn remove cesium#安装指定版本的 yarn add cesium1.96.0#安装指定版本到测试环境 yarn add cesium1.96.0 -D yarn install turf/turf token记得换成您自己的!!! <t…...

数据库攻防之MySQL
MySQL 是最流行的关系型数据库,与此同时也是 web 应用中最好的关系型数据库管理应用软件。我们在渗透过程中碰到的 PHP 站点大部分都会搭配 MySQL 数据库,因此它是红队攻防中最常遇到的数据库。 0x01 MySQL简介 MySQL 是典型的关系型数据库,…...

八国多语言微盘微交易所系统源码 单控点控 K线完好
安装环境linux NGMySQL5.6PHP7.2(函数全删)pm2管理器(node版本选择v12.20.0) config/ database.php 修改数据库链接 设置运行目录 public 伪静态thinkphp...

爪哇,我初学乍道
>>上一篇(学校上课,是耽误我学习了。。) 2016年9月,我大二了。 自从我发现上课会耽误我学习,只要我认为不影响我期末学分的,我就逃课了。 绝大多数课都是要签到的,有的是老师突击喊名字…...
【MySQL精通之路】全文搜索(5)-限制
主博客:【MySQL精通之路】全文搜索功能-CSDN博客 全文搜索仅支持InnoDB和MyISAM表。 分区表不支持全文搜索。参见“分区的限制和限制”。 全文搜索可用于大多数多字节字符集。 例外的是,对于Unicode,可以使用utf8mb3或utf8mb4字符集ÿ…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

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