1. 程式人生 > >spring boot 2.x + elasticsearch+mybatis-plus

spring boot 2.x + elasticsearch+mybatis-plus

第一步引入 maven

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.elasticsearch</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.2</version>
        </dependency>
        <!--mybatis-plus整合-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

2 配置檔案

spring:
  data:
    elasticsearch:
      cluster-name: my-application
      cluster-nodes: 127.0.0.1:9300
      properties:
        path:
          logs: ./elasticsearch/log
          data: ./elasticsearch/data
  datasource:
      name: oss-service
      url: jdbc:mysql://localhost:3306/es?useSSL=false&characterEncoding=utf8
      username: root
      password: root
      # 使用druid資料來源
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: com.mysql.jdbc.Driver
      druid:
        query-timeout: 2400
        filters: stat
        maxActive: 20
        initialSize: 1
        maxWait: 60000
        minIdle: 1
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: select 'x'
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        maxOpenPreparedStatements: 20

3 config配置

@Configuration
public class ElasticSearchConfig {

    @Bean
    public ElasticsearchTemplate elasticsearchTemplate(Client client) {
        return new ElasticsearchTemplate(client);
    }

}
@Configuration
@MapperScan("com.elasticsearch.demo.dao")
public class MybatisPlusConfig {

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

    /**
     * SQL執行效率外掛
     */
    @Bean
    @Profile({"dev","test"})// 設定 dev test 環境開啟
    public PerformanceInterceptor performanceInterceptor() {
        return new PerformanceInterceptor();
    }
}

4 java Bean 

@Document(indexName = "es", type = "posts", indexStoreType = "fs", shards = 5, replicas = 1, refreshInterval = "-1")
public class Posts {
    
}

@Document註解裡面的幾個屬性,類比mysql的話是這樣: 
index –> DB 
type –> Table 
Document –> row 
@Id註解加上後,在Elasticsearch裡相應於該列就是主鍵了,在查詢時就可以直接用主鍵查詢,後面一篇會講到。其實和mysql非常類似,基本就是一個數據庫。

@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Document {

String indexName();//索引庫的名稱,個人建議以專案的名稱命名

String type() default "";//型別,個人建議以實體的名稱命名

short shards() default 5;//預設分割槽數

short replicas() default 1;//每個分割槽預設的備份數

String refreshInterval() default "1s";//重新整理間隔

String indexStoreType() default "fs";//索引檔案儲存型別
}

加上了@Document註解之後,預設情況下這個實體中所有的屬性都會被建立索引、並且分詞。 
我們通過@Field註解來進行詳細的指定,如果沒有特殊需求,那麼只需要新增@Document即可。

@Field註解的定義如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@Inherited
public @interface Field {

FieldType type() default FieldType.Auto;#自動檢測屬性的型別

FieldIndex index() default FieldIndex.analyzed;#預設情況下分詞

DateFormat format() default DateFormat.none;

String pattern() default "";

boolean store() default false;#預設情況下不儲存原文

String searchAnalyzer() default "";#指定欄位搜尋時使用的分詞器

String indexAnalyzer() default "";#指定欄位建立索引時指定的分詞器

String[] ignoreFields() default {};#如果某個欄位需要被忽略

boolean includeInParent() default false;
}
@RestController
public class IndexController {

    @Autowired
    private PostsService postsService;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @GetMapping("save")
    public String save() {
        List<Posts> list = postsService.list(null);

        list.stream().forEach(posts -> {
            IndexQuery indexQuery = new IndexQueryBuilder().withId(posts.getId() + "").withObject(posts).build();
            elasticsearchTemplate.index(indexQuery);
        });

        return "success";
    }

    @GetMapping("get")
    public Page<Posts> test(String word, @PageableDefault Pageable pageable) {
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(matchQuery("postTitle",word ))
                .withPageable(pageable)
                .withHighlightFields(new HighlightBuilder.Field("postTitle").preTags("<em>").postTags("</em>"))
                .build();

        Page<Posts> page = elasticsearchTemplate.queryForPage(searchQuery, Posts.class, new DefaultResultMapper() {

            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
                List<T> chunk = new ArrayList<>();
                for (SearchHit searchHit : searchResponse.getHits()) {
                    if (searchResponse.getHits().getHits().length <= 0) {
                        return null;
                    }
                    String[] heightFields = {"postTitle"};

                    Map<String, Object> entityMap = searchHit.getSource();
                    for (String highName : heightFields) {
                        Text text[] = searchHit.getHighlightFields().get(highName).fragments();
                        if (text.length > 0) {
                            String highValue = searchHit.getHighlightFields().get(highName).fragments()[0].toString();
                            entityMap.put(highName, highValue);
                        }
                    }

                    try {
                        T t = getEntityMapper().mapToObject(searchHit.getSourceAsString(), aClass);
                        Field postTitle = aClass.getDeclaredField("postTitle");
                        postTitle.setAccessible(true);
                        postTitle.set(t,entityMap.get("postTitle"));

//                        Field postContent = aClass.getDeclaredField("postContent");
//                        postContent.setAccessible(true);
//                        postContent.set(t,entityMap.get("postContent"));

                        chunk.add(t);
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (NoSuchFieldException e) {
                        e.printStackTrace();
                    }
//                    chunk.add((Posts) PropertyHelper.getFansheObj(
//                            Posts.class, entityMap));
                }

                return new AggregatedPageImpl(chunk);
            }
        });
        return page;
    }
}

轉載 http://www.51csdn.cn/article/165.html