十次方后端笔记二:招聘、问答、文章和活动微服务
使用代码生成器完成招聘、问答、文章以及活动微服务

完成招聘、问答、文章以及活动微服务,并使用为部分数据添加缓存机制

招聘微服务

招聘微服务CRUD代码生成(省略)

表结构分析

招聘微服务分为两块:

  • 企业信息
  • 招聘信息

tb_enterprise 企业表

字段名称 字段含义 字段类型 备注
id ID 文本
name 企业名称 文本
summary 企业简介 文本
address 企业地址 文本
labels 标签列表 文本 用逗号分隔
coordinate 企业位置坐标 文本 经度,纬度
ishot 是否热门 文本 0:非热门1:热门
logo LOGO 文本
jobcount 职位数 数字
url URL 文本

tb_recruit 招聘信息表

字段名称 字段含义 字段类型 备注
id ID 文本
jobname 招聘职位 文本
salary 薪资范围 文本
condition 经验要求 文本
education 学历要求 文本
type 任职方式 文本
address 办公地址 文本
eid 企业ID 文本
createtime 发布日期 日期
state 状态 文本 0:关闭1:开启 2:推荐
url 原网址 文本
label 标签 文本
content1 职位描述 文本
content2 职位要求 文本

热门企业列表

controller

1
2
3
4
@GetMapping("/search/hotlist")
public Result hotlist() {
return Result.ok("查询成功", enterpriseService.hotlist());
}

service

1
2
3
public List<Enterprise> hotlist() {
return enterpriseDao.findByIshot("1");
}

dao

1
List<Enterprise> findByIshot(String ishot);

推荐职位列表

查询状态为2并以创建日期降序排序,查询前4条记录

controller

1
2
3
4
5
6
7
/**
* 推荐职位
*/
@GetMapping("search/recommend")
public Result findRecommend() {
return Result.ok(recruitService.findTop4ByStateOrderByCreatetimeDesc("2"));
}

service

1
2
3
4
5
6
7
/**
* 查询推荐职位
* @return
*/
public List<Recruit> findTop4ByStateOrderByCreatetimeDesc(String state) {
return recruitDao.findTop4ByStateOrderByCreatetimeDesc(state);
}

dao

1
List<Recruit> findTop4ByStateOrderByCreatetimeDesc(String state);

最新职位列表

查询状态不为0并以创建日期降序排序,查询前12条记录

controller

1
2
3
4
5
6
7
/**
* 最新职位
*/
@GetMapping("search/newlist")
public Result findNewRecruitList() {
return Result.ok(recruitService.findNewRecruitList());
}

service

1
2
3
4
5
6
7
/**
* 查询最新职位列表
* 查询最新的12条以及排除被关闭的职位
*/
public List<Recruit> findNewRecruitList() {
return recruitDao.findTop12ByStateNotOrderByCreatetimeDesc("0");
}

dao

1
List<Recruit> findTop12ByStateNotOrderByCreatetimeDesc(String state);

问答微服务

问答微服务CRUD代码生成(省略)

生成过后需要手动添加关系表的实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.tensquare.qa.pojo;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;

@Data
@Entity
@Table(name = "tb_pl")
public class Pl implements Serializable {

@Id
private String problemid;

@Id
private String labelid;
}

表结构分析

问答微服务的表分为两张数据表以及一张关系表:问题表、回答表以及问答标签关系表

tb_problem 问题表

字段名称 字段含义 字段类型 备注
id ID 文本
title 问题标题 文本
content 问题内容 文本
createtime 发布日期 日期
updatetime 更新日期 日期
userid 发布人ID 文本
nickname 发布人昵称 文本
visits 浏览量 整型
thumbup 点赞数 整型
reply 回复数 整型
solve 是否解决 文本
replyname 最新回复人 文本
replytime 最新回复时间 日期

tb_reply 回答表

字段名称 字段含义 字段类型 备注
id ID 文本
problemid 问题ID 文本
content 问题内容 文本
createtime 发布日期 日期
updatetime 更新日期 日期
userid 发布人ID 文本
nickname 发布人昵称 文本

tb_pl 问题标签关系表

字段名称 字段含义 字段类型 备注
problemid 问题ID 文本
labelid 标签ID 文本

最新问题列表

最新回复的问题显示在上方,按回复时间降序排序。

controller

1
2
3
4
5
6
7
8
9
/**
* 最新问题列表
*/
@GetMapping("newlist/{label}/{page}/{size}")
public Result findNewProblemList(@PathVariable("label") String labelId,
@PathVariable("page") int page,
@PathVariable("size") int size) {
return Result.ok(problemService.findNewProblemList(labelId, page, size));
}

service

1
2
3
4
5
6
7
8
9
10
11
/**
* 按活跃时间查询问题列表
*
* @param labelId 标签ID
* @param page 当前页码
* @param size 当前页记录数
* @return List<Problem> 问题列表
*/
public List<Problem> findNewProblemList(String labelId, int page, int size) {
return problemDao.findNewProblemList(labelId, PageRequest.of(page, size));
}

dao

1
2
3
4
@Query("SELECT p FROM Problem p " +
"WHERE id IN (SELECT pl.problemid FROM Pl pl WHERE pl.labelid = ?1) " +
"ORDER BY p.replytime DESC")
List<Problem> findNewProblemList(String labelId, Pageable pageable);

热门问题列表

按回复数降序排序

controller

1
2
3
4
5
6
7
8
9
/**
* 热门问题列表
*/
@GetMapping("hotlist/{label}/{page}/{size}")
public Result findHotList(@PathVariable("label") String labelId,
@PathVariable("page") int page,
@PathVariable("size") int size) {
return Result.ok(problemService.findHotList(labelId, page, size));
}

service

1
2
3
4
5
6
7
8
9
10
11
/**
* 查询热门问题列表
*
* @param labelId 标签ID
* @param page 当前页码
* @param size 当前页记录数
* @return List<Problem> 问题列表
*/
public List<Problem> findHotList(String labelId, int page, int size) {
return problemDao.findHotProblemList(labelId, PageRequest.of(page, size));
}

dao

1
2
3
4
@Query("SELECT p FROM Problem p " +
"WHERE id IN (SELECT pl.problemid FROM Pl pl WHERE pl.labelid = ?1) " +
"ORDER BY p.reply DESC")
List<Problem> findHotProblemList(String labelId, Pageable pageable);

等待回答列表

controller

1
2
3
4
5
6
7
8
9
/**
* 待回复问题列表
*/
@GetMapping("waitlist/{label}/{page}/{size}")
public Result findWaitList(@PathVariable("label") String labelId,
@PathVariable("page") int page,
@PathVariable("size") int size) {
return Result.ok(problemService.findWaitList(labelId, page, size));
}

service

1
2
3
4
5
6
7
8
9
10
11
/**
* 查询待回复问题列表
*
* @param labelId 标签ID
* @param page 当前页码
* @param size 当前页记录数
* @return List<Problem> 问题列表
*/
public List<Problem> findWaitList(String labelId, int page, int size) {
return problemDao.findWaitReplyProblemList(labelId, PageRequest.of(page, size));
}

dao

1
2
3
4
5
@Query("SELECT p FROM Problem p " +
"WHERE id IN (SELECT pl.problemid FROM Pl pl WHERE pl.labelid = ?1) " +
"AND p.reply = 0 " +
"ORDER BY p.createtime DESC")
List<Problem> findWaitReplyProblemList(String labelId, Pageable pageable);

文章微服务

文章微服务CRUD代码生成(省略)

表结构分析

文章微服务只有一张表:文章表

tb_article 文章表

字段名称 字段含义 字段类型 备注
id ID 文本
columnid 专栏ID 文本
userid 用户ID 文本
title 文章标题 文本
content 文章内容 文本
image 文章封面 文本
createtime 发表日期 日期
updatetime 修改日期 日期
ispublic 是否公开 文本 0:不公开1:公开
istop 是否置顶 文本 0:不置顶1:置顶
visits 浏览量 整型
thumbup 点赞数 整型
comment 评论数 整型
state 审核状态 文本 0:未审核 1:已审核
channelid 所属频道 整型 关联频道表ID
url URL 地址文本
type 文章类型 文本 0:分享1:专栏

文章审核

controller

1
2
3
4
5
6
7
8
/**
* 文章审核
*/
@PutMapping("examine/{articleId}")
public Result examine(@PathVariable("articleId") Integer articleId) {
articleService.examine(articleId);
return Result.ok("审核成功");
}

service

1
2
3
4
5
6
7
8
/**
* 文章审核
*
* @param articleId 文章ID
*/
public void examine(Integer articleId) {
articleDao.updateStateById(articleId);
}

dao

1
2
3
4
@Modifying
@Query("UPDATE Article a SET a.state = '1' " +
"WHERE a.id = ?1")
void updateStateById(Integer articleId);

文章点赞

controller

1
2
3
4
5
6
7
8
/**
* 文章点赞
*/
@PutMapping("thumbup/{articleId}")
public Result thumbup(@PathVariable("articleId") Integer articleId) {
articleService.thumbup(articleId);
return Result.ok("审核成功");
}

service

1
2
3
4
5
6
7
8
/**
* 文章点赞
*
* @param articleId 文章ID
*/
public void thumbup(Integer articleId) {
articleDao.updateThumbupById(articleId);
}

dao

1
2
3
4
@Modifying
@Query("UPDATE Article a SET a.thumbup = a.thumbup + 1 " +
"WHERE a.id = ?1")
void updateThumbupById(Integer articleId);

Spring Redis

使用Spring cache对部分数据进行缓存。

Docker安装Redis

任何安装复杂的东西只要和Docker联系起来,基本上可以说零操作!!!

下载Redis镜像

  1. 搜索Redis镜像

    1
    docker search redis
  2. 下载Redis镜像

    1
    docker pull redis
  3. 使用镜像生成Redis容器并运行

    1
    docker run -di --name=tensquare_redis -p 6379:6379 redis

Redis-GUI客户端

给大家提供一个Redis的界面工具 - RedisDesktopManager,我提供这个是Windows版本的,版本是4.0.0。这个工具最新的版本都是要收费的了,还不便宜。

👇百度云盘链接👇

链接:https://pan.baidu.com/s/1bx_a2jQANwPWloZ6-pdBYQ
提取码:csxg

文章微服务- 缓存处理

  1. 引入Spring Data Redis依赖

    1
    2
    3
    4
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
  2. application.yml中配置Redis主机位置

    1
    2
    3
    4
    5
    spring:   
    redis:
    host: 192.168.136.104
    # 如果redis端口保持默认的话,可以省略端口配置
    port: 6379
  3. 修改ArticleService#findById的逻辑

    先查询Redis是否已缓存,如果已缓存,取出缓存的数据直接返回,否则从数据库中查询并存入Redis,放入时需要设置有效时间为一天。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    @Autowired
    private RedisTemplate<String, Article> redisTemplate;

    private static final String redisKeyPrefix = "article_";

    /**
    * 根据ID查询实体
    * @param id
    * @return
    */
    public Article findById(String id) {
    String key = redisKeyPrefix + id;
    Article article = redisTemplate.opsForValue().get(key);
    if (article == null) {
    article = articleDao.findById(id).get();
    redisTemplate.opsForValue().set(key, article, 1, TimeUnit.DAYS);
    }

    return article;
    }
  4. 更新缓存

    修改、删除文章时,清除缓存。直接调用redisTemplate.delete(key)即可。

Spring Cache + Spring Redis

活动微服务

活动微服务CRUD代码生成(省略)

活动详情缓存

  1. 引入Spring Redis依赖

    1
    2
    3
    4
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
  2. application.yaml中配置Redis主机位置

    1
    2
    3
    4
    spring: 
    redis:
    host: 192.168.136.104
    port: 6379
  3. 开启Spring Cache注解扫描,修改GatheringApplication,在类上加上@EnableCaching即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    package com.tensquare.gathering;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import util.IdWorker;

    @EnableCaching
    @SpringBootApplication
    public class GatheringApplication {

    public static void main(String[] args) {
    SpringApplication.run(GatheringApplication.class, args);
    }

    @Bean
    public IdWorker idWorker(){
    return new IdWorker(1, 5);
    }

    }
  4. GatheringService#findById加入缓存注解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /**
    * 根据ID查询实体
    * @param id
    * @return
    */
    @Cacheable(value = "gathering", key = "#id")
    public Gathering findById(String id) {
    return gatheringDao.findById(id).get();
    }
  5. 删除和修改时,更新缓存

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /**
    * 修改
    * @param gathering
    */
    @CacheEvict(value = "gathering", key = "#id")
    public void update(Gathering gathering) {
    gatheringDao.save(gathering);
    }

    /**
    * 删除
    * @param id
    */
    @CacheEvict(value = "gathering", key = "#id")
    public void deleteById(String id) {
    gatheringDao.deleteById(id);
    }
文章作者: imxushuai
文章链接: https://www.imxushuai.com/2002/01/02/2.十次方后端笔记二:招聘、问答、文章和活动微服务/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 imxushuai
支付宝打赏
微信打赏