码神之路网站所使用的博客,项目简单,需求明确,容易上手,非常适合做为练手级项目。
blog.mszlu.com
项目讲解说明:
- 提供前端工程,只需要实现后端接口即可项目以单体架构入手,先快速开发,不考虑项目优化,降低开发负担开发完成后,开始优化项目,提升编程思维能力比如页面静态化,缓存,云存储,日志等docker部署上线云服务器购买,域名购买,域名备案等
项目使用技术 :
springboot + mybatisplus+redis+mysql
1. 工程搭建前端的工程:
npm install npm run build npm run dev1.1 新建maven工程
导入依赖
1.2 配置4.0.0 com.mszlu blog-parent1.0-SNAPSHOT org.springframework.boot spring-boot-starter-parent2.5.0 UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starterorg.springframework.boot spring-boot-starter-loggingorg.springframework.boot spring-boot-starter-log4j2org.springframework.boot spring-boot-starter-aoporg.springframework.boot spring-boot-starter-mailorg.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-testtest org.springframework.boot spring-boot-starter-data-rediscom.alibaba fastjson1.2.76 mysql mysql-connector-javaorg.springframework.boot spring-boot-configuration-processortrue org.apache.commons commons-lang3commons-collections commons-collections3.2.2 com.baomidou mybatis-plus-boot-starter3.4.3 org.projectlombok lombokjoda-time joda-time2.10.10 org.springframework.boot spring-boot-maven-plugin
在application.properties配置文件中配置数据库和Mybatisplus的配置
#server server.port= 8888 spring.application.name=mszlu_blog # datasource spring.datasource.url=jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=UTF-8&serverTimeZone=UTC spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #mybatis-plus mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl mybatis-plus.global-config.db-config.table-prefix=ms_
创建config包,在包下面创建MybatisPlusConfig类
@Configuration //扫包,将此包下的接口生成代理实现类,并且注册到spring容器中 @MapperScan("com.mszlu.blog.dao") public class MybatisPlusConfig { //分页插件 @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } }
同样在config包下创建WebConfig类实现WebMvcConfigurer 接口,进行跨域配置
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { //跨域配置,不可设置为*,不安全, 前后端分离项目,可能域名不一致 //本地测试 端口不一致 也算跨域 registry.addMapping(" private Long authorId; private Long bodyId; private Long categoryId; private int weight = Article_Common; private Long createDate; }
创建作者的实体类
package com.mszlu.blog.dao.pojo; import lombok.Data; @Data public class SysUser { private Long id; private String account; private Integer admin; private String avatar; private Long createDate; private Integer deleted; private String email; private Long lastLogin; private String mobilePhoneNumber; private String nickname; private String password; private String salt; private String status; }
创建标签的实体类
package com.mszlu.blog.dao.pojo; import lombok.Data; @Data public class Tag { private Long id; private String avatar; private String tagName; }2.2.2 Controller
//Json数据进行交互 @RestController @RequestMapping("/articles") public class ArticleController { @Autowired private ArticleService articleService; @PostMapping public result listArticle(@RequestBody PageParams pageParams) { return articleService.listArticle(pageParams); } }
统一最后的结果
package com.mszlu.blog.vo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class result { private boolean success; private int code; private String msg; private Object data; public static result success(Object data){ return new result(true,200,"success",data); } public static result fail(int code,String msg){ return new result(false,code,msg,null); } }
创建ArticleVo用于前端数据展示
@Data public class ArticleVo { private Long id; private String title; private String summary; private int commentCounts; private int viewCounts; private int weight; private String createDate; private String author; private ArticleBodyVo body; private List2.2.3 Servicetags; private List categorys; }
建立文章的业务层接口
public interface ArticleService { result listArticle(PageParams pageParams); }
创建ArticleServiceImpl类实现service业务层接口
@Service public class ArticleServiceImpl implements ArticleService { @Autowired private ArticleMapper articleMapper; @Autowired private TagService tagService; @Autowired private SysUserService sysUserService; @Override public result listArticle(PageParams pageParams) { Page page = new Page<>(pageParams.getPage(),pageParams.getPageSize()); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); //是否置顶 //order by creat_time queryWrapper.orderByDesc(Article::getWeight,Article::getCreateDate); Page articlePage = articleMapper.selectPage(page, queryWrapper); List records = articlePage.getRecords(); //不能直接返回 List articleVoList = copyList(records,true,true); return result.success(articleVoList); } private List copyList(List records,boolean isTag,boolean isAuthor) { List articleVoList = new ArrayList<>(); for (Article record : records) { articleVoList.add(copy(record,isTag,isAuthor)); } return articleVoList; } //把文章的字段数据传递给copy用于前端展示 private ArticleVo copy(Article article,boolean isTag,boolean isAuthor){ ArticleVo articleVo = new ArticleVo(); //进行对象之间属性的赋值 BeanUtils.copyProperties(article,articleVo); articleVo.setCreateDate(new DateTime(article.getCreateDate()).toString("yyyy-mm-dd HH:mm")); //并不是所有的接口都需要标签,作者信息 if(isTag){ Long articleId = article.getId(); ListtagVos = tagService.findTagByArticleId(articleId); articleVo.setTags(tagVos); } if(isAuthor){ Long authorId = article.getAuthorId(); SysUser user = sysUserService.findUserById(authorId); articleVo.setAuthor(user.getNickname()); } return articleVo; } }
创建用户的业务层接口
public interface SysUserService { SysUser findUserById(Long id); }
实现作者的业务层接口
@Service public class SysUserServiceImpl implements SysUserService { @Autowired private SysUserMapper sysUserMapper; @Override public SysUser findUserById(Long id) { SysUser sysUser = sysUserMapper.selectById(id); //判断查询sysUser对象是否为空,如果为空则给昵称复制,避免空指针异常 if(sysUser == null){ sysUser = new SysUser(); sysUser.setNickname("码神之路"); } return sysUser; } }
创建标签的业务层接口
public interface TagsService { ListfindTagsByArticleId(Long id); }
实现标签的业务层接口
@Service public class TagsServiceImpl implements TagsService { @Autowired private TagMapper tagMapper; public TagVo copy(Tag tag){ TagVo tagVo = new TagVo(); BeanUtils.copyProperties(tag,tagVo); return tagVo; } public List2.2.4 DaocopyList(List tagList){ List tagVoList = new ArrayList<>(); for (Tag tag : tagList) { tagVoList.add(copy(tag)); } return tagVoList; } @Override public List findTagByArticleId(Long articleId) { //myBatisPlus无法进行多表查询 List tags = tagMapper.findTagsByArticleId(articleId); return copyList(tags); } }
文章的持久层接口
public interface ArticleMapper extends baseMapper { }
标签的持久层接口
public interface TagMapper extends baseMapper{ List findTagsByArticleId(Long articleId); }
作者的持久层接口
public interface SysUserMapper extends baseMapper{ }
总的xml文件如下所示
2.2.5 测试 3. 首页-最热标签 3.1 接口说明id,avatar,tag_name as tagName
接口url:/tags/hot
请求方式:GET
请求参数:无
返回数据:
{ "success": true, "code": 200, "msg": "success", "data": [ { "id":1, "tagName":"4444" } ] }3.2 编码 3.2.1 Controller
先编写标签的业务层
@RestController @RequestMapping("/tags") public class TagController { @Autowired private TagService tagService; @GetMapping("/hot") private result hot(){ int limit = 6; return tagService.hots(limit); } }
标签与前端交互的Vo
package com.mszlu.blog.vo; import lombok.Data; @Data public class TagVo { private Long id; private String tagName; }3.2.2 Service
最热标签功能的业务层接口
public interface TagsService { Listhot(int limit); }
业务层接口的实现
@Override public result hots(int limit) { List3.2.3 DaotagIds = tagMapper.findHotsTagByIds(limit); if(CollectionUtils.isEmpty(tagIds)){ return result.success(Collections.emptyList()); } //需求的是 tagId 和 tagName Tag对象 //select * from tag where id in (1,2,3) 所以要判断tagIds是否为空 List tagList = tagMapper.findTagsByTagsId(tagIds); return result.success(tagList); }
持久层接口的编写
public interface TagMapper extends baseMapper{ List findHotsTagByIds(int limit); List findTagsByTagsId(List tagIds); }
标签持久层接口对应的xml文件
3.2.4 测试id,avatar,tag_name as tagName select from ms_tag where id in #{tagId}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)