微服务框架
【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】
SpringCloud微服务架构
文章目录
- 微服务框架
 - SpringCloud微服务架构
 - 25 黑马旅游案例
 - 25.1 搜索、分页
 - 25.1.1 直接开干
 
25 黑马旅游案例
25.1 搜索、分页
25.1.1 直接开干
案例1:实现黑马旅游的酒店搜索功能,完成关键字搜索和分页
我们课前提供的hotel-demo项目中,自带了前端页面,启动后可以看到:

妙啊
先实现其中的关键字搜索功能,实现步骤如下:
-  
定义实体类,接收前端请求
 -  
定义controller接口,接收页面请求,调用IHotelService的search方法
 -  
定义IHotelService中的search方法,利用match查询实现根据关键字搜索酒店信息
 

启动服务

OK, 成功运行,8089 端口直接访问

我超,但是我的数据库里面只有201 条,这应该是写死的假数据了【嗯】
看看网络请求

- key:搜索关键字
 - page:页码
 - size:每页大小
 - sortBy:靠什么排序【排序字段】
 
步骤1:定义类,接收前端请求参数
package cn.itcast.hotel.pojo;
import lombok.Data;
/**
 * ClassName: RequestParams
 * date: 2022/11/2 11:03
 *
 * @author DingJiaxiong
 */
@Data
public class RequestParams {
    private String key;
    private Integer page;
    private Integer size;
    private String sortBy;
}
 

OK, 请求参数实体类
步骤2:定义controller接口,接收前端请求
定义一个HotelController,声明查询接口,满足下列要求:
- 请求方式:Post
 - 请求路径:/hotel/list
 - 请求参数:对象,类型为RequestParam
 - 返回值:PageResult,包含两个属性 
  
- ①Long total:总条数
 - ②List<HotelDoc> hotels:酒店数据
 
 
先来一个返回结果的实体类
package cn.itcast.hotel.pojo;
import lombok.Data;
import java.util.List;
/**
 * ClassName: PageResult
 * date: 2022/11/2 11:06
 *
 * @author DingJiaxiong
 */
@Data
public class PageResult {
    private Long total;
    private List<HotelDoc> hotels;
    public PageResult() {
    }
    public PageResult(Long total, List<HotelDoc> hotels) {
        this.total = total;
        this.hotels = hotels;
    }
}
 

OK
定义controller
package cn.itcast.hotel.web;
import cn.itcast.hotel.pojo.PageResult;
import cn.itcast.hotel.pojo.RequestParams;
import cn.itcast.hotel.service.IHotelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * ClassName: HotelController
 * date: 2022/11/2 11:07
 *
 * @author DingJiaxiong
 */
@RestController
@RequestMapping("/hotel")
public class HotelController {
    @Autowired
    private IHotelService hotelService;
    @PostMapping("/list")
    public PageResult search(@RequestBody RequestParams params){
        return hotelService.search(params);
    }
}
 
修改服务接口
package cn.itcast.hotel.service;
import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.PageResult;
import cn.itcast.hotel.pojo.RequestParams;
import com.baomidou.mybatisplus.extension.service.IService;
public interface IHotelService extends IService<Hotel> {
    PageResult search(RequestParams params);
}
 
注入client
package cn.itcast.hotel;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@MapperScan("cn.itcast.hotel.mapper")
@SpringBootApplication
public class HotelDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(HotelDemoApplication.class, args);
    }
    @Bean
    public RestHighLevelClient client() {
        return new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://118.195.248.48:9200")
        ));
    }
}
 

修改业务实现类
package cn.itcast.hotel.service.impl;
import cn.itcast.hotel.mapper.HotelMapper;
import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.pojo.PageResult;
import cn.itcast.hotel.pojo.RequestParams;
import cn.itcast.hotel.service.IHotelService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PBEParameterSpec;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
    @Autowired
    private RestHighLevelClient client;
    @Override
    public PageResult search(RequestParams params) {
        try {
            //1. 准备Request
            SearchRequest request = new SearchRequest("hotel");
            //2. 准备DSL
            //2.1 关键字搜索query
            String key = params.getKey();
            //健壮判断
            if (key == null || "".equals(key)) {
                request.source().query(QueryBuilders.matchAllQuery());
            } else {
                request.source().query(QueryBuilders.matchQuery("all", key));
            }
            //2.2 分页
            Integer page = params.getPage();
            Integer size = params.getSize();
            request.source().from((page - 1) * size).size(size);
            //3. 发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            //4. 解析响应
            return handleResponse(response);
        }catch (IOException e){
            throw new RuntimeException(e);
        }
    }
    private PageResult handleResponse(SearchResponse response) {
        //4. 解析响应
        SearchHits searchHits = response.getHits();
        //4.1 获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        //4.2 文档数组
        SearchHit[] hits = searchHits.getHits();
        //4.3 遍历
        List<HotelDoc> hotels = new ArrayList<>();
        for (SearchHit hit : hits) {
            //获取文档source
            String json = hit.getSourceAsString();
            //反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            hotels.add(hotelDoc);
        }
        //4.4 封装返回
        return new PageResult(total, hotels);
    }
}
 
OK, 重启服务进行测试

OK, 我数据库里面确实只有201 条数据

试试分页

OK, 没问题
搜索“如家”

没毛病
查看控制台
发起的请求参数:

响应结果

没毛病

![[附源码]Python计算机毕业设计SSM基于云数据库的便民民宿租赁系统(程序+LW)](https://img-blog.csdnimg.cn/51cf7cd162fb44a2956d3d4025c8695c.png)
















![[附源码]计算机毕业设计JAVA中小企业人事管理系统](https://img-blog.csdnimg.cn/8a97c84c88684ba5b41554b79950a139.png)