1. 程式人生 > 其它 >HM-SpringCloud微服務系列6.4【黑馬旅遊案例】

HM-SpringCloud微服務系列6.4【黑馬旅遊案例】



1 酒店搜尋和分頁

1.1 課件




1.2 需求分析

  1. 在專案的首頁,有一個大大的搜尋框,還有分頁按鈕
    點選搜尋按鈕,可以看到瀏覽器控制檯發出了請求:

    請求引數如下:
  2. 由此可以知道,我們這個請求的資訊如下:
    • 請求方式:POST
    • 請求路徑:/hotel/list
    • 請求引數:JSON物件,包含4個欄位:
      • key:搜尋關鍵字
      • page:頁碼
      • size:每頁大小
      • sortBy:排序,目前暫不實現
    • 返回值:分頁查詢,需要返回分頁結果PageResult,包含兩個屬性:
      • total:總條數
      • List<HotelDoc>:當前頁的資料
  3. 因此,我們實現業務的流程如下:
    • 步驟一:定義實體類,接收請求引數的JSON物件
    • 步驟二:編寫controller,接收頁面的請求
    • 步驟三:編寫業務實現,利用RestHighLevelClient實現搜尋、分頁

1.3 定義實體類

實體類有兩個,一個是前端的請求引數實體,一個是服務端應該返回的響應結果實體。

1.3.1 請求引數

  1. 前端請求的json結構如下:
    {
    	"key": "搜尋關鍵字",
    	"page": 1,
    	"size": 3,
    	"sortBy": "default"
    }
    
  2. 因此,我們在com.yppah.hoteldemo.pojo包下定義一個實體類:
    package com.yppah.hoteldemo.pojo;
    
    import lombok.Data;
    
    @Data
    public class RequestParams {
    	private String key;
    	private Integer page;
    	private Integer size;
    	private String sortBy;
    }
    

1.3.2 返回值

  1. 分頁查詢,需要返回分頁結果PageResult,包含兩個屬性:
    • total:總條數
    • List<HotelDoc>:當前頁的資料
  2. 因此,我們在com.yppah.hoteldemo.pojo中定義返回結果:
    package com.yppah.hoteldemo.pojo;
    
    import lombok.Data;
    
    import java.util.List;
    
    @Data
    public class PageResult {
    	private Long total;
    	private List<HotelDoc> hotels;
    }
    

1.4 定義Controller

  1. 定義一個HotelController,宣告查詢介面,滿足下列要求:

    • 請求方式:Post
    • 請求路徑:/hotel/list
    • 請求引數:物件,型別為RequestParam
    • 返回值:PageResult,包含兩個屬性
      • Long total:總條數
      • List<HotelDoc> hotels:酒店資料
  2. 因此,我們在com.yppah.hoteldemo.web中定義HotelController:

    點選檢視程式碼
    package com.yppah.hoteldemo.web;
    
    import com.yppah.hoteldemo.pojo.PageResult;
    import com.yppah.hoteldemo.pojo.RequestParams;
    import com.yppah.hoteldemo.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;
    
    @RestController
    @RequestMapping("/hotel")
    public class HotelController {
    
    	@Autowired
    	private IHotelService hotelService;
    
    	@PostMapping("/list")
    	public PageResult search(@RequestBody RequestParams params) {
    		return hotelService.search(params);
    	}
    }
    

1.5 實現搜尋業務

  1. 我們在controller呼叫了IHotelService,並沒有實現該方法,因此下面我們就在IHotelService中定義方法,並且去實現業務邏輯。

  2. com.yppah.hoteldemo.service中的IHotelService介面中定義一個方法:

    點選檢視程式碼
    package com.yppah.hoteldemo.service;
    
    import com.yppah.hoteldemo.pojo.Hotel;
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.yppah.hoteldemo.pojo.PageResult;
    import com.yppah.hoteldemo.pojo.RequestParams;
    
    public interface IHotelService extends IService<Hotel> {
    
    	/**
    	 * 根據關鍵字搜尋酒店資訊
    	 * @param params 請求引數物件,包含使用者輸入的關鍵字
    	 * @return 酒店文件列表
    	 */
    	PageResult search(RequestParams params);
    }
    
  3. com.yppah.hoteldemo.service.impl中的HotelService中實現search方法:

    點選檢視程式碼
    package com.yppah.hoteldemo.service.impl;
    
    import com.alibaba.fastjson.JSON;
    import com.yppah.hoteldemo.mapper.HotelMapper;
    import com.yppah.hoteldemo.pojo.Hotel;
    import com.yppah.hoteldemo.pojo.HotelDoc;
    import com.yppah.hoteldemo.pojo.PageResult;
    import com.yppah.hoteldemo.pojo.RequestParams;
    import com.yppah.hoteldemo.service.IHotelService;
    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.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    @Service
    public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
    
    	@Autowired
    	private RestHighLevelClient client; // 使用之前需要在專案啟動類HoteldemoApplication中用@Bean將其注入到spring中
    
    	@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 查詢結果分頁處理
    			int page = params.getPage(); // 自動拆箱
    			int size = params.getSize();
    			request.source().from((page-1)*size).size(size);
    			// 3. 傳送Request,得到Response
    			SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    			// 4. 解析Response
    			return handleResponse(response);
    		} catch (IOException e) {
    			throw new RuntimeException(e);
    		}
    	}
    
    	private PageResult handleResponse(SearchResponse response) { // 需要在PageResult中新增建構函式兩個
    		//4 解析響應
    		SearchHits searchHits = response.getHits();
    		//4.1 獲取總條數
    		long total = searchHits.getTotalHits().value;
    		//4.2 獲取文件陣列
    		SearchHit[] hits = searchHits.getHits();
    		//4.3 遍歷陣列
    		List<HotelDoc> hotels = new ArrayList<>(); //用於存放PageResult所要求格式的資料
    		for (SearchHit hit : hits) {
    			//4.3.1 獲取文件source
    			String json = hit.getSourceAsString();
    			//4.3.2 反序列化解析json
    			HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
    			hotels.add(hotelDoc);
    		}
    		//4.4 封裝返回
    		return new PageResult(total, hotels);
    	}
    }
    
  4. 實現搜尋業務,肯定離不開RestHighLevelClient,我們需要把它註冊到Spring中作為一個Bean。在com.yppah.hoteldemo中的HotelDemoApplication中宣告這個Bean:

    	@Bean
    	public RestHighLevelClient client() {
    		return new RestHighLevelClient(RestClient.builder(
    				HttpHost.create("http://10.193.193.141:9200")
    		));
    	}
    


1.6 測試



2 酒店結果過濾

2.1 課件



3 我周邊的酒店

3.1 課件



4 酒店競價排名

4.1 課件