Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch

释放双眼,带上耳机,听听看~!

今日任务
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch

课程的CRUD

关于数据库的存储

有两种方案
方案一:
像课程详情 课程图片 都是数据课程的信息 可知直接放入t_course 就ok
方案二:

有时候我们只需要查询到课程的基本信息 不需要显示图片和详情 这个时候我们就会用到垂直分表

垂直分表:一些字段我们一般不需要直接查询 就把这些字段单独放一个表 通过外键关联 正常情况下 不需要查询关联表 如果需要 就通过外键查询就ok 这样能大大提高数据库的效率

生成代码

生成后测试是否已经加入

Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
然后从我们的资料中拷贝Course.vue界面
在这之前 我们需要集成一个支持Vue的富文本编辑器
直接在终端运行
npm install quill –save
npm install –save vue-quill-editor

然后把list一系列的修改了 和之前一样
然后启动前后端服务

然后可能会报一个这样的错
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
别担心 这是因为你的redis没有启动起来 将redis启动就行了

这与页面就能出来了

接下来我们来做新增操作
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch

页面都已经写好 我们只需要拷贝下来用就是了 因为我不是专业的前端 所以我们就直接用别人写好的就行了

后台:
我们需要修改的地方是 覆写service中的插入和修改方法 因为我们这个是有关联对象的 所以自带的方法已经满足不了我们了


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1@Override
2public boolean insert(Course entity) {
3    //要添加三张表 课程表 详情表 市场信心表
4    //tenantId tenantName userId userName
5    System.out.println(entity);
6    entity.setStatus(0);
7    courseMapper.insert(entity);
8    Long courseId = entity.getId();
9    //同时保存详情和市场信心
10    CourseDetail courseDetail = entity.getCourseDetail();
11    courseDetail.setCourseId(courseId);
12    courseDetailMapper.insert(courseDetail);
13    CourseMarket courseMarket = entity.getCourseMarket();
14    courseMarket.setCourseId(courseId);
15    courseMarketMapper.insert(courseMarket);
16    return true;
17}
18
19

对于Controller 在我么登录之后 需要传递一些信息进去 但是我们现在还用不到 所以就先注释掉


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1@PutMapping
2public AjaxResult addOrUpdate(@RequestBody Course course){
3    try {
4        // @TODO 以后登录成功都能获取,现在使用holder来模拟
5        //登录成功后设置到UserInfoHolder,以后所有模块要使用都直接使用UserInfoHolder
6//            course.setTenantId(UserInfoHolder.getTenant().getId());
7//            course.setTenantName(UserInfoHolder.getTenant().getCompanyName());
8//            course.setUserId(UserInfoHolder.getLoginUser().getId());
9//            course.setUserName(UserInfoHolder.getLoginUser().getUsername());
10        if(course.getId()!=null){
11            courseService.updateById(course);
12        }else{
13            courseService.insert(course);
14        }
15
16        return AjaxResult.me();
17    } catch (Exception e) {
18        e.printStackTrace();
19        return AjaxResult.me().setMessage("保存对象失败!"+e.getMessage());
20    }
21}
22
23

修改和删除我就不在这展示了 和之前的都大同小异


课程的上线和下线

业务说明

上线:
现实生活中:
当培训机构研发出新的课程后,准备招生时,要先把它添加到数据中。但是期望暂时不需要用户能够搜索到。所以需要上线才能操作
系统中:
在系统中,我们添加了一个课程,用户不立即解就搜索到,需要上线以后才行.
下线:
当某个课程不想卖的时候,就要下线. 当课程下线后,用户不能搜索到,但是数据库是还有的.

方案-用es查询代替数据库查询

上线后,修改状态为”上线”,前台用户搜索时只能搜索到上线状态的.如果不想卖了,执行下线时,修改状态下线就ok.———-垃圾(每次都要操作数据库.)

如果有1000W的并发来查询课程,要高并发访问数据库,效率低下


上线时把课程数据
同步到es,用户查询直接从es查询.也就意味着没有上线的课程用户查询不到,因为没有放到es库.
下线时把es库课程数据删除掉. 用户就查询不到了. —NB(以基于索引搜索代替数据库查询)

好处:
降低数据库压力

提高了查询速度,增强用户体验-基于索引搜索,效率远远数据库搜索


ES java操作

准备es环境

Es服务端

方案选择

  1. 原生ESTransport Client方式 —> 就相当于写jdbc代码,非常麻烦.
  2. Springboot spring data es

spring data
是spring对数据访问抽象.这些数据可以放入db,index,nosql等包含以下:
spring data jpa spring对关系型数据库访问支持
spring data ES spring对es数据访问支持
spring data redis等 spring对redis数据访问支持
spring data …

Springboot spring data es —>对 spring data es简化了配置

安装和使用

如果你是第一次安装
elasticsearch 需要修改一下配置

Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
这里面的所需的运存改为1g 当然 你电脑如果运存的大的话也可以不换
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
然后是启动 双击这个文件夹就行
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
直接就启动了
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
他有两个端口 一个是9200 一个是9300 9300是代码访问的客户端 9200是http的
然后再浏览器中访问
http://localhost:9200/
如果能看到这个界面 就说明是成功了
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
接下来我们使用kibana来访问她 首先要启动kibana的服务

首先修改一下配置 指定端口
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch

然后启动(
尽量使用管理员权限启动)Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
启动成功后
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
我们在浏览器中访问
http://localhost:5601/

Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch

我们用的最多的是
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
其他的喜欢研究的可以自己去研究一下

课程上下线实现

技术架构

Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch

管理员:(千级)
添加:直接操作数据库
删除和修改: 同步操作方案
分页查询:直接操作数据.并发量小.
上线:同步信息到ES库.
下线:删除ES库数据
用户:(千万级)
搜索课程:直接从ES

实现

写的服务不具备通用性,没必要单独搞一个服务

关于数据库的设计

需要值得注意的是 :这里我们的数据库采用的是反3NF的设计

Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch

准备环境 -在自己模块

导包


1
2
3
4
5
6
7
1<!--springboot 对spring data es支持-->
2<dependency>
3    <groupId>org.springframework.boot</groupId>
4    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
5</dependency>
6
7

配置文件


1
2
3
4
5
6
7
1spring:
2  data:
3    elasticsearch:
4      cluster-name: elasticsearch
5      cluster-nodes: 127.0.0.1:9300 #9200是图形界面端,9300代码端
6
7

入口类


1
2
3
4
5
6
7
8
1@SpringBootApplication
2public class ESApplication {
3    public static void main(String[] args) {
4        SpringApplication.run(ESApplication.class);
5    }
6}
7
8

EsCourse.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
1//包含了前台展示的字段和要添加到索引库都要写到这儿
2@Document(indexName = "hrm",type = "course")
3public class EsCourse {
4    @Id
5    private Long id;
6    private String name;
7    private String users;
8    private Long courseTypeId;
9    private String courseTypeName;
10    private Long gradeId;
11    private String gradeName;
12    private Integer status;
13    private Long tenantId;
14    private String tenantName;
15    private Long userId;
16    private String userName;
17    private Date startTime;
18    private Date endTime;
19    private String intro;
20    private String resources; //图片
21    private Date expires; //过期时间
22    private BigDecimal priceOld; //原价
23    private BigDecimal price; //原价
24    private String qq; //原价
25
26    @Field(type = FieldType.Text,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
27    private String all;
28
29  //getter和setter
30
31  //toString
32
33public String getAll() {
34        String tmp =  name
35        +" "+ users
36        +" "+ courseTypeName
37        +" "+ gradeName
38        +" "+ tenantName
39        +" "+ userName
40        +" "+ intro;
41        return tmp;
42    }
43
44

EsCourseRepository.java


1
2
3
4
5
6
7
8
1import org.leryoo.index.doc.EsCourse;
2import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
3
4//在service通过注入它就可以完成索引库操作了
5public interface EsCourseRepository extends ElasticsearchRepository<EsCourse,Long> {
6}
7
8

接下来什么地方要用到就直接调用就行了 和操作数据库的方法都差不多


Service层 业务逻辑
上线


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
1@Override
2public AjaxResult onLine(Long[] ids) {
3    try
4    {
5        //1添加索引库
6        // 通过id查询数据库里面课程
7        List<Course> courses = courseMapper
8                .selectBatchIds(Arrays.asList(ids));
9        //转换为doc
10        List<EsCourse> esCourses = courses2EsCourses(courses);
11        //批量添加就ok
12        repository.saveAll(esCourses);
13        //2 修改数据库状态和上线时间 - ids,time
14        Map<String,Object> params = new HashMap<>();
15        params.put("ids",ids);
16        params.put("onLineTime",new Date());
17        // 修改状态和上线时间
18        //update t_couse set status=1 and start_time={} where id in (1,2,3,4)
19        courseMapper.onLine(params);
20        return AjaxResult.me();
21    }catch (Exception e){
22        e.printStackTrace();
23        return AjaxResult.me().setSuccess(false).setMessage("上线失败!"+e.getMessage());
24    }
25
26}
27
28
29private List<EsCourse> courses2EsCourses(List<Course> courses) {
30    //1 声明要返回
31    List<EsCourse> result = new ArrayList<>();
32    //2 转换
33    for (Course course : courses) {
34        result.add(course2EsCourse(course));
35    }
36    //3返回
37    return  result;
38}
39
40
41
42//把一个course转换为EsCourse
43private EsCourse course2EsCourse(Course course) {
44    //1 声明要返回
45    EsCourse result = new EsCourse();
46    //  2 转换
47    result.setId(course.getId());
48    result.setName(course.getName());
49    result.setUsers(course.getUsers());
50    result.setCourseTypeId(course.getCourseTypeId());
51    //type-同库-没有做关联查询
52    if (course.getCourseType() != null)
53        result.setCourseTypeName(course.getCourseType().getName());
54    result.setGradeId(course.getGrade());
55    result.setGradeName(course.getGradeName());
56    result.setStatus(course.getStatus());
57    result.setTenantId(course.getTenantId());
58    result.setTenantName(course.getTenantName());
59    result.setUserId(course.getUserId());
60    result.setUserName(course.getUserName());
61    result.setStartTime(course.getStartTime());
62    result.setEndTime(course.getEndTime());
63    //Detail
64    result.setIntro(null);
65    //resource
66    result.setResources(null);
67    //market
68    result.setExpires(null);
69    result.setPrice(null);
70    result.setPriceOld(null);
71    result.setQq(null);
72    //   3返回
73    return result;
74}
75
76

下线:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1@Override
2public AjaxResult offLine(Long[] ids) {
3    try
4    {
5        //1 删除索引库里面的内容
6        //        List<Course> courses = courseMapper
7        //                .selectBatchIds(Arrays.asList(ids));
8        //转换为doc
9        //        List<EsCourse> esCourses = courses2EsCourses(courses);
10        //        repository.deleteAll(esCourses);
11        for (Long id : ids) {
12            repository.deleteById(id);
13        }
14        //2 修改数据库状态 status=0 end_time
15        Map<String,Object> params = new HashMap<>();
16        params.put("ids",ids);
17        params.put("offLineTime",new Date());
18        // 修改状态和下线时间
19        //update t_couse set status=0 and start_time={} where id in (1,2,3,4)
20        courseMapper.offLine(params);
21        return AjaxResult.me();
22    }catch (Exception e){
23        e.printStackTrace();
24        return AjaxResult.me().setSuccess(false).setMessage("下线失败!"+e.getMessage());
25    }
26
27}
28
29

SQL语句


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1<!--    上线-->
2<!--    void onLine(Map<String, Object> params);-->
3<update id="onLine" parameterType="map">
4    update t_course set status=1,start_time=#{onLineTime} where id in
5    <foreach collection="ids" separator="," open="(" close=")" item="id">
6        #{id}
7    </foreach>
8</update>
9
10
11<!--    void offLine(Map<String, Object> params);-->
12<update id="offLine" parameterType="map">
13    update t_course set status=0 , end_time=#{offLineTime} where id in
14    <foreach collection="ids" separator="," open="(" close=")" item="id">
15        #{id}
16    </foreach>
17</update>
18
19

注意前端传参
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
和封装参数
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
和选中行时往sels里面传值
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
需要注意的是 传值的时候 Controller层需要加上

Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
然后编写SQL语句的时候
Springcloud微服务项目——人力资源管理(HRM)Day06 ElasticSearch
这里直接写参数
自此 课程模块就已经写完了

今天的内容就到这啦

给TA打赏
共{{data.count}}人
人已打赏
安全网络

CDN安全市场到2022年价值76.3亿美元

2018-2-1 18:02:50

安全运维

Linux(内核剖析):02---Linux内核源码下载并编译Linux内核、内核开发的特点

2021-8-18 16:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索