Elasticsearch Java高级客户端

 

1.  概述

Java REST Client 有两种风格:

  • Java Low Level REST Client :用于Elasticsearch的官方低级客户端。它允许通过http与Elasticsearch集群通信。将请求编排和响应反编排留给用户自己处理。它兼容所有的Elasticsearch版本。(PS:学过WebService的话,对编排与反编排这个概念应该不陌生。可以理解为对请求参数的封装,以及对响应结果的解析)
  • Java High Level REST Client :用于Elasticsearch的官方高级客户端。它是基于低级客户端的,它提供很多API,并负责请求的编排与响应的反编排。(PS:就好比是,一个是传自己拼接好的字符串,并且自己解析返回的结果;而另一个是传对象,返回的结果也已经封装好了,直接是对象,更加规范了参数的名称以及格式,更加面对对象一点)

(PS:所谓低级与高级,我觉得一个很形象的比喻是,面向过程编程与面向对象编程)

在 Elasticsearch 7.0 中不建议使用TransportClient,并且在8.0中会完全删除TransportClient。因此,官方更建议我们用Java High Level REST Client,它执行HTTP请求,而不是序列号的Java请求。既然如此,这里就直接用高级了。

2.  Java High Level REST Client (高级REST客户端)

2.1.  Maven仓库

<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.5.4</version>
</dependency>

2.2.  依赖

  • org.elasticsearch.client:elasticsearch-rest-client
  • org.elasticsearch:elasticsearch

2.3.  初始化

RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));

高级客户端内部会创建低级客户端用于基于提供的builder执行请求。低级客户端维护一个连接池,并启动一些线程,因此当你用完以后应该关闭高级客户端,并且在内部它将会关闭低级客户端,以释放这些资源。关闭客户端可以使用close()方法:

client.close();

2.4.  文档API

2.4.1.  添加文档

IndexRequest

IndexRequest request = new IndexRequest("posts", "doc", "1");
String jsonString = "{\"user\":\"kimchy\",\"postDate\":\"2013-01-30\",\"message\":\"trying out Elasticsearch\"}";
request.source(jsonString, XContentType.JSON);

提供文档source的方式还有很多,比如:

通过Map的方式提供文档source

通过XContentBuilder方式提供source

通过Object的方式(键值对)提供source

可选参数

同步执行

异步执行

你也可以异步执行 IndexRequest,为此你需要指定一个监听器来处理这个异步响应结果:

一个典型的监听器看起来是这样的:

IndexResponse

如果有版本冲突,将会抛出ElasticsearchException

同样的异常也有可能发生在当opType设置为create的时候,且相同索引、相同类型、相同ID的文档已经存在时。例如:

2.4.2.  查看文档

Get Request

可选参数

同步执行

异步执行

Get Response

当索引不存在,或者指定的文档的版本不存在时,响应状态吗是404,并且抛出ElasticsearchException

2.4.3.  文档是否存在

2.4.4.  删除文档

Delete Request

可选参数

同添加

2.5.  搜索API

Search Request

基本格式是这样的:

大多数查询参数被添加到 SearchSourceBuilder

可选参数

SearchSourceBuilder

控制检索行为的大部分选项都可以在SearchSourceBuilder中设置。下面是一个常见选项的例子:

在这个例子中,我们首先创建了一个SearchSourceBuilder对象,并且带着默认选项。然后设置了一个term查询,接着设置检索的位置和数量,最后设置超时时间

在设置完这些选项以后,我们只需要把SearchSourceBuilder加入到SearchRequest中即可

构建Query

用QueryBuilder来创建Serarch Query。QueryBuilder支持Elasticsearch DSL中每一种Query

例如:

还可以通过QueryBuilders工具类来创建QueryBuilder对象,例如:

无论是用哪种方式创建,最后一定要把QueryBuilder添加到SearchSourceBuilder中

排序

SearchSourceBuilder 可以添加一个或多个 SortBuilder

SortBuilder有四种实现:FieldSortBuilder、GeoDistanceSortBuilder、ScoreSortBuilder、ScriptSortBuilder

聚集函数

同步执行

异步执行

从查询响应中取出文档

3.  示例

3.1.  准备数据

3.1.1.  安装IK分词器插件

./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.5.4/elasticsearch-analysis-ik-6.5.4.zip

3.1.2.  创建索引

curl -X PUT "localhost:9200/book" -H 'Content-Type: application/json' -d'
{
"mappings":{
"_doc":{
"properties":{
"id":{
"type":"integer"
},
"name":{
"type":"text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_max_word"
},
"author":{
"type":"text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_max_word"
},
"category":{
"type":"integer"
},
"price":{
"type":"double"
},
"status":{
"type":"short"
},
"sellReason":{
"type":"text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_max_word"
},
"sellTime":{
"type":"date",
"format":"yyyy-MM-dd"
}
}
}
}
}
'

3.1.3.  数据预览

3.2.  示例代码

3.2.1.  完整的pom.xml

<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cjs.example</groupId>
<artifactId>elasticsearch-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>elasticsearch-demo</name>
<description></description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency> <dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.5.4</version>
</dependency> <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

3.2.2.  配置

package com.cjs.example.elasticsearch.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* @author ChengJianSheng
* @date 2019-01-07
*/
@Configuration
public class ElasticsearchClientConfig { @Bean
public RestHighLevelClient restHighLevelClient() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")));
return client;
} }

3.2.3.  domain

package com.cjs.example.elasticsearch.domain.model;

import lombok.Data;

import java.io.Serializable;

/**
* 图书
* @author ChengJianSheng
* @date 2019-01-07
*/
@Data
public class BookModel implements Serializable { private Integer id; // 图书ID private String name; // 图书名称 private String author; // 作者 private Integer category; // 图书分类 private Double price; // 图书价格 private String sellReason; // 上架理由 private String sellTime; // 上架时间 private Integer status; // 状态(1:可售,0:不可售) }

3.2.4.  Controller

package com.cjs.example.elasticsearch.controller;

import com.alibaba.fastjson.JSON;
import com.cjs.example.elasticsearch.domain.common.BaseResult;
import com.cjs.example.elasticsearch.domain.common.Page;
import com.cjs.example.elasticsearch.domain.model.BookModel;
import com.cjs.example.elasticsearch.domain.vo.BookRequestVO;
import com.cjs.example.elasticsearch.service.BookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; /**
* 文档操作
* @author ChengJianSheng
* @date 2019-01-07
*/
@Slf4j
@RestController
@RequestMapping("/book")
public class BookController { @Autowired
private BookService bookService; /**
* 列表分页查询
*/
@GetMapping("/list")
public BaseResult list(BookRequestVO bookRequestVO) {
Page<BookModel> page = bookService.list(bookRequestVO);
if (null == page) {
return BaseResult.error();
}
return BaseResult.ok(page);
} /**
* 查看文档
*/
@GetMapping("/detail")
public BaseResult detail(Integer id) {
if (null == id) {
return BaseResult.error("ID不能为空");
}
BookModel book = bookService.detail(id);
return BaseResult.ok(book);
} /**
* 添加文档
*/
@PostMapping("/add")
public BaseResult add(@RequestBody BookModel bookModel) {
bookService.save(bookModel);
log.info("插入文档成功!请求参数: {}", JSON.toJSONString(bookModel));
return BaseResult.ok();
} /**
* 修改文档
*/
@PostMapping("/update")
public BaseResult update(@RequestBody BookModel bookModel) {
Integer id = bookModel.getId();
if (null == id) {
return BaseResult.error("ID不能为空");
}
BookModel book = bookService.detail(id);
if (null == book) {
return BaseResult.error("记录不存在");
}
bookService.update(bookModel);
log.info("更新文档成功!请求参数: {}", JSON.toJSONString(bookModel));
return BaseResult.ok();
} /**
* 删除文档
*/
@GetMapping("/delete")
public BaseResult delete(Integer id) {
if (null == id) {
return BaseResult.error("ID不能为空");
}
bookService.delete(id);
return BaseResult.ok();
} }

3.2.5.  Service

package com.cjs.example.elasticsearch.service.impl;

import com.alibaba.fastjson.JSON;
import com.cjs.example.elasticsearch.domain.common.Page;
import com.cjs.example.elasticsearch.domain.model.BookModel;
import com.cjs.example.elasticsearch.domain.vo.BookRequestVO;
import com.cjs.example.elasticsearch.service.BookService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.replication.ReplicationResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors; /**
* @author ChengJianSheng
* @date 2019-01-07
*/
@Slf4j
@Service
public class BookServiceImpl implements BookService { private static final String INDEX_NAME = "book";
private static final String INDEX_TYPE = "_doc"; @Autowired
private RestHighLevelClient client; @Override
public Page<BookModel> list(BookRequestVO bookRequestVO) {
int pageNo = bookRequestVO.getPageNo();
int pageSize = bookRequestVO.getPageSize(); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.from(pageNo - 1);
sourceBuilder.size(pageSize);
sourceBuilder.sort(new FieldSortBuilder("id").order(SortOrder.ASC));
// sourceBuilder.query(QueryBuilders.matchAllQuery()); BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); if (StringUtils.isNotBlank(bookRequestVO.getName())) {
boolQueryBuilder.must(QueryBuilders.matchQuery("name", bookRequestVO.getName()));
}
if (StringUtils.isNotBlank(bookRequestVO.getAuthor())) {
boolQueryBuilder.must(QueryBuilders.matchQuery("author", bookRequestVO.getAuthor()));
}
if (null != bookRequestVO.getStatus()) {
boolQueryBuilder.must(QueryBuilders.termQuery("status", bookRequestVO.getStatus()));
}
if (StringUtils.isNotBlank(bookRequestVO.getSellTime())) {
boolQueryBuilder.must(QueryBuilders.termQuery("sellTime", bookRequestVO.getSellTime()));
}
if (StringUtils.isNotBlank(bookRequestVO.getCategories())) {
String[] categoryArr = bookRequestVO.getCategories().split(",");
List<Integer> categoryList = Arrays.asList(categoryArr).stream().map(e->Integer.valueOf(e)).collect(Collectors.toList());
BoolQueryBuilder categoryBoolQueryBuilder = QueryBuilders.boolQuery();
for (Integer category : categoryList) {
categoryBoolQueryBuilder.should(QueryBuilders.termQuery("category", category));
}
boolQueryBuilder.must(categoryBoolQueryBuilder);
} sourceBuilder.query(boolQueryBuilder); SearchRequest searchRequest = new SearchRequest();
searchRequest.indices(INDEX_NAME);
searchRequest.source(sourceBuilder); try {
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); RestStatus restStatus = searchResponse.status();
if (restStatus != RestStatus.OK) {
return null;
} List<BookModel> list = new ArrayList<>();
SearchHits searchHits = searchResponse.getHits();
for (SearchHit hit : searchHits.getHits()) {
String source = hit.getSourceAsString();
BookModel book = JSON.parseObject(source, BookModel.class);
list.add(book);
} long totalHits = searchHits.getTotalHits(); Page<BookModel> page = new Page<>(pageNo, pageSize, totalHits, list); TimeValue took = searchResponse.getTook();
log.info("查询成功!请求参数: {}, 用时{}毫秒", searchRequest.source().toString(), took.millis()); return page;
} catch (IOException e) {
log.error("查询失败!原因: {}", e.getMessage(), e);
} return null;
} @Override
public void save(BookModel bookModel) {
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("id", bookModel.getId());
jsonMap.put("name", bookModel.getName());
jsonMap.put("author", bookModel.getAuthor());
jsonMap.put("category", bookModel.getCategory());
jsonMap.put("price", bookModel.getPrice());
jsonMap.put("sellTime", bookModel.getSellTime());
jsonMap.put("sellReason", bookModel.getSellReason());
jsonMap.put("status", bookModel.getStatus()); IndexRequest indexRequest = new IndexRequest(INDEX_NAME, INDEX_TYPE, String.valueOf(bookModel.getId()));
indexRequest.source(jsonMap); client.indexAsync(indexRequest, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() {
@Override
public void onResponse(IndexResponse indexResponse) {
String index = indexResponse.getIndex();
String type = indexResponse.getType();
String id = indexResponse.getId();
long version = indexResponse.getVersion(); log.info("Index: {}, Type: {}, Id: {}, Version: {}", index, type, id, version); if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
log.info("写入文档");
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
log.info("修改文档");
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.warn("部分分片写入成功");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();
log.warn("失败原因: {}", reason);
}
}
} @Override
public void onFailure(Exception e) {
log.error(e.getMessage(), e);
}
});
} @Override
public void update(BookModel bookModel) {
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("sellReason", bookModel.getSellReason());
UpdateRequest request = new UpdateRequest(INDEX_NAME, INDEX_TYPE, String.valueOf(bookModel.getId()));
request.doc(jsonMap);
try {
UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT);
} catch (IOException e) {
log.error("更新失败!原因: {}", e.getMessage(), e);
}
} @Override
public void delete(int id) {
DeleteRequest request = new DeleteRequest(INDEX_NAME, INDEX_TYPE, String.valueOf(id));
try {
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
if (deleteResponse.status() == RestStatus.OK) {
log.info("删除成功!id: {}", id);
}
} catch (IOException e) {
log.error("删除失败!原因: {}", e.getMessage(), e);
}
} @Override
public BookModel detail(int id) {
GetRequest getRequest = new GetRequest(INDEX_NAME, INDEX_TYPE, String.valueOf(id));
try {
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
if (getResponse.isExists()) {
String source = getResponse.getSourceAsString();
BookModel book = JSON.parseObject(source, BookModel.class);
return book;
}
} catch (IOException e) {
log.error("查看失败!原因: {}", e.getMessage(), e);
}
return null;
}
}

3.2.6.  页面

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>图书列表</title> <link rel="stylesheet" href="/bootstrap-4/css/bootstrap.min.css">
<link rel="stylesheet" href="/bootstrap-table/bootstrap-table.css"> <script src="jquery-3.3.1.min.js"></script>
<script src="/bootstrap-4/js/bootstrap.min.js"></script>
<script src="/bootstrap-table/bootstrap-table.js"></script>
<script src="/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script>
<script>
$(function(){ $('#table').bootstrapTable({
url: '/book/list',
method: 'get',
sidePagination: 'server',
responseHandler: function(res) { // 加载服务器数据之前的处理程序,可以用来格式化数据。参数:res为从服务器请求到的数据。
var result = {};
result.total = res.data.totalCount;
result.rows = res.data.pageList;
return result;
},
pagination: true,
pageSize: 3, // 初始PageSize
queryParams: function(params) {
var req = {
pageSize: params.limit,
pageNo: params.offset + 1
};
return req;
},
striped: true,
search: true,
columns: [{
field: 'id',
title: 'ID'
}, {
field: 'name',
title: '名称'
}, {
field: 'author',
title: '作者'
}, {
field: 'price',
title: '单价'
}, {
field: 'sellTime',
title: '上架时间'
}, {
field: 'status',
title: '状态',
formatter: function(value) {
if (value == 1) {
return '<span style="color: green">可售</span>';
} else {
return '<span style="color: red">不可售</span>';
}
}
}, {
field: 'category',
title: '分类',
formatter: function(value) {
if (value == 10010) {
return '中国当代小说';
} else if (value == 10011) {
return '武侠小说';
} else if (value == 10012) {
return '爱情小说';
} else if (value == 10013) {
return '中国当代随笔';
}
}
}, {
field: 'sellReason',
title: '上架理由'
}, {
title: '操作',
formatter: function() {
return '<a href="#">修改</a> <a href="#">删除</a>';
}
}
]
}); });
</script>
</head>
<body>
<div class="table-responsive" style="padding: 10px 30px">
<table id="table" class="table text-nowrap"></table>
</div>
</body>
</html>

3.3.  演示

重点演示几个查询

返回结果:

{
"code": 200,
"success": true,
"msg": "SUCCESS",
"data": {
"pageNumber": 1,
"pageSize": 10,
"totalCount": 2,
"pageList": [
{
"id": 2,
"name": "倚天屠龙记(全四册)",
"author": "金庸",
"category": 10011,
"price": 70.4,
"sellReason": "武林至尊,宝刀屠龙,号令天下,莫敢不从。",
"sellTime": "2018-11-11",
"status": 1
},
{
"id": 3,
"name": "神雕侠侣",
"author": "金庸",
"category": 10011,
"price": 70,
"sellReason": "风陵渡口初相遇,一见杨过误终身",
"sellTime": "2018-11-11",
"status": 1
}
]
}
}

上面的查询对应的Elasticsearch DSL是这样的:

{
"from":0,
"size":10,
"query":{
"bool":{
"must":[
{
"match":{
"author":{
"query":"金庸",
"operator":"OR",
"prefix_length":0,
"max_expansions":50,
"fuzzy_transpositions":true,
"lenient":false,
"zero_terms_query":"NONE",
"auto_generate_synonyms_phrase_query":true,
"boost":1
}
}
},
{
"term":{
"status":{
"value":1,
"boost":1
}
}
},
{
"bool":{
"should":[
{
"term":{
"category":{
"value":10010,
"boost":1
}
}
},
{
"term":{
"category":{
"value":10011,
"boost":1
}
}
},
{
"term":{
"category":{
"value":10012,
"boost":1
}
}
}
],
"adjust_pure_negative":true,
"boost":1
}
}
],
"adjust_pure_negative":true,
"boost":1
}
},
"sort":[
{
"id":{
"order":"asc"
}
}
]
}

3.4.  工程结构

4.  参考

https://github.com/medcl/elasticsearch-analysis-ik

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-search.html

https://bootstrap-table.wenzhixin.net.cn/documentation/

5.  其它相关

《Elasticsearch 分词器》

《Elasticsearch Document》

《Elasticsearch Search API》

《Elasticsearch查询》

《Elasticsearch Mapping》

《SpringBoot+Elasticsearch》

《ELK快速搭建日志平台》

本文摘自:https://www.cnblogs.com/cjsblog/p/10232581.html


感谢您的阅读,如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮。欢迎各位转载,但必须在文章页面中给出作者和原文连接。

【Elasticsearch-Java】Java客户端搭建的更多相关文章

  1. [转]World Wind Java开发之四——搭建本地WMS服务器

    在提供地理信息系统客户端时,NASA还为用户提供了开源的WMS Server 服务器应用:World Wind WMS Server.利用这个应用,我们可以架设自己的WMS服务并使用自己的数据(也支持 ...

  2. 使用Java操作Elasticsearch(Elasticsearch的java api使用)

    1.Elasticsearch是基于Lucene开发的一个分布式全文检索框架,向Elasticsearch中存储和从Elasticsearch中查询,格式是json. 索引index,相当于数据库中的 ...

  3. 超全详解Java开发环境搭建

    摘自:https://www.cnblogs.com/wangjiming/p/11278577.html 超全详解Java开发环境搭建   在项目产品开发中,开发环境搭建是软件开发的首要阶段,也是必 ...

  4. MAC系统 -java开发环境搭建

    MAC - java开发环境搭建 软件: jdk Intellij IDEA:java开发工具 maven:jar包管理 git :源码管理 sourceTree :源码管理GUI客户端 Studio ...

  5. Java操作Elasticsearch 之 [Java High Level REST Clientedit]

    1. 简述 Elasticsearch 是基于 Lucene 开发的一个分布式全文检索框架,向 Elasticsearch 中存储和从 Elasticsearch 中查询,格式是json. 向 Ela ...

  6. JAVA web环境搭建(使用Tomcat8整合httpd)

    说明:这里是Linux服务综合搭建文章的一部分,本文可以作为单独搭建Tomcat并整合httpd的参考. 注意:这里所有的标题都是根据主要的文章(Linux基础服务搭建综合)的顺序来做的. 如果需要查 ...

  7. Java Web 环境搭建步骤(超详细,包括前期安装步骤)

    Java Web 环境搭建步骤 安装对应版本的JDK 配置环境变量 本人安装的路径是C盘,在path中加入C:\Program Files\Java\jdk1.8.0_65\bin 测试配置成功,cm ...

  8. Intellij IDEA Java web 项目搭建

    Java web 项目搭建 简介 在上一节java web环境搭建中,我们配置了开发java web项目最基本的环境,现在我们将采用Spring MVC+Spring+Hibernate的架构搭建一个 ...

  9. Intellij IDEA工具Java web 环境搭建

    Java web 环境搭建 环境依赖 操作系统:Windows 7 64位 开发工具:IntelliJ IDEA 13.1.4 开发工具依赖环境 JDK版本:1.7+ 开发工具依赖插件 包管理:Mav ...

随机推荐

  1. rocketmq有序消息的(四)

    opic的有序消息已经成为mq的标配.而RocketMQ中是这样区分消息类型的, 普通消息也叫做无序消息,简单来说就是没有顺序的消息,而有序消息就是按照一定的先后顺序的消息类型.举个例子,produc ...

  2. Django笔记&教程 总目录

    本篇博客只有目录,正文内容在目录章节链接的博客里 除目录本身外,没有链接的章节,说明内容还没开始编辑 本项目笔记仍在不断创作中,还有些内容会根据自身所学不断更新完善 本项目主要为markdwon文档, ...

  3. PAT A1060——string的常见用法详解

    string 常用函数实例 (1)operator += 可以将两个string直接拼接起来 (2)compare operator 可以直接使用==.!=.<.<=.>.>= ...

  4. Json数据使用及学习方法

    以前对json的了解并不是很清楚,因为使用很少,所以也没有特意的研究.只知道json是轻量级的数据交换格式,可以被多种语言方便的处理,也是大型门户站接口使用的主要数据格式. 而最近做了个项目,涉及到j ...

  5. [atARC063F]Snuke's Coloring 2

    首先,可以通过将所有$x_{i}=0$都选择第1类,其余选第2类,构造出一个以$(0,0)$和$(1,h)$为左下角和右上角的矩形,答案即为$2h+2$,类似地还可以构造出$2w+2$ 若最终的矩形不 ...

  6. [uva11429]Randomness

    记p(i,j)表示第i次随机时,用多少个数对应到第j个事件,特别的,p(i,0)表示转移到下一次随机数的概率,那么即要求$aj/bj=\sum_{i=1}^{inf}p(i,j)/R^{i}$,容易发 ...

  7. 异常处理截止和UML图

    0.异常处理机制 0.1.java中异常的作用是:增强程序健壮性. 0.2.java中异常以类和对象的形式存在. 1.java的异常处理机制 1.1.异常在java中以类和对象的形式存在.那么异常的继 ...

  8. 统计学习1:朴素贝叶斯模型(Numpy实现)

    模型 生成模型介绍 我们定义样本空间为\(\mathcal{X} \subseteq \mathbb{R}^n\),输出空间为\(\mathcal{Y} = \{c_1, c_2, ..., c_K\ ...

  9. Codeforces 1076G - Array Game(博弈论+线段树)

    Codeforces 题面传送门 & 洛谷题面传送门 一道 hot tea--听讲解时半懂不懂因为不知道题目意思,最后终究还是琢磨出来了( 首先注意到对于每个 \(a_i\),它具体是什么并不 ...

  10. Codeforces Round #683 (Div. 1) Solution

    A. Knapsack 猜个结论--先把所有的东西加起来,如果小于 \(\frac{1}{2}m\) 就输出不合法:如果在 \([\frac{1}{2}m, m]\)之间直接全部输出:若大于 \(m\ ...