Spring Boot 整合 StringRedisTemplate + JestClient + JPA
GitHub: link. 欢迎star
注意:本篇博客风格(不多比比就是撸代码!!!)
一、Spring Boot 整合 Redis (StringRedisTemplate)
1.maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
2.RedisConfig.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
/**
* @author Andon
* @date 2019/2/20
*/
@Configuration
public class RedisConfig {
/**
* 注入 RedisConnectionFactory
*/
@Autowired
RedisConnectionFactory redisConnectionFactory;
/**
* 实例化 StringRedisTemplate 对象
*/
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(factory);
return stringRedisTemplate;
}
/**
* 实例化 HashOperations 对象,可以使用 Hash 类型操作
*/
@Bean
public HashOperations<String, String, String> hashOperations(StringRedisTemplate stringRedisTemplate) {
return stringRedisTemplate.opsForHash();
}
/**
* 实例化 ValueOperations 对象,可以使用 String 操作
*/
@Bean
public ValueOperations<String, String> valueOperations(StringRedisTemplate stringRedisTemplate) {
return stringRedisTemplate.opsForValue();
}
/**
* 实例化 ListOperations 对象,可以使用 List 操作
*/
@Bean
public ListOperations<String, String> listOperations(StringRedisTemplate stringRedisTemplate) {
return stringRedisTemplate.opsForList();
}
/**
* 实例化 SetOperations 对象,可以使用 Set 操作
*/
@Bean
public SetOperations<String, String> setOperations(StringRedisTemplate stringRedisTemplate) {
return stringRedisTemplate.opsForSet();
}
/**
* 实例化 ZSetOperations 对象,可以使用 ZSet 操作
*/
@Bean
public ZSetOperations<String, String> zSetOperations(StringRedisTemplate stringRedisTemplate) {
return stringRedisTemplate.opsForZSet();
}
}
3.RedisService.java
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @author Andon
* @date 2019/5/15
*/
@Service
public class RedisService {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private HashOperations<String, String, String> hashOperations;
@Resource
private SetOperations<String, Object> setOperations;
/**
* 设置超时时间
*
* @param key key
* @param expire 过期时间(单位:秒)
*/
public void expireKey(String key, long expire) {
stringRedisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
/**
* hash操作
*/
public void addHashValue(String key, String field, String value) {
hashOperations.put(key, field, value);
}
public void deleteHashValue(String key, String field) {
hashOperations.delete(key, field);
}
public void deleteHashKey(String key) {
hashOperations.delete(key);
}
public String getHashValue(String key, String field) {
return hashOperations.get(key, field);
}
public List<String> getHashValues(String key) {
return hashOperations.values(key);
}
public Set<String> getHashFields(String key) {
return hashOperations.keys(key);
}
public Map<String, String> getHashFieldsValues(String key){
return hashOperations.entries(key);
}
public boolean isHashFieldExists(String key, String field) {
return hashOperations.hasKey(key, field);
}
public void emptyHashKey(String key) {
Set<String> set = hashOperations.keys(key);
set.forEach(field -> hashOperations.delete(key, field));
}
/**
* set操作
*/
public void addSetValue(String key, Object value) {
setOperations.add(key, value);
}
public void addSetValues(String key, Object[] set) {
setOperations.add(key, set);
}
public void deleteSetValue(String key, Object value) {
setOperations.remove(key, value);
}
public void deleteSetValue(String key, Object[] value) {
setOperations.remove(key, value);
}
public Set<Object> getSetValues(String key) {
return setOperations.members(key);
}
}
二、Spring Boot 整合 ElasticSearch5.6.9 (JestClient)
1.maven
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>5.6.9</version>
</dependency>
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>5.3.4</version>
</dependency>
2.EsService.java
import com.alibaba.fastjson.JSONObject;
import com.blockchaindata.stockmarketcommon.domain.BaseModel;
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.*;
import io.searchbox.indices.CreateIndex;
import io.searchbox.indices.DeleteIndex;
import io.searchbox.indices.mapping.GetMapping;
import io.searchbox.indices.mapping.PutMapping;
import io.searchbox.indices.settings.GetSettings;
import io.searchbox.indices.settings.UpdateSettings;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author Andon
* 2021/01/27
*/
@Slf4j
@Service
public class EsService {
private JestClient jestClient;
@Value("${elasticsearch.uris.http}")
private String url;
@PostConstruct
public void init() {
List<String> uris = Arrays.asList(url.split(","));
JestClientFactory jestClientFactory = new JestClientFactory();
jestClientFactory.setHttpClientConfig(new HttpClientConfig
.Builder(uris)
.connTimeout(10000)
.readTimeout(10000)
.maxConnectionIdleTime(1500L, TimeUnit.MILLISECONDS)
.multiThreaded(true)
.build());
jestClient = jestClientFactory.getObject();
}
/**
* 创建索引index
*/
public void createIndex(String indexName) {
try {
JestResult jestResult = jestClient.execute(new CreateIndex.Builder(indexName).build());
log.info("createIndex indexName:{} state:{}", indexName, jestResult.isSucceeded());
} catch (IOException e) {
log.error("createIndex failure!! indexName:{} error={}", indexName, e.getMessage());
e.printStackTrace();
}
}
/**
* 删除索引index
*/
public void deleteIndex(String indexName) {
try {
JestResult result = jestClient.execute(new DeleteIndex.Builder(indexName).build());
log.info("deleteIndex indexName:{} state:{}", indexName, result.isSucceeded());
} catch (Exception e) {
log.error("deleteIndex failure!! indexName:{} error={}", indexName, e.getMessage());
e.printStackTrace();
}
}
/**
* 创建索引index的映射mapping
*
* @param mapping json格式的映射mappings
*/
public void createIndexMappings(String indexName, String typeName, String mapping) {
try {
JestResult result;
if (ObjectUtils.isEmpty(typeName)) {
result = jestClient.execute(new PutMapping.Builder(indexName, indexName, mapping).build());
} else {
result = jestClient.execute(new PutMapping.Builder(indexName, typeName, mapping).build());
}
log.info("createIndexMappings indexName:{} typeName:{} mapping:{} state:{}", indexName, typeName, mapping, result.isSucceeded());
} catch (Exception e) {
log.error("createIndexMappings failure!! indexName:{} typeName:{} mapping:{} error{}", indexName, typeName, mapping, e.getMessage());
e.printStackTrace();
}
}
/**
* 获取索引index的映射mappings
*/
public String getIndexMappings(String indexName, String typeName) {
try {
JestResult result;
if (ObjectUtils.isEmpty(typeName)) {
result = jestClient.execute(new GetMapping.Builder().addIndex(indexName).build());
} else {
result = jestClient.execute(new GetMapping.Builder().addIndex(indexName).addType(typeName).build());
}
log.info("getIndexMappings indexName:{} typeName:{} state:{}", indexName, typeName, result.isSucceeded());
String jsonString = result.getJsonString();
JSONObject jsonObject = JSONObject.parseObject(jsonString);
return jsonObject.getJSONObject(indexName).getJSONObject("mappings").toJSONString();
} catch (IOException e) {
log.error("getIndexMappings failure!! indexName:{} typeName:{} error={}", indexName, typeName, e.getMessage());
e.printStackTrace();
}
return null;
}
/**
* 获取索引index的设置settings
*/
public String getIndexSettings(String indexName) {
try {
JestResult result = jestClient.execute(new GetSettings.Builder().addIndex(indexName).build());
log.info("getIndexSettings indexName:{} state:{}", indexName, result.isSucceeded());
String jsonString = result.getJsonString();
JSONObject jsonObject = JSONObject.parseObject(jsonString);
return jsonObject.getJSONObject(indexName).getJSONObject("settings").toJSONString();
} catch (IOException e) {
log.error("getIndexSettings failure!! indexName:{} error={}", indexName, e.getMessage());
e.printStackTrace();
}
return null;
}
/**
* 修改索引index的设置settings
*
* @param settings json格式的设置settings(传值示例:{"max_result_window":"200000000"})
*/
public void updateIndexSettings(String indexName, String settings) {
try {
JestResult jestResult = jestClient.execute(new UpdateSettings.Builder(settings).addIndex(indexName).build());
log.info("updateIndexSettings indexName:{} settings:{} state:{}", indexName, settings, jestResult.isSucceeded());
} catch (Exception e) {
log.error("updateIndexSettings failure!! indexName:{} settings:{} error={}", indexName, settings, e.getMessage());
e.printStackTrace();
}
}
/**
* SearchSourceBuilder进行查询
*/
public SearchResult searchSource(String indexName, String typeName, SearchSourceBuilder searchSourceBuilder) {
try {
String searchSourceBuilderStr = searchSourceBuilder.toString();
if (ObjectUtils.isEmpty(typeName)) {
Search search = new Search.Builder(searchSourceBuilderStr).addIndex(indexName).build();
return jestClient.execute(search);
} else {
Search search = new Search.Builder(searchSourceBuilderStr).addIndex(indexName).addType(typeName).build();
return jestClient.execute(search);
}
} catch (IOException e) {
log.error("searchSource failure!! indexName:{} typeName:{} error={}", indexName, typeName, e.getMessage());
e.printStackTrace();
return null;
}
}
/**
* 发送json查询
*/
SearchResult jsonSearch(String indexName, String typeName, String json) {
try {
if (ObjectUtils.isEmpty(typeName)) {
return jestClient.execute(new Search.Builder(json).addIndex(indexName).build());
} else {
return jestClient.execute(new Search.Builder(json).addIndex(indexName).addType(typeName).build());
}
} catch (Exception e) {
log.error("jsonSearch failure!! indexName:{} typeName:{} json:{} error={}", indexName, typeName, json, e.getMessage());
e.printStackTrace();
return null;
}
}
/**
* 批量写入
*/
public <T extends BaseModel> void bulkIndex(String indexName, Collection<T> collection) {
try {
Bulk.Builder bulk = new Bulk.Builder();
for (T o : collection) {
Index index;
if (ObjectUtils.isEmpty(o.getType())) {
index = new Index.Builder(o).id(o.getPK()).index(indexName).type(indexName).build();
} else {
index = new Index.Builder(o).id(o.getPK()).index(indexName).type(o.getType()).build();
}
bulk.addAction(index);
}
jestClient.execute(bulk.build());
log.info("bulkIndex >> indexName:{} collection.size={}", indexName, collection.size());
} catch (IOException e) {
log.error("bulkIndex failure!! indexName:{} error:{} ", indexName, e.getMessage());
e.printStackTrace();
}
}
/**
* 新增或者更新文档
*/
public <T> void insertOrUpdateDocumentById(String indexName, String typeName, String id, T o) {
try {
Index.Builder builder = new Index.Builder(o).id(id).refresh(true);
Index index;
if (ObjectUtils.isEmpty(typeName)) {
index = builder.index(indexName).type(indexName).build();
} else {
index = builder.index(indexName).type(typeName).build();
}
jestClient.execute(index);
} catch (IOException e) {
log.error("insertOrUpdateDocumentById failure!! indexName:{} typeName:{} id={} error={}", indexName, typeName, id, e.getMessage());
e.printStackTrace();
}
}
/**
* 根据主键id删除文档
*/
public void deleteDocumentById(String indexName, String typeName, String id) {
try {
if (ObjectUtils.isEmpty(typeName)) {
jestClient.execute(new Delete.Builder(id).index(indexName).build());
} else {
jestClient.execute(new Delete.Builder(id).index(indexName).type(typeName).build());
}
} catch (IOException e) {
log.error("deleteDocumentById failure!! indexName:{} typeName:{} id={} error={}", indexName, typeName, id, e.getMessage());
e.printStackTrace();
}
}
/**
* 根据主键id获取文档
*/
public <T> T getDocumentById(String indexName, String id, T object) {
try {
JestResult result = jestClient.execute(new Get.Builder(indexName, id).build());
return (T) result.getSourceAsObject(object.getClass(), false);
} catch (IOException e) {
log.error("getDocumentById failure!! indexName:{} id={} error={}", indexName, id, e.getMessage());
e.printStackTrace();
}
return null;
}
}
3.BaseModel.java
import java.io.Serializable;
/**
* @author Andon
* 2019/5/27
*/
public abstract class BaseModel implements Serializable {
public abstract String getPK();
public abstract String getType();
}
三、Spring Boot 整合 MySQL(SpringDataJPA)
1.maven依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2.domain实体类
import javax.persistence.*;
import java.io.Serializable;
/**
* @author Andon
* @date 2019/2/20
*/
@Entity
@Table(name = "stock_security")
public class StockInformation implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) //id自动增长
@Column(name = "id")
private int id; //id
@Column(name = "stock_code")
private String stockCode; //股票代码
@Column(name = "stock_display_name")
private String stockDisplayName; //股票名称
@Column(name = "stock_name")
private String stockName; //股票拼音缩写(大写)
@Column(name = "start_date")
private String startDate; //上市时间:2019-02-18 14:57:00
@Column(name = "end_date")
private String endDate; //退市时间:2200-01-01 0:00:00
@Column(name = "type")
private String type; //标的类型
@Column(name = "pe_ratio")
private String peRatio; //市盈率
@Column(name = "turnover_ratio")
private String turnoverRatio; //换手率
@Column(name = "pb_ratio")
private String pbRatio; //市净率
@Column(name = "ps_ratio")
private String psRatio; //市销率
@Column(name = "pcf_ratio")
private String pcfRatio; //市现率
@Column(name = "capitalization")
private String capitalization; //总股本
@Column(name = "market_cap")
private String marketCap; //总市值
@Column(name = "circulating_cap")
private String circulatingCap; //流通股本
@Column(name = "circulating_market_cap")
private String circulatingMarketCap; //流通市值
@Column(name = "day")
private String day; //日期
@Column(name = "pe_ratio_lyr")
private String peRatioLyr; //市盈率
/**
* getter/setter 省略
*/
}
3.StockInformationRepository.java
import com.blockchaindata.stockmarketmacdcalculate.domain.StockInformation;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author Andon
* @date 2019/2/20
*/
@Repository
public interface StockInformationRepository extends JpaRepository<StockInformation, Integer> {
List<StockInformation> findAllByEndDateAfter(String endTime);
@Query(value = "SELECT stockCode FROM StockInformation WHERE endDate > ?1")
List<String> findAllStockCodeAfter(String endTime);
@Query(nativeQuery = true, value = "SELECT stock_code FROM stock_finance")
List<String> findAllStockCodeOfDividend();
@Query(nativeQuery = true, value = "SELECT COUNT(id) FROM stock_trade_day WHERE trade_day = ?1")
int nowIsItCurrentlyTradingDay(String nowTime);
@Modifying //修改表数据
@Query(nativeQuery = true, value = "INSERT INTO stock_suspension(stock_code) VALUES (?1)")
int insertSuspensionStockCode(String stockCode);
@Modifying
@Query(nativeQuery = true, value = "DELETE FROM sector_stock WHERE stock_code NOT IN (SELECT stock_code FROM stock_security)")
int deleteAllInvalidStockCodeOfSectorStock();
@Modifying
@Query(nativeQuery = true, value = "TRUNCATE TABLE concept_sector")
int deleteAllConceptSector();
@Query(nativeQuery = true, value = "SELECT stock_code AS code, stock_name AS name, stock_display_name AS displayName FROM stock_security WHERE stock_code IN (SELECT stock_code FROM stock_calculated)")
List<Map<String, String>> findAllStockCodeInfoOfCalculated();
@Query(nativeQuery = true, value = "SELECT DISTINCT(stock_code) FROM stock_calculated WHERE stock_code NOT IN (SELECT stock_code FROM stock_suspension)")
List<String> findAllStockCodeOfCalculatedAndNoSuspension();
@Query(nativeQuery = true, value = "SELECT * FROM (SELECT code AS sectorCode, name AS sectorName FROM custom_sector UNION SELECT code AS sectorCode, name AS sectorName FROM concept_sector UNION SELECT code AS sectorCode, name AS sectorName FROM industry_sector) AS tableA \n" +
"WHERE tableA.sectorName LIKE ?3 LIMIT ?1,?2")
List<Map<String, String>> findAllSectorInfo(int row, int size, String sectorName);
}
四、application.yml
#server:
# port: 8888
spring:
main:
web-application-type: none
datasource:
url: ######:3306/block?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8&autoReconnect=true&failOverReadOnly=false
username: ######
password: ######
driver-class-name: com.mysql.jdbc.Driver
hikari:
read-only: false
connection-timeout: 60000
idle-timeout: 60000
validation-timeout: 3000
max-lifetime: 60000
login-timeout: 5
maximum-pool-size: 60
minimum-idle: 10
jpa:
generate-ddl: false
show-sql: true
hibernate:
ddl-auto: none
database: mysql
open-in-view: true
redis:
host: ##.###.###.#
port: 6379
password: ######
elasticsearch:
jest:
uris: http://##.###.###.###:###,http://##.###.###.###:###,http://##.###.###.###:###,http://##.###.###.###:###,http://##.###.###.###:###
elasticsearch:
uris:
http: http://##.###.###.###:###,http://##.###.###.###:###,http://##.###.###.###:###,http://##.###.###.###:###,http://##.###.###.###:###
redis:
key:
macdSignal: stock_market_macd_signaling
es:
index:
macdData: stock_market_macd_data
macdSignal: stock_market_macd_result
macdExpectedPrice: stock_market_macd_expected_price
macdResonance: stock_market_macd_resonance
kLineDifference_4: 4
kLineDifference_7: 7
email:
address:
GitHub: link. 欢迎star