Spring Boot整合ElasticSearch实现多版本兼容的方法详解

前言

在上一篇学习SpringBoot中,整合了Mybatis、Druid和PageHelper并实现了多数据源的操作。本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和SpringBoot进行结合使用。

ElasticSearch介绍

ElasticSearch是一个基于Lucene的搜索服务器,其实就是对Lucene进行封装,提供了 REST API 的操作接口 ElasticSearch作为一个高度可拓展的开源全文搜索和分析引擎,可用于快速地对大数据进行存储,搜索和分析。

ElasticSearch主要特点:分布式、高可用、异步写入、多API、面向文档 。

ElasticSearch核心概念:近实时,集群,节点(保存数据),索引,分片(将索引分片),副本(分片可设置多个副本) 。它可以快速地储存、搜索和分析海量数据。

ElasticSearch使用案例:维基百科、Stack Overflow、Github 等等。

SpringBoot整合Elasticsearch

在使用SpringBoot整合Elasticsearch 之前,我们应该了解下它们之间对应版本的关系。

Spring Boot Version (x) Spring Data Elasticsearch Version (y) Elasticsearch Version (z)
x <= 1.3.5 y <= 1.3.4 z <= 1.7.2*
x >= 1.4.x 2.0.0 <=y < 5.0.0** 2.0.0 <= z < 5.0.0**

这里我们使用的SpringBoot的版本是1.5.9,Elasticsearch的版本是2.3.5。

使用SpringBoot整合Elasticsearch,一般都是使用 SpringData 进行封装的,然后再dao层接口继承ElasticsearchRepository 类,该类实现了很多的方法,比如常用的CRUD方法。

SpringData的使用

首先,在使用之前,先做好相关的准备。

Maven的配置如下:

<dependency> <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 <version>1.5.9.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
 <version>1.5.9.RELEASE</version>
 </dependency>

application.properties的配置

spring.data.elasticsearch.repositories.enabled = true
spring.data.elasticsearch.cluster-nodes =127.0.0.1\:9300

注: 9300 是 Java 客户端的端口。9200 是支持 Restful HTTP 的接口。

更多的配置:

spring.data.elasticsearch.cluster-name Elasticsearch 集群名。(默认值: elasticsearch)
spring.data.elasticsearch.cluster-nodes 集群节点地址列表,用逗号分隔。如果没有指定,就启动一个客户端节点。
spring.data.elasticsearch.propertie 用来配置客户端的额外属性。
spring.data.elasticsearch.repositories.enabled 开启 Elasticsearch 仓库。(默认值:true。)

代码编写

实体类

@Document(indexName = "userindex", type = "user")
public class User implements Serializable{
 /**
 *
 */
 private static final long serialVersionUID = 1L;
 /** 编号 */
 private Long id;
 /** 姓名 */
 private String name;

 /** 年龄 */
 private Integer age;

 /** 描述 */
 private String description;

 /** 创建时间 */
 private String createtm;
 // getter和setter 略
} 

使用SpringData的时候,它需要在实体类中设置indexName 和type ,如果和传统型数据库比较的话,就相当于库和表。

需要注意的是indexName和type都必须是小写!!!

dao层

public interface UserDao extends ElasticsearchRepository<User, Long>{
}

dao层这里就比较简单了,只需继承ElasticsearchRepository该类就行了。其中主要的方法就是 save、delete和search。其中save方法相当如insert和update,没有就新增,有就覆盖。delete方法主要就是删除数据以及索引库。至于search就是查询了,包括一些常用的查询,如分页、权重之类的。

Service层

@Service
public class UserServiceImpl implements UserService {
 @Autowired
 private UserDao userDao;
 @Override
 public boolean insert(User user) {
 boolean falg=false;
 try{
 userDao.save(user);
 falg=true;
 }catch(Exception e){
 e.printStackTrace();
 }
 return falg;
 }

 @Override
 public List<User> search(String searchContent) {
 QueryStringQueryBuilder builder = new QueryStringQueryBuilder(searchContent);
 System.out.println("查询的语句:"+builder);
 Iterable<User> searchResult = userDao.search(builder);
 Iterator<User> iterator = searchResult.iterator();
 List<User> list=new ArrayList<User>();
 while (iterator.hasNext()) {
 list.add(iterator.next());
 }
 return list;
 }

 @Override
 public List<User> searchUser(Integer pageNumber, Integer pageSize,String searchContent) {
 // 分页参数
 Pageable pageable = new PageRequest(pageNumber, pageSize);
 QueryStringQueryBuilder builder = new QueryStringQueryBuilder(searchContent);
 SearchQuery searchQuery = new NativeSearchQueryBuilder().withPageable(pageable).withQuery(builder).build();
 System.out.println("查询的语句:" + searchQuery.getQuery().toString());
 Page<User> searchPageResults = userDao.search(searchQuery);
 return searchPageResults.getContent();
 }

 @Override
 public List<User> searchUserByWeight(String searchContent) {
 // 根据权重进行查询
 FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery()
 .add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("name", searchContent)),
  ScoreFunctionBuilders.weightFactorFunction(10))
 .add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("description", searchContent)),
  ScoreFunctionBuilders.weightFactorFunction(100)).setMinScore(2);
 System.out.println("查询的语句:" + functionScoreQueryBuilder.toString());
 Iterable<User> searchResult = userDao.search(functionScoreQueryBuilder);
 Iterator<User> iterator = searchResult.iterator();
 List<User> list=new ArrayList<User>();
 while (iterator.hasNext()) {
 list.add(iterator.next());
 }
 return list;
 }
}

这里我就简单的写了几个方法,其中主要的方法是查询。查询包括全文搜索,分页查询和权重查询。其中需要说明的是权重查询这块,权重的分值越高,查询的结果也越靠前,如果没有对其它的数据设置分值,它们默认的分值就是1,如果不想查询这些语句,只需使用setMinScore将其设为大于1即可。

代码测试

调用接口进行添加数据

新增数据:

POST http://localhost:8086/api/user
{"id":1,"name":"张三","age":20,"description":"张三是个Java开发工程师","createtm":"2018-4-25 11:07:42"}
{"id":2,"name":"李四","age":24,"description":"李四是个测试工程师","createtm":"1980-2-15 19:01:32"}
{"id":3,"name":"王五","age":25,"description":"王五是个运维工程师","createtm":"2016-8-21 06:11:32"}

进行全文查询

请求

http://localhost:8086/api/user?searchContent=工程师

返回

[{"id":2,"name":"李四","age":14,"description":"李四是个测试工程师","createtm": "1980-2-15 19:01:32"},
{"id":1,"name":"张三","age":20,"description":"张三是个Java开发工程师", "createtm": "2018-4-25 11:07:42"},
{"id":3,"name":"王五","age":25,"description":"王五是个运维工程师","createtm": "2016-8-21 06:11:32"}]

进行分页查询

请求

http://localhost:8086/api/user?pageNumber=0&pageSize=2&searchContent=工程师

返回

[{"id":2,"name":"李四","age":14,"description":"李四是个测试工程师"},{"id":1,"name":"张三","age":20,"description":"张三是个Java开发工程师"}]

进行权重查询

请求

http://localhost:8086/api/user2?searchContent=李四

返回

[{"id":2,"name":"李四","age":24,"description":"李四是个测试工程师","createtm":"1980-2-15 19:01:32"}]

权重查询打印的语句:

查询的语句:{{
 "function_score" : {
 "functions" : [ {
 "filter" : {
 "bool" : {
 "should" : {
 "match" : {
 "name" : {
 "query" : "李四",
 "type" : "boolean"
 }
 }
 }
 }
 },
 "weight" : 10.0
 }, {
 "filter" : {
 "bool" : {
 "should" : {
 "match" : {
 "description" : {
 "query" : "李四",
 "type" : "boolean"
 }
 }
 }
 }
 },
 "weight" : 100.0
 } ],
 "min_score" : 2.0
 }
}

注:测试中,因为设置了setMinScore最小权重分为2的,所以无关的数据是不会显示出来的。如果想显示的话,在代码中去掉即可。

新增完数据之后,可以在浏览器输入:http://localhost:9200/_plugin/head/

然后点击基本查询,便可以查看添加的数据。如果想用语句查询,可以将程序中控制台打印的查询语句粘贴到查询界面上进行查询!

注:这里的ElasticSearch是我在windows上安装的,并安装了ES插件head,具体安装步骤在文章末尾。

除了SpringData之外,其实还有其它的方法操作ElasticSearch的。

比如使用原生ElasticSearch的Api,使用TransportClient类实现。

或者使用由Spring封装,只需在Service层,进行注入Bean即可。

示例:

@Autowired
 ElasticsearchTemplate elasticsearchTemplate; 

但是,上述方法中都有其局限性,也就是随着ElasticSearch的版本变更,相关的Java API也在做不断的调整,就是ElasticSearch服务端版本进行更改之后,客户端的代码可能需要重新编写。

因此介绍一个相当好用的第三方工具JestClient,它对ElasticSearch进行封装,填补了 ElasticSearch HttpRest接口 客户端的空白,它适用于ElasticSearch2.x以上的版本,无需因为ElasticSearch服务端版本更改而对代码进行更改!

JestClient

首先在Maven中添加如下依赖:

 <dependency>
 <groupId>io.searchbox</groupId>
 <artifactId>jest</artifactId>
 <version>5.3.3</version>
 </dependency>

然后编写相关的测试代码。

代码中的注释应该很完整,所以这里就不再对代码过多的讲述了。

import java.util.ArrayList;
import java.util.List;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import com.pancm.pojo.User;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.JestResult;
import io.searchbox.client.config.HttpClientConfig;
import io.searchbox.core.Bulk;
import io.searchbox.core.BulkResult;
import io.searchbox.core.Delete;
import io.searchbox.core.DocumentResult;
import io.searchbox.core.Index;
import io.searchbox.core.Search;
import io.searchbox.indices.CreateIndex;
import io.searchbox.indices.DeleteIndex;
import io.searchbox.indices.mapping.GetMapping;
import io.searchbox.indices.mapping.PutMapping;

public class JestTest {
 private static JestClient jestClient;
 private static String indexName = "userindex";
// private static String indexName = "userindex2";
 private static String typeName = "user";
 private static String elasticIps="http://192.169.2.98:9200";
// private static String elasticIps="http://127.0.0.1:9200";

 public static void main(String[] args) throws Exception {
 jestClient = getJestClient();
 insertBatch();
 serach1();
 serach2();
 serach3();
 jestClient.close(); 

 }

 private static JestClient getJestClient() {
 JestClientFactory factory = new JestClientFactory();
 factory.setHttpClientConfig(new HttpClientConfig.Builder(elasticIps).connTimeout(60000).readTimeout(60000).multiThreaded(true).build());
 return factory.getObject();
 } 

 public static void insertBatch() {
 List<Object> objs = new ArrayList<Object>();
 objs.add(new User(1L, "张三", 20, "张三是个Java开发工程师","2018-4-25 11:07:42"));
 objs.add(new User(2L, "李四", 24, "李四是个测试工程师","1980-2-15 19:01:32"));
 objs.add(new User(3L, "王五", 25, "王五是个运维工程师","2016-8-21 06:11:32"));
 boolean result = false;
 try {
 result = insertBatch(jestClient,indexName, typeName,objs);
 } catch (Exception e) {
 e.printStackTrace();
 }
 System.out.println("批量新增:"+result);
 }

 /**
 * 全文搜索
 */
 public static void serach1() {
 String query ="工程师";
 try {
 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  searchSourceBuilder.query(QueryBuilders.queryStringQuery(query));
  //分页设置
  searchSourceBuilder.from(0).size(2);
 System.out.println("全文搜索查询语句:"+searchSourceBuilder.toString());
 System.out.println("全文搜索返回结果:"+search(jestClient,indexName, typeName, searchSourceBuilder.toString()));
 } catch (Exception e) {
 e.printStackTrace();
 }
 }

 /**
 * 精确搜索
 */
 public static void serach2() {
 try {
 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
 searchSourceBuilder.query(QueryBuilders.termQuery("age", 24));
 System.out.println("精确搜索查询语句:"+searchSourceBuilder.toString());
 System.out.println("精确搜索返回结果:"+search(jestClient,indexName, typeName, searchSourceBuilder.toString()));
 } catch (Exception e) {
 e.printStackTrace();
 }
 }

 /**
 * 区间搜索
 */
 public static void serach3() {
 String createtm="createtm";
 String from="2016-8-21 06:11:32";
 String to="2018-8-21 06:11:32";

 try {
 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
 searchSourceBuilder.query(QueryBuilders.rangeQuery(createtm).gte(from).lte(to));
 System.out.println("区间搜索语句:"+searchSourceBuilder.toString());
 System.out.println("区间搜索返回结果:"+search(jestClient,indexName, typeName, searchSourceBuilder.toString()));
 } catch (Exception e) {
 e.printStackTrace();
 }
 }

 /**
 * 创建索引
 * @param indexName
 * @return
 * @throws Exception
 */
 public boolean createIndex(JestClient jestClient,String indexName) throws Exception {
 JestResult jr = jestClient.execute(new CreateIndex.Builder(indexName).build());
 return jr.isSucceeded();
 } 

 /**
 * 新增数据
 * @param indexName
 * @param typeName
 * @param source
 * @return
 * @throws Exception
 */
 public boolean insert(JestClient jestClient,String indexName, String typeName, String source) throws Exception {
 PutMapping putMapping = new PutMapping.Builder(indexName, typeName, source).build();
 JestResult jr = jestClient.execute(putMapping);
 return jr.isSucceeded();
 } 

 /**
 * 查询数据
 * @param indexName
 * @param typeName
 * @return
 * @throws Exception
 */
 public static String getIndexMapping(JestClient jestClient,String indexName, String typeName) throws Exception {
 GetMapping getMapping = new GetMapping.Builder().addIndex(indexName).addType(typeName).build();
 JestResult jr =jestClient.execute(getMapping);
 return jr.getJsonString();
 } 

 /**
 * 批量新增数据
 * @param indexName
 * @param typeName
 * @param objs
 * @return
 * @throws Exception
 */
 public static boolean insertBatch(JestClient jestClient,String indexName, String typeName, List<Object> objs) throws Exception {
 Bulk.Builder bulk = new Bulk.Builder().defaultIndex(indexName).defaultType(typeName);
 for (Object obj : objs) {
 Index index = new Index.Builder(obj).build();
  bulk.addAction(index);
 }
 BulkResult br = jestClient.execute(bulk.build());
 return br.isSucceeded();
 } 

 /**
 * 全文搜索
 * @param indexName
 * @param typeName
 * @param query
 * @return
 * @throws Exception
 */
 public static String search(JestClient jestClient,String indexName, String typeName, String query) throws Exception {
 Search search = new Search.Builder(query)
 .addIndex(indexName)
 .addType(typeName)
 .build();
 JestResult jr = jestClient.execute(search);
// System.out.println("--"+jr.getJsonString());
// System.out.println("--"+jr.getSourceAsObject(User.class));
 return jr.getSourceAsString();
 } 

 /**
 * 删除索引
 * @param indexName
 * @return
 * @throws Exception
 */
 public boolean delete(JestClient jestClient,String indexName) throws Exception {
 JestResult jr = jestClient.execute(new DeleteIndex.Builder(indexName).build());
 return jr.isSucceeded();
 } 

 /**
 * 删除数据
 * @param indexName
 * @param typeName
 * @param id
 * @return
 * @throws Exception
 */
 public boolean delete(JestClient jestClient,String indexName, String typeName, String id) throws Exception {
 DocumentResult dr = jestClient.execute(new Delete.Builder(id).index(indexName).type(typeName).build());
 return dr.isSucceeded();
 } 

注:测试之前先说明下,本地windows系统安装的是ElasticSearch版本是2.3.5,linux服务器上安装的ElasticSearch版本是6.2。

测试结果

全文搜索

全文搜索查询语句:{
 "from" : 0,
 "size" : 2,
 "query" : {
 "query_string" : {
 "query" : "工程师"
 }
 }
}

全文搜索返回结果:{"id":1,"name":"张三","age":20,"description":"张三是个Java开发工程师","createtm":"2018-4-25 11:07:42"},{"id":2,"name":"李四","age":24,"description":"李四是个测试工程师","createtm":"1980-2-15 19:01:32"}

匹配搜索

精确搜索查询语句:{
 "query" : {
 "term" : {
 "age" : 24
 }
 }
}

精确搜索返回结果:{"id":2,"name":"李四","age":24,"description":"李四是个测试工程师","createtm":"1980-2-15 19:01:32"}

时间区间搜索

区间搜索语句:{
 "query" : {
 "range" : {
 "createtm" : {
 "from" : "2016-8-21 06:11:32",
 "to" : "2018-8-21 06:11:32",
 "include_lower" : true,
 "include_upper" : true
 }
 }
 }
}
区间搜索返回结果:{"id":1,"name":"张三","age":20,"description":"张三是个Java开发工程师","createtm":"2018-4-25 11:07:42"}

新增完数据之后,我们可以上linux的 Kibana中进行相关的查询,查询结果如下:

注:Kibana 是属于ELK中一个开源软件。Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助汇总、分析和搜索重要数据日志。

上述代码中测试返回的结果符合我们的预期。其中关于JestClient只是用到了很少的一部分,更多的使用可以查看JestClient的官方文档。

Windows安装ElasticSearch

1,文件准备

下载地址:https://www.elastic.co/downloads

选择ElasticSearch相关版本, 然后选择后缀名为ZIP文件进行下载,下载之后进行解压。

2,启动Elasticsearch

进入bin目录下,运行 elasticsearch.bat

然后在浏览上输入: localhost:9200

成功显示一下界面表示成功!

3,安装ES插件

web管理界面head 安装

进入bin目录下,打开cmd,进入dos界面

输入:plugin install mobz/elasticsearch-head

进行下载

成功下载之后,在浏览器输入:http://localhost:9200/_plugin/head/

若显示一下界面,则安装成功!

4,注册服务

进入bin目录下,打开cmd,进入dos界面

依次输入:

service.bat install
service.bat start

成功之后,再输入

services.msc

跳转到Service服务界面,可以直接查看es的运行状态!

其它

ElasticSearch官网API地址:

https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.3/index.html

JestClientGithub地址:

https://github.com/searchbox-io/Jest (本地下载)

项目我放到github上面去了。

https://github.com/xuwujing/springBoot (本地下载)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Spring Boot集成ElasticSearch实现搜索引擎的示例

    Elastic Search是一个开源的,分布式,实时搜索和分析引擎.Spring Boot为Elasticsearch及Spring Data Elasticsearch提供的基于它的抽象提供了基本的配置.Spring Boot提供了一个用于聚集依赖的spring-boot-starter-data-elasticsearch 'StarterPOM'. ElasticSearch作为搜索引擎,我们需要解决2大问题: 1,  如何将被搜索的数据在ES上创建反向索引 2,  Java代码如何与E

  • SpringBoot整合ElasticSearch实践

    本节我们基于一个发表文章的案例来说明SpringBoot如何elasticsearch集成.elasticsearch本身可以是一个独立的服务,也可以嵌入我们的web应用中,在本案例中,我们讲解如何将elasticsearch嵌入我们的应用中. 案例背景:每个文章(Article)都要属于一个教程(Tutorial),而且每个文章都要有一个作者(Author). 一.实体设计: Tutorial.java public class Tutorial implements Serializable

  • 详解spring-boot集成elasticsearch及其简单应用

    介绍 记录将elasticsearch集成到spring boot的过程,以及一些简单的应用和helper类使用. 接入方式 使用spring-boot中的spring-data-elasticsearch,可以使用两种内置客户端接入 1.节点客户端(node client): 配置文件中设置为local:false,节点客户端以无数据节点(node-master或node-client)身份加入集群,换言之,它自己不存储任何数据,但是它知道数据在集群中的具体位置,并且能够直接转发请求到对应的节

  • Spring boot中使用ElasticSearch的方法详解

    0.版本选择 我这里选择了5.6.x,记得如果spring-boot-starter-parent是1.x可以选择2.x版本的elasticsearch,版本要对应,不然会有莫名其妙的问题 1.安装ElasticSearch https://www.elastic.co/downloads/past-releases windows 测试的,解压就能用 解压,到bin目录,双击elasticsearch.bat 1.1安装elasticsearch-head https://github.com

  • SpringBoot整合ElasticSearch的示例代码

    ElasticSearch作为基于Lucene的搜索服务器,既可以作为一个独立的服务部署,也可以签入Web应用中.SpringBoot作为Spring家族的全新框架,使得使用SpringBoot开发Spring应用变得非常简单.本文要介绍如何整合ElasticSearch与SpringBoot. 实体设计: 每一本书(Book)都属于一个分类(Classify),都有一个作者(Author). 生成这个三个实体类,并实现其get和set方法. SpringBoot配置修改: 1.修改pom.xm

  • Spring Boot与Kotlin 整合全文搜索引擎Elasticsearch的示例代码

    Elasticsearch 在全文搜索里面基本是无敌的,在大数据里面也很有建树,完全可以当nosql(本来也是nosql)使用. 这篇文章简单介绍Spring Boot使用Kotlin语言连接操作 Elasticsearch.但是不会做很详细的介绍,如果要深入了解Elasticsearch在Java/kotlin中的使用,请参考我之前编写的<Elasticsearch Java API 手册> https://gitee.com/quanke/elasticsearch-java/ 里面包含使

  • springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服务的坑

    前一阵子准备为项目搭建一个简单的搜索服务,虽然业务数据库mongodb提供了文本搜索的支持,但是在大量文档需要通过关键词进行定位时,es明显更加适合去作为一个搜索引擎(虽然我们之前大部分使用到了ELK那套分析和可视化的特性).Elasticsearch建立在Lucene之上并且支持极其快速的查询和丰富的查询语法,偶尔也可以作为一个轻量级的NoSQL.但是对复杂查询和聚合操作的能力并不是很强. 本篇不会提及如何搭建一个简单搜索服务,而是记录一下大约一周工作时间内遇见的几个坑.. 为什么选择elas

  • Spring Boot整合Elasticsearch实现全文搜索引擎案例解析

    简单说,ElasticSearch(简称 ES)是搜索引擎,是结构化数据的分布式搜索引擎.Elastic Search是一个开源的,分布式,实时搜索和分析引擎.Spring Boot为Elasticsearch及Spring Data Elasticsearch提供的基于它的抽象提供了基本的配置.Spring Boot提供了一个用于聚集依赖的spring-boot-starter-data-elasticsearch 'StarterPOM'. 引入spring-boot-starter-dat

  • SpringBoot整合Elasticsearch并实现CRUD操作

     配置准备 在build.gradle文件中添加如下依赖: compile "org.elasticsearch.client:transport:5.5.2" compile "org.elasticsearch:elasticsearch:5.5.2" //es 5.x的内部使用的 apache log4日志 compile "org.apache.logging.log4j:log4j-core:2.7" compile "org

  • Spring Boot整合ElasticSearch实现多版本兼容的方法详解

    前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和SpringBoot进行结合使用. ElasticSearch介绍 ElasticSearch是一个基于Lucene的搜索服务器,其实就是对Lucene进行封装,提供了 REST API 的操作接口 ElasticSearch作为一个高度可拓展的开源全文搜索和分析引擎,可用于快速地对大数据进行存储,搜索和分析.

  • Spring Boot 整合mybatis 使用多数据源的实现方法

    前言 本篇教程偏向实战,程序猿直接copy代码加入到自己的项目中做简单的修修改改便可使用,而对于springboot以及mybatis不在此进行展开介绍,如有读者希望了解可以给我留言,并持续关注,我后续会慢慢更新.(黑色区域代码部分,安卓手机可手动向左滑动,来查看全部代码) 整合 其实整合很简单,如果是用gradle的话,在build.gradle文件里加入 compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1')

  • Spring Boot整合JPA使用多个数据源的方法步骤

    介绍 JPA(Java Persistence API)Java 持久化 API,是 Java 持久化的标准规范,Hibernate 是持久化规范的技术实现,而 Spring Data JPA 是在 Hibernate 基础上封装的一款框架. 第一次使用 Spring JPA 的时候,感觉这东西简直就是神器,几乎不需要写什么关于数据库访问的代码一个基本的 CURD 的功能就出来了.在这篇文章中,我们将介绍 Spring Boot 整合 JPA 使用多个数据源的方法. 开发环境: Spring B

  • Spring Boot 使用 SSE 方式向前端推送数据详解

    目录 前言 服务端 SSE工具类 在Controller层创建 SSEController.java 前端代码 前言 SSE简单的来说就是服务器主动向前端推送数据的一种技术,它是单向的,也就是说前端是不能向服务器发送数据的.SSE适用于消息推送,监控等只需要服务器推送数据的场景中,下面是使用Spring Boot 来实现一个简单的模拟向前端推动进度数据,前端页面接受后展示进度条. 服务端 在Spring Boot中使用时需要注意,最好使用Spring Web 提供的SseEmitter这个类来进

  • SpringBoot整合MinIO实现文件上传的方法详解

    目录 前言 1. MinIO 简介 2. MinIO 安装 3. 整合 Spring Boot 4. 配置nginx 5. 小结 前言 现在 OSS 服务算是一个基础服务了,很多云服务厂商都有提供这样的服务,价格也不贵,松哥自己的网站用的就是类似的服务. 不过对于中小公司来说,除了购买 OSS 服务之外,也可以自己搭建专业的文件服务器,自己搭建专门的文件服务器的话,曾经比较专业的做法是 FastDFS,松哥之前也专门为之录过视频发在 B 站上,感兴趣的小伙伴可以自行查看.不过 FastDFS 搭

  • Java Spring MVC 上传下载文件配置及controller方法详解

    下载: 1.在spring-mvc中配置(用于100M以下的文件下载) <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <!--配置下载返回类型--> <bean class="or

  • IntelliJ IDEA 的 Spring 项目如何查看 @Value 的配置和值(方法详解)

    当你打开项目或者项目中的文件的时候,如果你有 Spring 的 Value 的配置,Intellij 将会自动将参数替换为值. 如果你单击上面的值,那么这个配置参数将会显示为配置的参数名. 如果你还想显示值的话,你需要重新打开这个文件或者项目. 有没有什么快捷键可以快速进行切换. 快捷键 这个配置是在 Intellij 的 Code > Folding 中进行配置的. 快捷键是是 Ctrl + NumberPad + 快捷键是是 Ctrl + NumberPad - NumberPad +,这个

  • spring boot整合jsp及设置启动页面的方法

    前言 这几天在集中学习Spring boot+Shiro框架,因为之前view层用jsp比较多,所以想在spring boot中配置jsp,但是spring boot官方不推荐使用jsp,因为jsp相对于一些模板引擎,性能都比较低,官方推荐使用thymeleaf,但是Spring boot整合jsp的过程已经完成,在这里记录一下. 本文基于springboot2.0.4最新版本 spring官方推荐Thymeleaf但是还是有很多javaweb朋友习惯使用jsp虽然现在jsp有点out.本节教程

  • spring boot整合quartz实现多个定时任务的方法

    最近收到了很多封邮件,都是想知道spring boot整合quartz如何实现多个定时任务的,由于本人生产上并没有使用到多个定时任务,这里给个实现的思路. 1.新建两个定时任务,如下: public class ScheduledJob implements Job{ @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("sched

随机推荐