Spring Boot 整合 StringRedisTemplate + JestClient + JPA

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.blockchaindata.stockmarketcommon.domain.BaseModel;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.core.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;

/**
 * @author Andon
 * @date 2019/2/21
 */
@Service
public class EsService {

    private static final Logger LOG = LoggerFactory.getLogger(EsService.class);

    private JestClient jestClient;
    @Value("${uris}")
    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();
    }
    /**
     * 發送json查詢
     */
    SearchResult jsonSearch(String json, String indexName, String typeName) {
        Search search = new Search.Builder(json).addIndex(indexName).addType(typeName).build();
        try {
            return jestClient.execute(search);
        } catch (Exception e) {
            LOG.warn("index:{}, type:{}, search again!! error = {}", indexName, typeName, e.getMessage());
            sleep(100);
            return jsonSearch(json, indexName, typeName);
        }
    }

    /**
     * 批量寫入
     */
    public <T extends BaseModel> void bulkIndex(List<T> list, String indexName) {
        Bulk.Builder bulk = new Bulk.Builder();
        for (T o : list) {
            Index index = new Index.Builder(o).id(o.getPK()).index(indexName).type(o.getType()).build();
            bulk.addAction(index);
        }
        try {
            jestClient.execute(bulk.build());
        } catch (IOException e) {
            LOG.warn("bulkIndex again!! error={} index={}", e.getMessage(), indexName);
            sleep(100);
            bulkIndex(list, indexName);
        }
    }

    /**
     * 新增或者更新文檔
     */
    public <T> void insertOrUpdateDocumentById(T o, String index, String type, String uniqueId) {
        Index.Builder builder = new Index.Builder(o);
        builder.id(uniqueId);
        builder.refresh(true);
        Index indexDoc = builder.index(index).type(type).build();
        try {
            jestClient.execute(indexDoc);
        } catch (IOException e) {
            LOG.warn("insertOrUpdateDocumentById again!! error={} id={}", e.getMessage(), uniqueId);
            sleep(100);
            insertOrUpdateDocumentById(o, index, type, uniqueId);
        }
    }

    /**
     * 根據主鍵id刪除文檔
     */
    public void deleteDocumentById(String index, String type, String id) {
        Delete delete = new Delete.Builder(id).index(index).type(type).build();
        try {
            jestClient.execute(delete);
        } catch (IOException e) {
            LOG.warn("deleteDocumentById again!! error={} id={}", e.getMessage(), id);
            sleep(100);
            deleteDocumentById(index, type, id);
        }
    }

    /**
     * 根據主鍵id獲取文檔
     */
    public <T> T getDocumentById(T object, String index, String id) {
        Get get = new Get.Builder(index, id).build();
        T o = null;
        try {
            JestResult result = jestClient.execute(get);
            o = (T) result.getSourceAsObject(object.getClass());
        } catch (IOException e) {
            LOG.warn("getDocumentById again!! error={} id=");
            sleep(100);
            getDocumentById(object, index, id);
        }
        return o;
    }

    private void sleep(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            LOG.error("Thread sleep failure!! error={}", e.getMessage());
        }
    }

}

三、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://##.###.###.###:###

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章