基于vue+spring的博客系统

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 基于vue+spring的博客系统

系统展示


主页

登录页面

登录成功之后

发布博客

发布成功

点击编辑还可以对自己的文章进行编辑


前端核心代码


主页


1. <template>
2. <div class="mcontaner">
3. <Header></Header>
4. 
5. <div class="block">
6. <el-timeline>
7. 
8. <el-timeline-item :timestamp="blog.created" placement="top" v-for="blog in blogs">
9. <el-card>
10. <h4>
11. <router-link :to="{name: 'BlogDetail', params: {blogId: blog.id}}">
12.                 {{blog.title}}
13. </router-link>
14. </h4>
15. <p>{{blog.description}}</p>
16. </el-card>
17. </el-timeline-item>
18. 
19. </el-timeline>
20. 
21. <el-pagination class="mpage"
22. background
23. layout="prev, pager, next"
24. :current-page="currentPage"
25. :page-size="pageSize"
26. :total="total"
27.                      @current-change=page>
28. </el-pagination>
29. 
30. </div>
31. 
32. </div>
33. </template>
34. 
35. <script>
36. import Header from "../components/Header";
37. 
38. export default {
39. name: "Blogs.vue",
40. components: {Header},
41. data() {
42. return {
43. blogs: {},
44. currentPage: 1,
45. total: 0,
46. pageSize: 5
47.       }
48.     },
49. methods: {
50. page(currentPage) {
51. const _this = this
52.         _this.$axios.get("/blogs?currentPage=" + currentPage).then(res => {
53. console.log(res)
54.           _this.blogs = res.data.data.records
55.           _this.currentPage = res.data.data.current
56.           _this.total = res.data.data.total
57.           _this.pageSize = res.data.data.size
58. 
59.         })
60.       }
61.     },
62. created() {
63. this.page(1)
64.     }
65.   }
66. </script>
67. 
68. <style scoped>
69. 
70. .mpage {
71. margin: 0 auto;
72. text-align: center;
73.   }
74. 
75. </style>

博客编辑页

1. <template>
2. <div>
3. <Header></Header>
4. 
5. <div class="m-content">
6. 
7. <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
8. <el-form-item label="标题" prop="title">
9. <el-input v-model="ruleForm.title"></el-input>
10. </el-form-item>
11. 
12. <el-form-item label="摘要" prop="description">
13. <el-input type="textarea" v-model="ruleForm.description"></el-input>
14. </el-form-item>
15. 
16. <el-form-item label="内容" prop="content">
17. <mavon-editor v-model="ruleForm.content"></mavon-editor>
18. </el-form-item>
19. 
20. <el-form-item>
21. <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
22. <el-button @click="resetForm('ruleForm')">重置</el-button>
23. </el-form-item>
24. </el-form>
25. 
26. </div>
27. 
28. 
29. 
30. </div>
31. </template>
32. 
33. <script>
34. import Header from "../components/Header";
35. export default {
36. name: "BlogEdit.vue",
37. components: {Header},
38. data() {
39. return {
40. ruleForm: {
41. id: '',
42. title: '',
43. description: '',
44. content: ''
45.         },
46. rules: {
47. title: [
48.             { required: true, message: '请输入标题', trigger: 'blur' },
49.             { min: 3, max: 25, message: '长度在 3 到 25 个字符', trigger: 'blur' }
50.           ],
51. description: [
52.             { required: true, message: '请输入摘要', trigger: 'blur' }
53.           ],
54. content: [
55.             { trequired: true, message: '请输入内容', trigger: 'blur' }
56.           ]
57.         }
58.       };
59.     },
60. methods: {
61. submitForm(formName) {
62. this.$refs[formName].validate((valid) => {
63. if (valid) {
64. 
65. const _this = this
66. this.$axios.post('/blog/edit', this.ruleForm, {
67. headers: {
68. "Authorization": localStorage.getItem("token")
69.               }
70.             }).then(res => {
71. console.log(res)
72.               _this.$alert('操作成功', '提示', {
73. confirmButtonText: '确定',
74. callback: action => {
75.                   _this.$router.push("/blogs")
76.                 }
77.               });
78. 
79.             })
80. 
81.           } else {
82. console.log('error submit!!');
83. return false;
84.           }
85.         });
86.       },
87. resetForm(formName) {
88. this.$refs[formName].resetFields();
89.       }
90.     },
91. created() {
92. const blogId = this.$route.params.blogId
93. console.log(blogId)
94. const _this = this
95. if(blogId) {
96. this.$axios.get('/blog/' + blogId).then(res => {
97. const blog = res.data.data
98.           _this.ruleForm.id = blog.id
99.           _this.ruleForm.title = blog.title
100.           _this.ruleForm.description = blog.description
101.           _this.ruleForm.content = blog.content
102.         })
103.       }
104. 
105.     }
106.   }
107. </script>
108. 
109. <style scoped>
110. .m-content {
111. text-align: center;
112.   }
113. </style>

登录页面


1. <template>
2. <div>
3. 
4. <el-container>
5. <el-header>
6. <img class="mlogo" src="https://www.markerhub.com/dist/images/logo/markerhub-logo.png" alt="">
7. </el-header>
8. <el-main>
9. 
10. <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
11. <el-form-item label="用户名" prop="username">
12. <el-input v-model="ruleForm.username"></el-input>
13. </el-form-item>
14. <el-form-item label="密码" prop="password">
15. <el-input type="password" v-model="ruleForm.password"></el-input>
16. </el-form-item>
17. 
18. <el-form-item>
19. <el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
20. <el-button @click="resetForm('ruleForm')">重置</el-button>
21. <el-button ><el-link href="/blogs">主页</el-link></el-button>
22. 
23. </el-form-item>
24. </el-form>
25. 
26. </el-main>
27. </el-container>
28. 
29. </div>
30. </template>
31. 
32. <script>
33. export default {
34. name: "Login",
35. data() {
36. return {
37. ruleForm: {
38. username: 'sy',
39. password: '111111'
40.         },
41. rules: {
42. username: [
43.             { required: true, message: '请输入用户名', trigger: 'blur' },
44.             { min: 0, max: 15, message: '长度在 3 到 15 个字符', trigger: 'blur' }
45.           ],
46. password: [
47.             { required: true, message: '请选择密码', trigger: 'change' }
48.           ]
49.         }
50.       };
51.     },
52. methods: {
53. submitForm(formName) {
54. this.$refs[formName].validate((valid) => {
55. if (valid) {
56. const _this = this
57. this.$axios.post('/login', this.ruleForm).then(res => {
58. 
59. console.log(res.data)
60. const jwt = res.headers['authorization']
61. const userInfo = res.data.data
62. 
63. // 把数据共享出去
64.               _this.$store.commit("SET_TOKEN", jwt)
65.               _this.$store.commit("SET_USERINFO", userInfo)
66. 
67. // 获取
68. console.log(_this.$store.getters.getUser)
69. 
70.               _this.$router.push("/blogs")
71.             })
72. 
73.           } else {
74. console.log('error submit!!');
75. return false;
76.           }
77.         });
78.       },
79. resetForm(formName) {
80. this.$refs[formName].resetFields();
81.       }
82.     }
83.   }
84. </script>
85. 
86. <style scoped>
87. .el-header, .el-footer {
88. background-color: #B3C0D1;
89. color: #333;
90. text-align: center;
91. line-height: 60px;
92.   }
93. 
94. .el-aside {
95. background-color: #D3DCE6;
96. color: #333;
97. text-align: center;
98. line-height: 200px;
99.   }
100. 
101. .el-main {
102. /*background-color: #E9EEF3;*/
103. color: #333;
104. text-align: center;
105. line-height: 160px;
106.   }
107. 
108. body > .el-container {
109. margin-bottom: 40px;
110.   }
111. 
112. .el-container:nth-child(5) .el-aside,
113. .el-container:nth-child(6) .el-aside {
114. line-height: 260px;
115.   }
116. 
117. .el-container:nth-child(7) .el-aside {
118. line-height: 320px;
119.   }
120. 
121. .mlogo {
122. height: 60%;
123. margin-top: 10px;
124.   }
125. 
126. .demo-ruleForm {
127. max-width: 500px;
128. margin: 0 auto;
129.   }
130. 
131. </style>

博客详情页

1. <template>
2. <div>
3. <Header></Header>
4. 
5. <div class="mblog">
6. <h2> {{ blog.title }}</h2>
7. <el-link icon="el-icon-edit" v-if="ownBlog">
8. <router-link :to="{name: 'BlogEdit', params: {blogId: blog.id}}" >
9.         编辑
10. </router-link>
11. </el-link>
12. <el-divider></el-divider>
13. <div class="markdown-body" v-html="blog.content"></div>
14. 
15. </div>
16. 
17. </div>
18. </template>
19. 
20. <script>
21. import 'github-markdown-css'
22. import Header from "../components/Header";
23. 
24. export default {
25. name: "BlogDetail.vue",
26. components: {Header},
27. data() {
28. return {
29. blog: {
30. id: "",
31. title: "",
32. content: ""
33.         },
34. ownBlog: false
35.       }
36.     },
37. created() {
38. const blogId = this.$route.params.blogId
39. console.log(blogId)
40. const _this = this
41. this.$axios.get('/blog/' + blogId).then(res => {
42. const blog = res.data.data
43.         _this.blog.id = blog.id
44.         _this.blog.title = blog.title
45. 
46. var MardownIt = require("markdown-it")
47. var md = new MardownIt()
48. 
49. var result = md.render(blog.content)
50.         _this.blog.content = result
51.         _this.ownBlog = (blog.userId === _this.$store.getters.getUser.id)
52. 
53.       })
54.     }
55.   }
56. </script>
57. 
58. <style scoped>
59. .mblog {
60. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
61. width: 100%;
62. min-height: 700px;
63. padding: 20px 15px;
64.   }
65. 
66. </style>

后端代码


博客接口


1. @RestController
2. public class BlogController {
3. 
4. @Autowired
5.     BlogService blogService;
6. 
7. //    列表
8. @GetMapping("/blogs")
9. public Result list(@RequestParam(defaultValue = "1") Integer currentPage) {
10. 
11. Page page = new Page(currentPage, 5);
12. IPage pageData = blogService.page(page, new QueryWrapper<Blog>().orderByDesc("created"));
13. 
14. return Result.succ(pageData);
15.     }
16. 
17. 
18. 
19. //    详情
20. @GetMapping("/blog/{id}")
21. public Result detail(@PathVariable(name = "id") Long id) {
22. Blog blog = blogService.getById(id);
23.         Assert.notNull(blog, "该博客已被删除");
24. 
25. return Result.succ(blog);
26.     }
27. 
28. //    编辑
29. @RequiresAuthentication
30. @PostMapping("/blog/edit")
31. public Result edit(@Validated @RequestBody Blog blog) {
32. 
33. //        Assert.isTrue(false, "公开版不能任意编辑!");
34. 
35. Blog temp = null;
36. if(blog.getId() != null) {
37.             temp = blogService.getById(blog.getId());
38. // 只能编辑自己的文章
39.             System.out.println(ShiroUtil.getProfile().getId());
40.             Assert.isTrue(temp.getUserId().longValue() == ShiroUtil.getProfile().getId().longValue(), "没有权限编辑");
41. 
42.         } else {
43. 
44.             temp = new Blog();
45.             temp.setUserId(ShiroUtil.getProfile().getId());
46.             temp.setCreated(LocalDateTime.now());
47.             temp.setStatus(0);
48.         }
49. 
50.         BeanUtil.copyProperties(blog, temp, "id", "userId", "created", "status");
51.         blogService.saveOrUpdate(temp);
52. 
53. return Result.succ(null);
54.     }
55. 
56. }

用户校验接口

1. @RestController
2. public class AccountController {
3. 
4. @Autowired
5.     UserService userService;
6. 
7. @Autowired
8.     JwtUtils jwtUtils;
9. 
10. @PostMapping("/login")
11. public Result login(@Validated @RequestBody LoginDto loginDto, HttpServletResponse response) {
12. 
13.         System.out.println(loginDto.getUsername());
14. User user = userService.getOne(new QueryWrapper<User>().eq("username", loginDto.getUsername()));
15. 
16.         System.out.println(2222);
17.         Assert.notNull(user, "用户不存在");
18. 
19. if(!user.getPassword().equals(SecureUtil.md5(loginDto.getPassword()))){
20. return Result.fail("密码不正确");
21.         }
22. String jwt = jwtUtils.generateToken(user.getId());
23. 
24.         response.setHeader("Authorization", jwt);
25.         response.setHeader("Access-control-Expose-Headers", "Authorization");
26. 
27. return Result.succ(MapUtil.builder()
28.                 .put("id", user.getId())
29.                 .put("username", user.getUsername())
30.                 .put("avatar", user.getAvatar())
31.                 .put("email", user.getEmail())
32.                 .map()
33.         );
34.     }
35. 
36. @RequiresAuthentication
37. @GetMapping("/logout")
38. public Result logout() {
39.         SecurityUtils.getSubject().logout();
40. return Result.succ(null);
41.     }
42. 
43. }

spring整合shiro

1. @Component
2. public class JwtFilter extends AuthenticatingFilter {
3. @Autowired
4.     JwtUtils jwtUtils;
5. 
6. @Override
7. protected AuthenticationToken createToken(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
8. HttpServletRequest request = (HttpServletRequest) servletRequest;
9. String jwt = request.getHeader("Authorization");
10. if(StringUtils.isEmpty(jwt)) {
11. return null;
12.         }
13. 
14. return new JwtToken(jwt);
15.     }
16. 
17. @Override
18. protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
19. HttpServletRequest request = (HttpServletRequest) servletRequest;
20. String jwt = request.getHeader("Authorization");
21. if(StringUtils.isEmpty(jwt)) {
22. return true;
23.         } else {
24. // 校验jwt
25. Claims claim = jwtUtils.getClaimByToken(jwt);
26. if(claim == null || jwtUtils.isTokenExpired(claim.getExpiration())) {
27. throw new ExpiredCredentialsException("token已失效,请重新登录");
28.             }
29. 
30. // 执行登录
31. return executeLogin(servletRequest, servletResponse);
32.         }
33.     }
34. 
35. @Override
36. protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
37. 
38. HttpServletResponse httpServletResponse = (HttpServletResponse) response;
39. 
40. Throwable throwable = e.getCause() == null ? e : e.getCause();
41. Result result = Result.fail(throwable.getMessage());
42. String json = JSONUtil.toJsonStr(result);
43. 
44. try {
45.             httpServletResponse.getWriter().print(json);
46.         } catch (IOException ioException) {
47. 
48.         }
49. return false;
50.     }
51. 
52. @Override
53. protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
54. 
55. HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
56. HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
57.         httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
58.         httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
59.         httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
60. // 跨域时会首先发送一个OPTIONS请求,这里我们给OPTIONS请求直接返回正常状态
61. if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
62.             httpServletResponse.setStatus(org.springframework.http.HttpStatus.OK.value());
63. return false;
64.         }
65. 
66. return super.preHandle(request, response);
67.     }
68. 
69. }
1. @Configuration
2. public class ShiroConfig {
3. 
4. @Autowired
5.     JwtFilter jwtFilter;
6. 
7. @Bean
8. public SessionManager sessionManager(RedisSessionDAO redisSessionDAO) {
9. DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
10. 
11. // inject redisSessionDAO
12.         sessionManager.setSessionDAO(redisSessionDAO);
13. return sessionManager;
14.     }
15. 
16. @Bean
17. public DefaultWebSecurityManager securityManager(AccountRealm accountRealm,
18.                                                      SessionManager sessionManager,
19.                                                      RedisCacheManager redisCacheManager) {
20. 
21. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(accountRealm);
22. 
23. //inject sessionManager
24.         securityManager.setSessionManager(sessionManager);
25. 
26. // inject redisCacheManager
27.         securityManager.setCacheManager(redisCacheManager);
28. return securityManager;
29.     }
30. 
31. @Bean
32. public ShiroFilterChainDefinition shiroFilterChainDefinition() {
33. DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
34. 
35.         Map<String, String> filterMap = new LinkedHashMap<>();
36. 
37. 
38.         filterMap.put("/**", "jwt");
39.         chainDefinition.addPathDefinitions(filterMap);
40. return chainDefinition;
41.     }
42. 
43. @Bean("shiroFilterFactoryBean")
44. public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager,
45.                                                          ShiroFilterChainDefinition shiroFilterChainDefinition) {
46. ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
47.         shiroFilter.setSecurityManager(securityManager);
48. 
49.         Map<String, Filter> filters = new HashMap<>();
50.         filters.put("jwt", jwtFilter);
51. 
52. 
53.         shiroFilter.setFilters(filters);
54. 
55.         Map<String, String> filterMap = shiroFilterChainDefinition.getFilterChainMap();
56. 
57.         shiroFilter.setFilterChainDefinitionMap(filterMap);
58. return shiroFilter;
59.     }
60. 
61. 
62. }

数据库设计


1. SET NAMES utf8mb4;
2. SET FOREIGN_KEY_CHECKS = 0;
3. 
4. -- ----------------------------
5. -- Table structure for m_blog
6. -- ----------------------------
7. DROP TABLE IF EXISTS `m_blog`;
8. CREATE TABLE `m_blog`  (
9.   `id` bigint(20) NOT NULL AUTO_INCREMENT,
10.   `user_id` bigint(20) NOT NULL,
11.   `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
12.   `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
13.   `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
14.   `created` datetime NOT NULL,
15.   `status` tinyint(4) NULL DEFAULT NULL,
16. PRIMARY KEY (`id`) USING BTREE
17. ) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
18. 
19. -- ----------------------------
20. -- Records of m_blog
21. -- ----------------------------
22. INSERT INTO `m_blog` VALUES (6, 2, '123', '321', '123213', '2022-12-20 12:14:56', 0);
23. INSERT INTO `m_blog` VALUES (7, 1, 'syy', '23', '12321321321', '2022-12-20 12:52:00', 0);
24. INSERT INTO `m_blog` VALUES (8, 1, '123213', '123213', 'ceshi', '2022-12-21 07:46:34', 0);
25. INSERT INTO `m_blog` VALUES (9, 1, '测试1', '测试二', '测试', '2022-12-29 04:20:06', 0);
26. 
27. -- ----------------------------
28. -- Table structure for m_discussion
29. -- ----------------------------
30. DROP TABLE IF EXISTS `m_discussion`;
31. CREATE TABLE `m_discussion`  (
32.   `id` bigint(20) NOT NULL AUTO_INCREMENT,
33.   `user_id` bigint(20) NOT NULL,
34.   `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
35.   `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
36.   `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
37.   `created` datetime NOT NULL,
38.   `status` tinyint(4) NULL DEFAULT NULL,
39. PRIMARY KEY (`id`) USING BTREE
40. ) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
41. 
42. -- ----------------------------
43. -- Records of m_discussion
44. -- ----------------------------
45. INSERT INTO `m_discussion` VALUES (1, 1, '小明', '五行学习法很不错', '五行学习法很好', '2020-10-13 21:05:31', 0);
46. INSERT INTO `m_discussion` VALUES (6, 1, '小李', 'nice', '内容', '2022-11-21 15:25:15', 0);
47. INSERT INTO `m_discussion` VALUES (7, 1, '小张', '不错', '', '2022-11-21 16:15:57', 0);
48. INSERT INTO `m_discussion` VALUES (8, 1, '小伤', '挺好的', '', '2022-11-21 16:25:36', 0);
49. INSERT INTO `m_discussion` VALUES (9, 1, 'shangyi', '挺不错的', '', '2022-11-21 16:27:00', 0);
50. INSERT INTO `m_discussion` VALUES (10, 1, '小商', '很好', '', '2022-11-21 16:31:49', 0);
51. INSERT INTO `m_discussion` VALUES (11, 1, '小诗', '挺好的', '', '2022-11-21 16:34:11', 0);
52. INSERT INTO `m_discussion` VALUES (12, 1, '尚艺', '很好', '', '2022-11-25 16:55:35', 0);
53. INSERT INTO `m_discussion` VALUES (13, 1, '11', '11', '', '2022-12-09 14:19:00', 0);
54. INSERT INTO `m_discussion` VALUES (14, 1, '111', '111112', '', '2022-12-09 15:31:43', 0);
55. INSERT INTO `m_discussion` VALUES (15, 1, '小诺', '12三大', '', '2022-12-09 15:33:04', 0);
56. INSERT INTO `m_discussion` VALUES (16, 1, '12', '123', '', '2022-12-09 15:34:20', 0);
57. INSERT INTO `m_discussion` VALUES (17, 1, '111', '111', '', '2022-12-09 16:25:59', 0);
58. INSERT INTO `m_discussion` VALUES (18, 1, 'xiao', '123', '', '2022-12-09 16:59:00', 0);
59. 
60. -- ----------------------------
61. -- Table structure for m_user
62. -- ----------------------------
63. DROP TABLE IF EXISTS `m_user`;
64. CREATE TABLE `m_user`  (
65.   `id` bigint(20) NOT NULL AUTO_INCREMENT,
66.   `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
67.   `avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
68.   `email` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
69.   `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
70.   `status` int(5) NOT NULL,
71.   `created` datetime NULL DEFAULT NULL,
72.   `last_login` datetime NULL DEFAULT NULL,
73.   `like` int(23) NULL DEFAULT NULL,
74.   `collection` int(11) NULL DEFAULT NULL,
75.   `visit` int(11) NULL DEFAULT NULL,
76. PRIMARY KEY (`id`) USING BTREE,
77.   INDEX `UK_USERNAME`(`username`) USING BTREE
78. ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
79. 
80. -- ----------------------------
81. -- Records of m_user
82. -- ----------------------------
83. INSERT INTO `m_user` VALUES (1, 'sy', 'https://image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/5a9f48118166308daba8b6da7e466aab.jpg', NULL, '96e79218965eb72c92a549dd5a330112', 0, '2020-04-20 10:44:01', NULL, NULL, NULL, NULL);
84. INSERT INTO `m_user` VALUES (2, 'xia', NULL, NULL, '96e79218965eb72c92a549dd5a330112', 0, NULL, NULL, NULL, NULL, NULL);
85. 
86. SET FOREIGN_KEY_CHECKS = 1;


代码地址


博客系统: 博客系统初态,可以发表文章,浏览文章

 

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
131 62
|
22天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
107 13
|
28天前
|
Java 数据库 数据安全/隐私保护
轻松掌握Spring依赖注入:打造你的登录验证系统
本文以轻松活泼的风格,带领读者走进Spring框架中的依赖注入和登录验证的世界。通过详细的步骤和代码示例,我们从DAO层的创建到Service层的实现,再到Spring配置文件的编写,最后通过测试类验证功能,一步步构建了一个简单的登录验证系统。文章不仅提供了实用的技术指导,还以口语化和生动的语言,让学习变得不再枯燥。
40 2
|
30天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
2月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
124 2
|
2月前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
2月前
|
JavaScript NoSQL Java
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
53 0
|
前端开发 JavaScript Java
前后端分离之Spring&Vue单页面开发(2)
前言     需求: 最近本人在学习SpringBoot,希望自己能搭一个简单的Demo应用出来,但是搭到前端的时候遇到了困惑,因为网络上大部分教程前端都是应用模板引擎thymeleaf生成的,它给我的感觉就是一个进化版的JSP,但是很明显这种开发方式已经有些落后了。
4116 0
|
6天前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
51 1
|
17天前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。