• SpringBoot--中间件技术-3:整合mongodb,整合ElasticSearch,附案例含代码(简单易懂)


    SpringBoot整合mongodb

    实现步骤:

    1. pom文件导坐标

      
      <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-data-mongodbartifactId>
      dependency>
      <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
      dependency>
      <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
      dependency>
      <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-testartifactId>
        <scope>testscope>
      dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
    2. yaml配置文件配置mongodb:

      spring:
        data:
          mongodb:
            uri: mongodb://localhost/spring
      
      • 1
      • 2
      • 3
      • 4
    3. 随便建一个pojo

      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      public class Book {
          private int id;
          private String name;
          private String type;
          private String description;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    4. 测试:

      @SpringBootTest
      class SpringbootMongodb01ApplicationTests {
      
        @Autowired(required = false)
        private MongoTemplate mongoTemplate;
      
        @Test
        void contextLoads() {
          Book book = new Book();
          book.setId(4);
          book.setName("张三");
          book.setType("牛逼");
          book.setDescription("真牛逼");
          mongoTemplate.save(book);
        }
      
        @Test
        void find(){
          List<Book> all = mongoTemplate.findAll(Book.class);
          System.out.println(all);
        }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22

      装配MongoTemplate模板类,调用方法

    整合MongoDB总结:

    1. 导坐标
    2. 写配置文件
    3. 核心类MongoTemplate调用

    SpringBoot整合ElasticSearch

    前提准备:数据库+ES

    数据库建表语句:

    DROP TABLE IF EXISTS `tb_hotel`;
    CREATE TABLE `tb_hotel`  (
      `id` bigint(20) NOT NULL COMMENT '酒店id',
      `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店名称',
      `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店地址',
      `price` int(10) NOT NULL COMMENT '酒店价格',
      `score` int(2) NOT NULL COMMENT '酒店评分',
      `brand` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店品牌',
      `city` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '所在城市',
      `star_name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '酒店星级,1星到5星,1钻到5钻',
      `business` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商圈',
      `latitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '纬度',
      `longitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '经度',
      `pic` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '酒店图片',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    实现步骤:

    1. pom文件到坐标

      <properties>
        
        <java.version>1.8java.version>
        
        <elasticsearch.version>7.12.0elasticsearch.version>
      properties>
      
      <dependencies>
        <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-webartifactId>
        dependency>
      
        <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-testartifactId>
          <scope>testscope>
        dependency>
      
        <dependency>
          <groupId>org.elasticsearch.clientgroupId>
          <artifactId>elasticsearch-rest-high-level-clientartifactId>
        dependency>
      
        <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
          <groupId>com.baomidougroupId>
          <artifactId>mybatis-plus-boot-starterartifactId>
          <version>3.4.2version>
        dependency>
        <dependency>
          <groupId>mysqlgroupId>
          <artifactId>mysql-connector-javaartifactId>
          <version>8.0.29version>
        dependency>
        <dependency>
          <groupId>org.projectlombokgroupId>
          <artifactId>lombokartifactId>
          <optional>trueoptional>
        dependency>
        <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-testartifactId>
        dependency>
        
        <dependency>
          <groupId>com.alibabagroupId>
          <artifactId>fastjsonartifactId>
          <version>1.2.71version>
        dependency>
      dependencies>
      
      • 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
    2. yaml配置文件

      spring:
        datasource:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/spring?serverTimezone=GMT
          username: root
          password: 123456
      logging:
        level:
          com.dong: debug
      mybatis-plus:
        configuration:
          map-underscore-to-camel-case: true
        type-aliases-package: com.dong.pojo
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    3. 创建实体类:

      对应数据库表的实体类

      @NoArgsConstructor
      @AllArgsConstructor
      @Data
      @TableName("tb_hotel")
      public class Hotel {
        @TableId(type = IdType.INPUT)
        private Long id;
        private String name;
        private String address;
        private Integer price;
        private Integer score;
        private String brand;
        private String city;
        private String starName;
        private String business;
        private String longitude;//经度
        private String latitude;//纬度
        private String pic;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19

      对应ES的实体类

      @Data
      @NoArgsConstructor
      public class HotelDoc {
        private Long id;
        private String name;
        private String address;
        private Integer price;
        private Integer score;
        private String brand;
        private String city;
        private String starName;
        private String business;
        private String location;
        private String pic;
      // 构造方法用于类型转换   将数据库中的经、纬度用坐标location代替,所以HotelDoc稍有不同
        public HotelDoc(Hotel hotel){   
          this.id = hotel.getId();
          this.name = hotel.getName();
          this.address = hotel.getAddress();
          this.price = hotel.getPrice();
          this.score = hotel.getScore();
          this.brand = hotel.getBrand();
          this.city = hotel.getCity();
          this.starName = hotel.getStarName();
          this.business = hotel.getBusiness();
          this.location = hotel.getLatitude() + ", "+ hotel.getLongitude();
          this.pic = hotel.getPic();
        }
      }
      
      • 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
    4. mapper层:

      @Mapper
      public interface HotelMapper extends BaseMapper<Hotel> {
      }
      
      • 1
      • 2
      • 3
    5. service层:

      接口:

      public interface IHotelService extends IService<Hotel> {
      }
      
      • 1
      • 2

      实现类:

      @Service
      public class HotelServiceImp extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
      }
      
      • 1
      • 2
      • 3
    6. 演示在juint中进行,演示对索引库和文档的操作

    索引库的操作

    • 判断索引库是否存在(其实就是查询)
    • 创建索引库
    • 删除索引库
    @SpringBootTest
    class SpringbootEs01ApplicationTests {
    	// 操作es的核心对象
      private RestHighLevelClient client;
    	// 单元测试之前都执行的,告诉核心对象es的端口号  固定语法
      @BeforeEach
      void setUp(){
        this.client = new RestHighLevelClient(RestClient.builder(
          HttpHost.create("http://localhost:9200")
        ));
      }
    	// 单元测试之后都执行的
      @AfterEach
      void tearDown() throws Exception{
        this.client.close();
      }
    
      // 判断索引库是否存在
      @Test
      void testExistsHotelIndex() throws Exception {
        GetIndexRequest request = new GetIndexRequest("hotels");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.err.println(exists ? "索引库已经存在":"索引库不存在");
      }
    
      // 创建索引库
      @Test
      void createHotelIndex() throws Exception{
        // 创建Request对象
        CreateIndexRequest request = new CreateIndexRequest("hotels");
        // 准备请求的参数:DSL语句
        request.source(HotelConstants.MAPPING_TEMPLATE, XContentType.JSON);
        // 发送请求
        client.indices().create(request,RequestOptions.DEFAULT);
      }
    
      // 删除索引库
      @Test
      void delteHotelIndex() throws Exception{
        // 创建Request对象
        DeleteIndexRequest request = new DeleteIndexRequest("hotels");
        // 发送请求
        client.indices().delete(request,RequestOptions.DEFAULT);
      }
    }
    
    • 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

    创建索引库的时候需要映射,映射往往是一个复杂且长的JSON,所以单独写个类,上面创建索引库的映射如下

    可以在postman中写好粘贴过来

    public class HotelConstants {
      public static final String MAPPING_TEMPLATE = "{\n" +
        "  \"mappings\": {\n" +
        "    \"properties\": {\n" +
        "      \"id\": {\n" +
        "        \"type\": \"keyword\"\n" +
        "      },\n" +
        "      \"name\":{\n" +
        "        \"type\": \"text\",\n" +
        "        \"analyzer\": \"ik_max_word\",\n" +
        "        \"copy_to\": \"all\"\n" +
        "      },\n" +
        "      \"address\":{\n" +
        "        \"type\": \"keyword\",\n" +
        "        \"index\": false\n" +
        "      },\n" +
        "      \"price\":{\n" +
        "        \"type\": \"integer\"\n" +
        "      },\n" +
        "      \"score\":{\n" +
        "        \"type\": \"integer\"\n" +
        "      },\n" +
        "      \"brand\":{\n" +
        "        \"type\": \"keyword\",\n" +
        "        \"copy_to\": \"all\"\n" +
        "      },\n" +
        "      \"city\":{\n" +
        "        \"type\": \"keyword\",\n" +
        "        \"copy_to\": \"all\"\n" +
        "      },\n" +
        "      \"starName\":{\n" +
        "        \"type\": \"keyword\"\n" +
        "      },\n" +
        "      \"business\":{\n" +
        "        \"type\": \"keyword\"\n" +
        "      },\n" +
        "      \"location\":{\n" +
        "        \"type\": \"geo_point\"\n" +
        "      },\n" +
        "      \"pic\":{\n" +
        "        \"type\": \"keyword\",\n" +
        "        \"index\": false\n" +
        "      },\n" +
        "      \"all\":{\n" +
        "        \"type\": \"text\",\n" +
        "        \"analyzer\": \"ik_max_word\"\n" +
        "      }\n" +
        "    }\n" +
        "  }\n" +
        "}";
    }
    
    • 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

    文档的操作

    @SpringBootTest
    public class HotelDocumentTests {
      // 核心对象
      private RestHighLevelClient client;
    
      // 需要从数据库中查数据存入es,装配业务
      @Autowired(required = false)
      private IHotelService service;
    
      @BeforeEach
      void setUp(){
        this.client = new RestHighLevelClient(RestClient.builder(
          HttpHost.create("http://localhost:9200")
        ));
      }
    
      @AfterEach
      void tearDown() throws  Exception{
        this.client.close();
      }
    
      // 从数据库新增一条数据到es
      @Test
      void addDocument() throws Exception{
        // 从数据库查询一条数据
        Hotel hotel = service.getById(395434);
        System.out.println(hotel);
        // 转换为文档类型
        HotelDoc hotelDoc = new HotelDoc(hotel);
        // 将文档类型转为JSON格式
        String json = JSON.toJSONString(hotelDoc);
        // 准备request请求对象
        IndexRequest request = new IndexRequest("hotels").id(hotelDoc.getId().toString());
        // 准备JSON文档
        request.source(json, XContentType.JSON);
        // 发送请求
        client.index(request, RequestOptions.DEFAULT);
      }
    
      // 从es中删除一条数据
      @Test
      void deleteDocument() throws Exception{
        // 准备删除请求Request
        DeleteRequest request = new DeleteRequest("hotels", "395434");
        // 发送请求
        client.delete(request,RequestOptions.DEFAULT);
      }
    
      // 修改es中的数据
      @Test
      void updateDocument() throws  Exception{
        // 准备修改请求UpdateRequest
        UpdateRequest request = new UpdateRequest("hotels", "395434");
        // 准备请求参数(要修改的数据内容)
        request.doc(
          "name","W酒店",
          "city","西安",
          "price","2000",
          "starName","五星级"
        );
        // 发送请求
        client.update(request, RequestOptions.DEFAULT);
      }
    
      // 从es中查询一条数据
      @Test
      void getDocumentById() throws  Exception{
        // 准备查询请求GetRequest
        GetRequest getRequest = new GetRequest("hotels", "395434");
        // 发送请求,得到响应
        GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
        // 解析响应结果
        String json = response.getSourceAsString();
        HotelDoc hotelDoc = JSON.parseObject(json,HotelDoc.class);
        System.out.println(hotelDoc);
      }
    
      // 批量新增数据到es
      @Test
      void addAllDocument() throws  Exception{
        // 数据库全查
        List<Hotel> hotels = service.list();
        // 准备请求
        BulkRequest bulkRequest = new BulkRequest();
        // 准备参数
        for(Hotel hotel : hotels){
          // 类型转化
          HotelDoc hotelDoc = new HotelDoc(hotel);
          // 请求添加数据
          bulkRequest.add(new IndexRequest("hotels").id(hotelDoc.getId().toString()).source(JSON.toJSONString(hotelDoc),XContentType.JSON));
        }
        // 发送请求
        client.bulk(bulkRequest,RequestOptions.DEFAULT);
      }
    
      // 解析对象方法
      public void show(SearchResponse response){
        // 解析响应
        SearchHits searchHits = response.getHits();
        long total = searchHits.getTotalHits().value;
        System.out.println("总计查询数据:"+total+"条");
        SearchHit[] hits = searchHits.getHits();
        for(SearchHit hit :hits){
          /// 获取文档source
          String json = hit.getSourceAsString();
          // 反序列化
          HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
          System.out.println("hotelDoc="+hotelDoc);
        }
      }
      /*---------- 全查 ------------*/
      // 全查
      @Test
      void findAllDocument() throws IOException{
        // 准备request
        SearchRequest request = new SearchRequest("hotels");
    
        // 2.准备DSL,QueryBuilders构造查询条件
        request.source().query(QueryBuilders.matchAllQuery());
    
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        show(response);
      }
    
      /*-------------- 全文检索 ---------------*/
      // 查询all字段内容中含有如家的
      @Test
      void testMacth() throws IOException{
        // 准备请求
        SearchRequest request = new SearchRequest("hotels");
        // 准备DSL
        request.source().
          query(QueryBuilders.matchQuery("all","如家"));
    
        // 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        show(response);
      }
    
      // 查询字段name、city中有上海的
      @Test
      void testMultiMatchQuery()throws IOException {
        // 准备请求
        SearchRequest request = new SearchRequest("hotels");
        // 准备DSL
        request.source()
          .query(QueryBuilders.multiMatchQuery("上海","name","city"));
        // 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        show(response);
      }
    
      /*------------ 精确查询 ------------------*/
    
      // term:根据词条精准查询(字段等值查询)
      @Test
      void testTerm() throws  IOException{
        // 准备请求
        SearchRequest request = new SearchRequest("hotels");
        // 准备DSL
        request.source()
          .query(QueryBuilders.termQuery("brand","希尔顿"));
    
        // 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        show(response);
      }
    
      // range范围查询
      @Test
      void  testRange() throws IOException {
        // 准备请求
        SearchRequest request = new SearchRequest("hotels");
        // 准备DSL
        request.source()
          .query(QueryBuilders.rangeQuery("price").gte(200).lte(300));
        // 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        show(response);
      }
    
      // ids查询
      @Test
      void testIds() throws IOException  {
        // 准备请求
        SearchRequest request = new SearchRequest("hotels");
        // 准备DSL
        request.source()
          .query(QueryBuilders.idsQuery().addIds("395434","3532"));
        // 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        show(response);
      }
    
      /*------------- 复合查询 --------------------*/
      // bool复合查询
      @Test
      void testBool() throws IOException{
        // 准备请求
        SearchRequest request = new SearchRequest("hotels");
        // 准备条件
        /*-- 方式1  ----*/
        //        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //        boolQueryBuilder.must(QueryBuilders.termQuery("city","北京"));
        //        boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(500));
        //        // 准备DSL
        //        request.source().query(boolQueryBuilder);
    
        /*---- 方式2 ----*/
        request.source()
          .query(QueryBuilders.boolQuery()
                 .must(QueryBuilders.termQuery("city","北京"))
                 .filter(QueryBuilders.rangeQuery("price").lte(500)));
        // 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        show(response);
      }
    
      // 自定义分页方式
      @Test
      void testPageAndSort() throws IOException{
        int page = 1;   //页码
        int size = 5;   //步长
        String searchName="希尔顿"; // 查询条件
        // 准备请求
        SearchRequest request = new SearchRequest("hotels");
        if (searchName == null){
          request.source().query(QueryBuilders.matchAllQuery());
        }else {
          request.source().query(QueryBuilders.matchQuery("brand",searchName));
        }
        // 自定义分页
        request.source().from((page-1)*size).size(size);
        // 自定义排序
        request.source().sort("price", SortOrder.DESC);
        // 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 解析结果
        show(response);
      }
    }
    
    • 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
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242

    小结:

    文档的查询操作实现步骤大致都相同:

    1. 准备请求
    2. 准备DSL
    3. 发送请求
  • 相关阅读:
    Image does NOT change color when selecting it in tiptap
    Python字典(dict)的操作方法汇总(约18种操作方法),并附示例代码
    C语言每日一题(6):求五位数中的变种水仙花数
    JS高级 之 防抖debounce - throttle节流
    【开源】基于Vue.js的高校宿舍调配管理系统
    FPGA设计过程中有关数据之间的并串转化
    bean的生命周期分析(四)
    高速缓冲存储器Cache的映射方式
    漫谈:C语言 C++ 所有编程语言 =和==的麻烦
    springboot项目下logback配置
  • 原文地址:https://blog.csdn.net/HakerDONG/article/details/134368392