门户网站课程站点搭建,课程列表面包屑展示,课程列表检索,页面静态化原因和使用场景

    技术2022-07-13  86

    在父级项目下创建子模块(门户网站课程站点) hrm-website-course拷贝页面 live-server 启动

    面包屑数据查询

    前台判断搜索type还是keywrod

    如果是type就发请求根据typeId查询面包屑需要的数据结构:一个本身要展示的,还有一个集合,这个集合就是自己的同级(父级id一样)coursetype控制层写方法接收请求封装dto前台往后台传参数,封装vo后台往前台返回参数在course-common封装vo面包屑数据CrumbsVo自己 兄弟姐妹(courseType的数组) public class CrumbsVo { //自己当前的数据 private CourseType ownerProductType; //自己的兄弟姐妹们 private List<CourseType> otherProductTypes; public CourseType getOwnerProductType() { return ownerProductType; } public void setOwnerProductType(CourseType ownerProductType) { this.ownerProductType = ownerProductType; } public List<CourseType> getOtherProductTypes() { return otherProductTypes; } public void setOtherProductTypes(List<CourseType> otherProductTypes) { this.otherProductTypes = otherProductTypes; } @Override public String toString() { return "CrumbsVo{" + "ownerProductType=" + ownerProductType + ", otherProductTypes=" + otherProductTypes + '}'; } } service层查询面包屑1根据分类id查询当前分类2.获取当前分类的path(上一级的分类id)3切割path得到上级分类id3.1 去掉两边的“.”3.2 切割(注意".“在正则有特殊含义,要转义。4.查询出多个id对应的类型对象4.1 循环切割的数组,转成Long4.2 查询5.循环课程分类封装成一个CourseVo5.1循环类型对象,添加到CourseVo的自己6.为每一个分类寻找兄弟姐妹节点,设置到CourseVo的otherType6.1pid和自己的pid相等就是自己的兄弟姐妹。通过pid查询type6.2除去自己 -》使用迭代器循环排除id和自己相等的 使用for循环 一边循环一遍删会报异常6.3使用集合的remove方法(底层使用了equals比较,对象equals比较的是地址是有问题的) /** * * @param id * @return */ @Override public List<CrumbsVo> crumbs(Long id) { //通过id获取类型 CourseType courseType = baseMapper.selectById(id); //获取path String path = courseType.getPath(); //去掉两端的. path = path.startsWith(".") ? path.substring(1) : path; path = path.endsWith(".") ? path.substring(0, path.length() - 1) : path; //分割path //分割的path循环转成long String[] idStrs = path.split("\\."); List<Long> ids=new ArrayList<>(); for (String idStr : idStrs) { ids.add(Long.valueOf(idStr)); } List<CrumbsVo> crumbsVos=new ArrayList<>(); //查询这些数据 List<CourseType> courseTypes = baseMapper.selectBatchIds(ids); for (CourseType type : courseTypes) { CrumbsVo crumbsVo=new CrumbsVo(); crumbsVo.setOwnerProductType(type); //找兄弟们 有一样的pid那就是 List<CourseType> other=baseMapper.selectByPid(type.getPid()); //移除自己 other.remove(type); crumbsVo.setOtherProductTypes(other); crumbsVos.add(crumbsVo); } System.out.println(crumbsVos); return crumbsVos; } 6.4复写equals方法,只比较两个对象的id Long的eq的值响应没有数据,复制url去浏览器访问能访问说明后端没有错。排前端的错,数据交互出现问题,有可能是跨域问题。

    -门户网站 课程检索

    前台钩子方法里的search方法发起请求

    控制层处理请求 使用接收参数CourseQuery。

    添加前台传的参数到CourseQuery中,不然接收不到

    排序和排序方式大家公用可以将字段添加到baseQuery

    服务层调用feign查询课程

    ES控制层加上查询方法(和Course控制成一样,可以 直接调用ES控制处理前台请求,效率还高些)

    把CurseQuery的字段取出来作为es查询条件


    ESController代码具体实现思路
    首先构建本地查询器根据前台传过来的字段排序指定一个默认排序取出来判断是否为空使用switch判断前台传过来的是什么字段排序方式:获取前台传过来的排序方式字段,可以转成小写于desc去equals比较三目运算成立就SortOrder.DESC否则就是SortOrder.ASC然后分页注意:所有获取的参数都要判断合法性,下面就不在说了,记住判断获取分页参数,使用PageRequest.of(current,pageSize)来分页组合查询 构建一个组合查询器BoolQueryBuilder获取前台参数关键字搜索keywrod使用DSL查询 must获取前台参数价格最大值最小值使用DSL过滤查询(range范围查询)获取前台课程id通过课程id查询DSL过滤查询:课程分类(termQuery等值查询),使用本地器查询去查询然后返回结果(总条数和总数据) //课程搜索 @RequestMapping(value = "/search/coursedoc",method = RequestMethod.POST) public AjaxResult queryCourses(@RequestBody CourseQuery courseQuery) { //构建本地查询器 NativeSearchQueryBuilder nBuilder = new NativeSearchQueryBuilder(); //排序 String sortField = courseQuery.getSortField(); if(StringUtils.isNotBlank(sortField)){ String s="price"; switch (sortField){ case "xp":s="onlineTime"; case "pl":s="commentCount"; case "xl":s="saleCount"; } //排序方式 SortOrder sortOrder= SortOrder.DESC; String sortType = courseQuery.getSortType(); sortOrder =sortType.toLowerCase().equals("desc")?SortOrder.ASC:SortOrder.DESC; nBuilder.withSort(new FieldSortBuilder(s).order(sortOrder)); } //分页 nBuilder.withPageable(PageRequest.of(courseQuery.getPage()-1,courseQuery.getRows())); //组合查询 BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery(); //关键词搜索 在es中searchField搜索 if(StringUtils.isNotBlank(courseQuery.getKeyword())){ boolQueryBuilder.must(QueryBuilders.matchQuery("searchField",courseQuery.getKeyword())); } //价格查询 范围查询 if(courseQuery.getPriceMin()!=null){ boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(courseQuery.getPriceMin())); } if(courseQuery.getPriceMax()!=null){ boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(courseQuery.getPriceMax())); } //把组合查询交给本地查询 nBuilder.withQuery(boolQueryBuilder); //使用接口查询 Page<CourseDoc> search = courseElasticsearchRepository.search(nBuilder.build()); //返回数据 return AjaxResult.me().setResultObj(new PageList<>(search.getTotalPages(),search.getContent())); } feign接口添加ES的查询课程方法,这样服务层才可以调用 //elasticsearch搜索 @RequestMapping(value = "/es/search/coursedoc",method = RequestMethod.POST) public AjaxResult queryCourses(@RequestBody CourseQuery courseQuery); 然后写托低方法 @Override public AjaxResult queryCourses(CourseQuery courseQuery) { //打印异常信息 throwable.printStackTrace(); //打印日志 logger.error("ElasticSearch服务不可用[search]"); return AjaxResult.me().setSuccess(false).setMessage("ElasticSearch服务不可用[search]"); } 前端显示图片: 拷贝属性时拼接fastdfs在配置文件读取,在yml配置fastdfsUrl:@Value("${fastdfsUrl}")取值

    页面静态化

    页面静态化:首页并发高,每次访问都要请求后台从mysql重新查询数据,然后合并数据渲染页面,很消耗服务器性能,高并发的时候页面反应慢,用户体验极差。

    页面内容不经常改变,性能低。使用redis缓存,或者使用页面静态化(首页,详情页)什么是页面静态化使用模板引擎(freemarker)把页面生成html,访问时直接返回html’,不需要重新查询数据渲染视图,将页面需要的数据和模板进行合成,生成一个html.原理就是:分布式页面静态化实现
    Processed: 0.016, SQL: 9