基于 SpringBoot + MyBatis 的博客系统
文章目录
- 1. 项目设计
- 2. 效果展示
- 3. 创建项目并配置文件
- 1.1 创建 Spring 项目
- 1.2 配置文件
- 4. 数据库实现用户和博客管理
- 4.1 设计数据库
- 4.2 使用 MyBatis 操作数据库
- UserMapper.xml
- BlogMapper.xml
- User 实体类 和 Blog 实体类
- UserMapper 接口 和 BlogMapper 接口
- UserService 类 和 BlogService 类
- 5. 前后端交互接口设计
- 6. 导入前端代码
- 7. 实现博客主页
- 7.1 实现后端代码
- 7.2 实现前端代码
- 7.3 测试代码
- 7.4 解决页面内容太多超出当前浏览器
- 7.5 解决页面顺序不是按最新时间排序
- 7.6 解决内容太多, 导致显示的时候占位太多.
- 7.7 再次测试代码
- 8. 实现博客详情页
- 8.1 实现后端代码
- 8.2 实现前端代码
- 8.3 测试代码
- 8.4 这里展示为markdown语法的正文
- 9. 实现博客登录界面
- 9.1 实现后端代码
- 9.2 实现前端代码
- 10. 实现登录判断 --- 拦截器
- 10.1 实现自定义拦截器
- 10.2 将自定义拦截器加入到系统配置
- 11. 实现注册功能
- 11.1 实现后端代码
- 11.2 实现前端代码
- 12. 实现注销功能
- 12.1 实现后端代码
- 13. 实现博客编辑页
- 13.1 实现后端代码
- 13.2 实现前端代码
- 14. 实现博客个人主页
- 14.1 实现后端代码
- 14.2 实现前端代码
- 15. 实现展示用户信息的功能
- 15.1 实现后端代码
- 15.2 实现前端代码
- 16. 实现博客的删除功能
- 16.1 改进代码
- 16.2 实现后端代码
- 17. 实现博客的修改功能
- 17.1 实现后端代码
- 17.2 实现前端代码
1. 项目设计
前端使用 HTML+CSS+JavaScript+JQuery
后端使用 Spring MVC+Spring Boot+MyBatis
2. 效果展示
3. 创建项目并配置文件
1.1 创建 Spring 项目
1.2 配置文件
application.properties
配置内容
spring.profiles.active=dev
application-dev.properties
配置内容
spring.datasource.url=jdbc:mysql://localhost:3306/MyBlogSystem?characterEncoding=utf8&useSSL=true
spring.datasource.username=root
spring.datasource.password=0000
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Drivermybatis.mapper-locations=classpath:mapper/**Mapper.xml
4. 数据库实现用户和博客管理
4.1 设计数据库
这里博客系统, 是一个用户表和博客表,
用户一般分为:
- 用户Id (每个人一个且互不相同)
- 用户名 (每个人的用户名不相同)
- 密码
- 用户头像(暂不实现)
- 用户马云地址(暂不实现)
博客一般分为:
- 博客Id (每篇博客一个且互不相同)
- 标题
- 正文
- 创建时间
- 修改时间 (这里没用到, 自己想加也可以)
- 用户Id (可以设置一个外键,这里没设置)
create database if not exists MyBlogSystem;use MyBlogSystem;drop table if exists blog;-- 创建一个博客表
create table blog (blogId int primary key auto_increment,title varchar(1024),content mediumtext,postTime datetime,userId int
);drop table if exists user;-- 创建一个用户信息表
create table user (userId int primary key auto_increment,username varchar(128) unique,password varchar(128)
);
4.2 使用 MyBatis 操作数据库
在
resources
下创建一个mapper
包. 包下创建UserMapper.xml
和
BlogMapper.xml
- BlogMapper.xml 里是对博客表的数据库操作
- UserMapper.xml 里是对用户表的数据库操作
UserMapper.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.UserMapper"><!-- 注册一个用户 --><insert id="addUser" keyProperty="userId" keyColumn="userId">insert into user(username password) values (#{username}, #{password})</insert><!-- 通过用户名查找用户信息 --><select id="selectByName" resultType="com.example.demo.model.User">select * from user where username = #{username}</select><!-- 通过用户Id查找用户信息 --><select id="selectById" resultType="com.example.demo.model.User">select * from user where userId = #{userId}</select>
</mapper>
BlogMapper.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.BlogMapper"><!-- 查找当前所有的文章 --><select id="getAllBlog" resultType="com.example.demo.model.Blog">select * from blog</select><!-- 通过博客id查找所有的文章 --><select id="getBlogByBid" resultType="com.example.demo.model.Blog">select * from blog where blogId = #{blogId}</select><!-- 发布一篇博客 --><insert id="postBlog" keyColumn="userId" keyProperty="userId">insert into blog(title,content,postTime,userId) values(#{title},#{content},#{postTime},#{userId})</insert><!-- 删除一篇博客 --><delete id="deleteBlog">delete from blog where blogId = #{blogId}</delete><!-- 更新一篇博客 --><update id="updateBlog">update blog set content = #{content},title = #{title} where blogId = #{blogId}</update><!-- 根据当前用户Id获取所有的博客 --><select id="getAllBlogById" resultType="com.example.demo.model.Blog">select * from blog where userId = #{userId}</select>
</mapper>
User 实体类 和 Blog 实体类
在 model 包下 创建 User 类 和 Blog 类
User 类
@Data
public class User {public int userId;public String username;public String password;
}
Blog 类
@Data
public class Blog {public int blogId;public String title;public String content;public Timestamp postTime;public int userId;
}
UserMapper 接口 和 BlogMapper 接口
在 mapper 包下创建 UserMapper 和 BlogMapper 接口
UserMapper
@Mapper
public interface UserMapper {void addUser(User user);User selectByName(String username);User selectById(Integer userId);
}
BlogMapper
@Mapper
public interface BlogMapper {List<Blog> getAllBlog();Blog getBlogByBid(Integer blogId);void postBlog(Blog blog);void deleteBlog(Integer blogId);void updateBlog(Blog blog);List<Blog> getAllBlogById();
}
UserService 类 和 BlogService 类
service
包下创建 UserService类 和 BlogService类
UserService
@Service
public class UserService {@Resourceprivate UserMapper userMapper;public void addUser(User user){userMapper.addUser(user);}public User selectByName(String username){return userMapper.selectByName(username);}public User selectById(Integer userId){return userMapper.selectById(userId);}
}
BlogService
@Service
public class BlogService {@Resourceprivate BlogMapper blogMapper;public List<Blog> getAllBlog(){return blogMapper.getAllBlog();}public Blog getBlogByBid(Integer blogId){return blogMapper.getBlogByBid(blogId);}public void postBlog(Blog blog) {blogMapper.postBlog(blog);}public void deleteBlog(Integer blogId){blogMapper.deleteBlog(blogId);}public void updateBlog(Blog blog){blogMapper.updateBlog(blog);}public List<Blog> getAllBlogById(){return blogMapper.getAllBlogById();}
}
5. 前后端交互接口设计
交互1
交互2
交互3
交互4
交互5
交互6
交互7
交互8
交互9
交互10
交互11
6. 导入前端代码
导入前端代码到 resources
的 static
下
具体代码查看 文章 博客系统前端界面
https://wangzhi430.blog.csdn.net/article/details/124649884
7. 实现博客主页
这里的交互接口是 交互6
7.1 实现后端代码
@RestController
public class IndexController {@Autowiredprivate BlogService blogService;@RequestMapping("/index")public List<Blog> getAllBlog() {return blogService.getAllBlog();}
}
7.2 实现前端代码
$.ajax({url: "index",method: "GET",success: function(data,status) {buildBlogs(data);}})function buildBlogs(blogs){let rightDiv = document.querySelector('.right');for(let blog of blogs){let blogDiv = document.createElement('div');blogDiv.className = 'article';// 创建 titlelet h2 = document.createElement('h2');h2.className = 'title';h2.innerHTML = blog.title;blogDiv.appendChild(h2);// 创建 postTimelet postTime = document.createElement('span');postTime.className = 'date';postTime.innerHTML = DateFormat(blog.postTime);blogDiv.appendChild(postTime);// 创建 contentlet content = document.createElement('div');content.className = 'desc';content.innerHTML = blog.content;blogDiv.appendChild(content);// 创建 详情页的超链接let detailA = document.createElement('a');detailA.className = 'more';detailA.href = 'art.html?blogId=' + blog.blogId;detailA.innerHTML = '查看全文>>';blogDiv.appendChild(detailA);// 加入到 right 中rightDiv.appendChild(blogDiv);}}// 把毫秒级时间戳转化成格式化日期function DateFormat(timeStampMS) {var date = new Date(timeStampMS);var year = date.getFullYear(),month = date.getMonth()+1,//月份是从0开始的day = date.getDate(),hour = date.getHours(),min = date.getMinutes(),sec = date.getSeconds();var newTime = year + '-' +(month < 10? '0' + month : month) + '-' +(day < 10? '0' + day : day) + ' ' +(hour < 10? '0' + hour : hour) + ':' +(min < 10? '0' + min : min) + ':' +(sec < 10? '0' + sec : sec);return newTime;}
7.3 测试代码
7.4 解决页面内容太多超出当前浏览器
7.5 解决页面顺序不是按最新时间排序
在BlogMapper.xml中修改当前sql语句.
7.6 解决内容太多, 导致显示的时候占位太多.
7.7 再次测试代码
8. 实现博客详情页
这里的交互是 交互5
8.1 实现后端代码
根据当前blogId来获取文章, 要判断blogId是否合法, 是否存在当前blogId的文章
这里使用, message来判断, 返回的message不为空就表示异常.
@RestController
public class DetailsController {@Autowiredprivate BlogService blogService;@RequestMapping("/details")public Object ShowBlog(Integer blogId) {HashMap<String,Object> map = new HashMap<>();if (blogId == null || blogId < 1) {map.put("message","blogId异常!");return map;}Blog blog = blogService.getBlogByBid(blogId);if (blog == null) {map.put("message","不存在当前blogId的文章");return map;}return blog;}
}
8.2 实现前端代码
$.ajax({url: "details"+location.search,method: "GET",success: function(data,status) {if(data.message == null) {buildBlog(data);} else {alert(data.message);location.assign("home.html");}}})function buildBlog(blog){// 1. 更新 titlelet titleDiv = document.querySelector('.title');titleDiv.innerHTML = blog.title;// 2. 更新 postTimelet postTime = document.querySelector('.date');postTime.innerHTML = DateFormat(blog.postTime);editormd.markdownToHTML('content', {markdown: blog.content});}// 把毫秒级时间戳转化成格式化日期function DateFormat(timeStampMS) {var date = new Date(timeStampMS);var year = date.getFullYear(),month = date.getMonth()+1,//月份是从0开始的day = date.getDate(),hour = date.getHours(),min = date.getMinutes(),sec = date.getSeconds();var newTime = year + '-' +(month < 10? '0' + month : month) + '-' +(day < 10? '0' + day : day) + ' ' +(hour < 10? '0' + hour : hour) + ':' +(min < 10? '0' + min : min) + ':' +(sec < 10? '0' + sec : sec);return newTime;}
8.3 测试代码
8.4 这里展示为markdown语法的正文
展示为 markdown 语法的正文.
注意这里的几段代码
这里还需要导入依赖包
9. 实现博客登录界面
这里的交互是 交互8
9.1 实现后端代码
这里要根据前端穿过来的 json 格式数据进行判断
判断当前是否存在用户, 以及当前用户密码是否正确
登录成功之后, 要创建一个session
@RestController
public class LoginController {@Autowiredprivate UserService userService;@RequestMapping("/login")public Object userLogin(@RequestBody User user, HttpServletRequest request) {HashMap<String,Object> map = new HashMap<>();if (user == null) {map.put("message","当前还没有输入用户名和密码,登录失败!");return map;}User user1 = userService.selectByName(user.getUsername());if (user1 == null) {map.put("message","当前用户名不存在!");return map;}if (!user.getPassword().equals(user1.getPassword())) {map.put("message","当前用户名密码错误!");return map;}user.setUserId(user1.getUserId());HttpSession session = request.getSession(true);if (session != null) {session.setAttribute("user",user);}return map;}
}
9.2 实现前端代码
这里前端去除了前后空格,以及为空的情况
let submit = document.querySelector('.button');submit.onclick = function() {let username = document.querySelector('.user');let password = document.querySelector('.password');if (username.value.trim() == ""){alert('请先输入用户名!');username.focus();return;}if (password.value.trim() == ""){alert('请先输入密码!');password.focus();return;}$.ajax({url: "login",method: "POST",data: JSON.stringify({username: username.value.trim(), password: password.value.trim()}),contentType: "application/json;charset=utf-8",success: function(data, status) {if(data.message == null) {location.assign("home.html");}else{alert(data.message);username.value="";password.value="";username.focus();}}})}
10. 实现登录判断 — 拦截器
10.1 实现自定义拦截器
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("user") != null) {return true;}response.setStatus(401);response.sendRedirect("/login.html");return false;}
}
10.2 将自定义拦截器加入到系统配置
@Configuration
public class AppConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/**/*.js").excludePathPatterns("/**/*.jpg").excludePathPatterns("/**/*.css").excludePathPatterns("/**/*.png").excludePathPatterns("/**/login.html").excludePathPatterns("/**/register.html").excludePathPatterns("/**/login").excludePathPatterns("/**/register");}
}
11. 实现注册功能
这里的交互是 交互9
11.1 实现后端代码
实现一个 类 Register 来接收前端返回来的数据
class Register {public String username;public String password1;public String password2;
}
这里后端需要判断当前用户名是否已经被使用.
@RestController
public class RegisterController {@Autowiredprivate UserService userService;@RequestMapping("/register")public Object userRegister(@RequestBody Register register) {HashMap<String,Object> map = new HashMap<>();User user = userService.selectByName(register.username);if (user != null) {map.put("message","当前用户名已经存在了, 请更换!");return map;}User user1 = new User();user1.setUsername(register.username);user1.setPassword(register.password1);userService.addUser(user1);return map;}
}
11.2 实现前端代码
要对输入内容去除前后空格,并且判空
let submit = document.querySelector('.button');submit.onclick = function() {let username = document.querySelector('.user');let password1 = document.querySelector('.password1');let password2 = document.querySelector('.password2');if(username.value.trim() == ""){alert("请先输入用户名!");username.focus();return;}if(password1.value.trim() == ""){alert('请先输入密码!');password1.focus();return;}if(password2.value.trim() == ""){alert('请再次输入密码!');password2.focus();return;}if(password1.value.trim() != password2.value.trim()) {alert('两次输入的密码不同!');passwrod1.value="";password2.value="";return;}$.ajax({url: "register",method: "POST",data: JSON.stringify({username: username.value.trim(), password1: password1.value.trim(),password2: password2.value.trim()}),contentType: "application/json;charset=utf-8",success: function(data,status){if(data.message != null){alert(data.message);username.value="";password1.value="";password2.value="";username.focus();}else{location.assign('login.html');}}})}
12. 实现注销功能
这里的交互是 交互10
12.1 实现后端代码
因为 注销功能是点击注销的时候, 触发一个logout的url, 然后发送一个请求.
这里只需要实现后端代码既可
@Controller
public class LogoutController {@RequestMapping("/logout")public void userLogout(HttpServletRequest request, HttpServletResponse response) throws IOException {HttpSession session = request.getSession(false);// 拦截器的拦截, 所以不可能出现session为空的情况session.removeAttribute("user");response.sendRedirect("login.html");}
}
13. 实现博客编辑页
这里的交互是 交互1
13.1 实现后端代码
@RestController
public class EditController {@Autowiredprivate BlogService blogService;@RequestMapping("/edit")public void postBlog(@RequestBody Blog blog, @SessionAttribute(value = "user",required = false)User user){blog.setPostTime(new Timestamp(System.currentTimeMillis()));blog.setUserId(user.getUserId());blogService.postBlog(blog);}
}
13.2 实现前端代码
let submit = document.querySelector('.publish');submit.onclick = function() {let title = document.querySelector('.title');let content = document.querySelector('.content');if(title.value.trim() == ""){alert('当前文章标题为空,请输入!');title.focus();return;}if(content.value.trim() == ""){alert('当前文章内容为空,请输入!');content.focus();return;}$.ajax({url: "edit",method: "POST",data: JSON.stringify({title: title.value.trim(), content: content.value.trim()}),contentType: "application/json;charset=utf-8",success: function(data,status) {location.assign('home.html');}})}
14. 实现博客个人主页
这里的交互是 交互7
这里的前端页面主要就是主页页面的改进
14.1 实现后端代码
@RestController
public class PersonController {@Autowiredprivate BlogService blogService;@RequestMapping("/person")public List<Blog> getMyBlog(@SessionAttribute(value = "user",required = false)User user) {List<Blog> blogs = blogService.getAllBlogById(user.getUserId());for (Blog blog : blogs) {if (blog.getContent().length() > 80) {blog.setContent(blog.getContent().substring(0,80) + " ...");}}return blogs;}
}
14.2 实现前端代码
$.ajax({url: "person",method: "GET",success: function(data,status) {buildBlogs(data);}})function buildBlogs(blogs){let rightDiv = document.querySelector('.right');for(let blog of blogs){let blogDiv = document.createElement('div');blogDiv.className = 'article';// 创建 titlelet h2 = document.createElement('h2');h2.className = 'title';h2.innerHTML = blog.title;blogDiv.appendChild(h2);// 创建 postTimelet postTime = document.createElement('span');postTime.className = 'date';postTime.innerHTML = DateFormat(blog.postTime);blogDiv.appendChild(postTime);// 创建 contentlet content = document.createElement('div');content.className = 'desc';content.innerHTML = blog.content;blogDiv.appendChild(content);// 创建 详情页的超链接let detailA = document.createElement('a');detailA.className = 'more';detailA.href = 'art.html?blogId=' + blog.blogId;detailA.innerHTML = '查看全文>>';blogDiv.appendChild(detailA);// 加入到 right 中rightDiv.appendChild(blogDiv);}}// 把毫秒级时间戳转化成格式化日期function DateFormat(timeStampMS) {var date = new Date(timeStampMS);var year = date.getFullYear(),month = date.getMonth()+1,//月份是从0开始的day = date.getDate(),hour = date.getHours(),min = date.getMinutes(),sec = date.getSeconds();var newTime = year + '-' +(month < 10? '0' + month : month) + '-' +(day < 10? '0' + day : day) + ' ' +(hour < 10? '0' + hour : hour) + ':' +(min < 10? '0' + min : min) + ':' +(sec < 10? '0' + sec : sec);return newTime;}
15. 实现展示用户信息的功能
这里的交互是 交互11
这里需要分情况考虑, 展示个人信息主要是 主页页面, 详情页面, 个人主页页面.
以带不带blogId来区分
15.1 实现后端代码
这里判断了 blogId丢失的情况以及,文章作者丢失情况(数据库表数据被删除的时候会出现这种错误)
@RestController
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate BlogService blogService;@RequestMapping("/user")public Object getUser(Integer blogId, @SessionAttribute(value = "user",required = false)User user){if(blogId == null) {return user;}else {HashMap<String,Object> map = new HashMap<>();Blog blog = blogService.getBlogByBid(blogId);if(blog == null) {map.put("message","不存在当前blogId的文章");return map;}User author = userService.selectById(blog.getUserId());if(author == null){map.put("message","当前文章作者出错");return map;}return author;}}
}
15.2 实现前端代码
详情页的情况:
$.ajax({url: "user"+location.search,method: "GET",success: function(data,status) {if(data.message == null){let username = document.querySelector('.name');username.innerHTML = data.username;}else{alert(data.message);location.assign('home.html');}}})
个人主页和主页的情况
$.ajax({url: "user",method: "GET",success: function(data,status){let username = document.querySelector('.name');username.innerHTML = data.username;}})
16. 实现博客的删除功能
这里需要用到 交互2
这里在详情页的时候进行构建, 在Blog实体类中加一项 isAuthor
, 为1的时候就是当前文章就是作者.
前端接收到这个的时候, 进行判断, 如果为1就显示删除的按钮.
16.1 改进代码
16.2 实现后端代码
@Controller
public class DeleteController {@Autowiredprivate BlogService blogService;@RequestMapping("/delete")public Object deleteBlog(Integer blogId) {blogService.deleteBlog(blogId);return "/home.html";}
}
17. 实现博客的修改功能
这里的交互是 交互3
和 交互4
交互3是在新的页面进行加载
17.1 实现后端代码
@RestController
public class UpdateController {@Autowiredprivate BlogService blogService;@RequestMapping("/updateLoad")public Object updateLoad(Integer blogId){HashMap<String, Object> map = new HashMap<>();if(blogId == null) {map.put("message","blogId丢失!");return map;}Blog blog = blogService.getBlogByBid(blogId);if(blog == null) {map.put("blog","不存在当前blog的文章!");return map;}return blog;}@RequestMapping("/update")public Object Update(Integer blogId, @RequestBody Blog blog, @SessionAttribute(value = "user",required = false)User user) {HashMap<String, Object> map = new HashMap<>();if(blogId == null) {map.put("message","blogId丢失!");return map;}blog.setBlogId(blogId);blog.setUserId(user.getUserId());blogService.updateBlog(blog);return map;}
}
17.2 实现前端代码
$.ajax({url: "updateLoad"+location.search,method: "GET",success: function(data,status) {if(data.message == null) {let title = document.querySelector('.title');title.value=data.title;let content = document.querySelector('.content');content.value=data.content;}else{alert(data.message);location.assign('home.html');}}})// 初始化编辑器var editor = editormd("editor", {// 这里的尺寸必须在这里设置. 设置样式会被 editormd 自动覆盖掉.width: "100%",// 高度 100% 意思是和父元素一样高. 要在父元素的基础上去掉标题编辑区的高度height: "calc(100% - 60px)",// 指定 editor.md 依赖的插件路径path: "editor.md/lib/",// 放到 textarea中saveHTMLToTextArea: true});let submit = document.querySelector('.publish');submit.onclick = function() {let title = document.querySelector('.title');let content = document.querySelector('.content');if(title.value.trim() == ""){alert('当前文章标题为空,请输入!');title.focus();return;}if(content.value.trim() == ""){alert('当前文章内容为空,请输入!');content.focus();return;}$.ajax({url: "update"+location.search,method: "POST",data: JSON.stringify({title: title.value.trim(), content: content.value.trim()}),contentType: "application/json;charset=utf-8",success: function(data,status) {if(data.message == null){location.assign('home.html');}else{alert(data.message);location.assign('home.html');}}})}
基于 SpringBoot + MyBatis 的博客系统相关推荐
- 基于SpringBoot的个人博客系统
项目编号:BS-PT-042 该博客是基于SpringBoot + Mybatis + Thymeleaf 等技术实现的 Java 博客系统,页面美观.功能齐全.部署简单及完善的代码,做为毕设项目的话 ...
- 基于springboot框架的博客系统
1 概览 1.1 文档目的 利用该文档可以搭建一套博客的在线系统,其中包括博客首页以及博客管理等后台系统,可以实现博客预览,博客发布,博客管理以及其他管理功能,来满足工作或者学习上的需要. 1. ...
- 基于springboot+vue个人博客搭建
目录 博客介绍 源码地址:springboot+vue个人博客系统: 基于springboot+vue个人博客系统 在线地址 目录结构 编辑 项目特点 技术介绍 开发环境 项目截图 注意事项: 项目 ...
- 基于 Vue 和 SpringBoot 实现的博客系统(附源码)
今天给大家分享一个基于 Vue 和 SpringBoot 实现的博客系统! 源码在文章结尾处,大家自行下载即可,我设置的免积分下载! 一.主要功能 1.前端 后台管理系统采用Vue开发. 文章模块,支 ...
- (附源码)springboot掌上博客系统 毕业设计 063131
Springboot掌上博客系统的设计与实现 摘 要 掌上博客系统是当今网络的热点,博客技术的出现使得每个人可以零成本.零维护地创建自己的网络媒体,Blog站点所形成的网状结构促成了不同于以往社区的B ...
- 基于python的个人博客系统的设计开题报告_基于SSM的个人博客系统设计开题报告...
本 科 毕 业 设 计(论文)开 题 报 告 题 目:基于SSM的个人博客系统设计与实现 专题题目(若无专题则不填): 本课题来源及研究现状: 关于博客的未来:在创办了博客中国(blogchina) ...
- 基于ssm的个人博客系统的设计与实现(含源文件)
欢迎添加微信互相交流学习哦! 项目源码:https://gitee.com/oklongmm/biye 进入二十一世纪,以Internet为核心的现代网络积水和通信技术已经得到了飞速的发展和广泛的应用 ...
- 【基于python+Django的博客系统-哔哩哔哩】 https://b23.tv/bmRfAMu
[基于python+Django的博客系统-哔哩哔哩] https://b23.tv/bmRfAMu https://b23.tv/bmRfAMu
- 关于博客的论文php,基于php的个人博客系统毕业设计论文
版权声明:以上文章中所选用的图片及文字来源于网络以及用户投稿,由于未联系到知识产权人或未发现有关知识产权的登记,如有知识产权人并不愿意我们使用,如果有侵权请立即联系:55525090@qq.com,我 ...
最新文章
- TensorFlow基础9-多层神经网络
- c++栈和java栈的区别
- Git上传文件到GitHub失败问题解决
- 抓取Web网页数据分析
- splay tree成段更新,成段查询poj3466
- 【Microsoft Azure 的1024种玩法】五十五.Azure speech service之通过JavaScript快速实现文本转换为语音
- excel 取消合并单元格
- web前端项目 - cypress自动化测试运行构建
- Unity特效基础:粒子效果面板
- 网络实名认证接口认证形式有哪些?
- SwiftUI3 新组件教程之 TimelineView 制作一闪一闪星耀效果(中文教程)
- 企业管理必须具备的8大要素!
- [Excel]如何去除恼人的外部链接
- 响应式网站如何实现?
- 冬天到了,女朋友想让我的网站也下雪,我立马打开电脑撸代码…
- 彻底对一个男人失望的瞬间
- 计算机考研 保研夏令营 经验 经历 经验总结
- uniapp的表单验证
- 闲谈【Stable-Diffusion WEBUI】的插件:美不美?交给AI打分
- 大型企业AD架构规划(一)