springboot整合DolphinDB

pom文件

java 复制代码
<?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 https://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>3.5.10</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.mqq.dd</groupId>
	<artifactId>dolphinDB-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>dolphinDB-demo</name>
	<description>dolphinDB-demo</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<scm>
		<connection/>
		<developerConnection/>
		<tag/>
		<url/>
	</scm>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</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>
		<!-- https://mvnrepository.com/artifact/com.dolphindb/dolphindb-javaapi -->
		<dependency>
			<groupId>com.dolphindb</groupId>
			<artifactId>dolphindb-javaapi</artifactId>
			<version>3.00.2.2</version>
		</dependency>

		<dependency>
			<groupId>com.dolphindb</groupId>
			<artifactId>jdbc</artifactId>
			<version>3.00.2.2</version>
			<type>pom</type>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-enforcer-plugin</artifactId>
				<version>3.5.0</version>
				<executions>
					<execution>
						<id>enforce-java</id>
						<goals>
							<goal>enforce</goal>
						</goals>
						<configuration>
							<rules>
								<requireJavaVersion>
									<version>[17,)</version>
								</requireJavaVersion>
							</rules>
						</configuration>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<annotationProcessorPaths>
						<path>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</path>
					</annotationProcessorPaths>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

application.yml文件

java 复制代码
spring:
  application:
    name: dolphinDB-demo

dolphindb:
  host: 170.21.12.14
  port: 8858
  username: admin
  password: 123456
  connect-timeout: 5000
  database: dfs://db
  table: tb

DolphinDBConfig配置文件

java 复制代码
package com.mqq.dd.config;

import com.xxdb.DBConnection;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Configuration
public class DolphinDBConfig {

    @Value("${dolphindb.host}")
    private String host;

    @Value("${dolphindb.port}")
    private int port;

    @Value("${dolphindb.username}")
    private String username;

    @Value("${dolphindb.password}")
    private String password;

    @Bean(destroyMethod = "close")
    public DBConnection dolphinDBConnection() throws IOException {
        DBConnection dbConnection = new DBConnection();
        dbConnection.connect(host, port, username, password);
        return dbConnection;
    }
}

DolphinDbDemoApplication 启动类

java 复制代码
package com.mqq.dd;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DolphinDbDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DolphinDbDemoApplication.class, args);
	}

}

entity 实体类

java 复制代码
package com.mqq.dd.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.time.LocalDateTime;

public class TradeSummary implements Serializable {
    // 交易时间
    private LocalDateTime tradeTime;
    // 股票id
    private String securityId;
    private long totalVolumeTrade;
    private Double totalValueTrade;

    public TradeSummary() {
    }

    public TradeSummary(LocalDateTime tradeTime, String securityId, long totalVolumeTrade, Double totalValueTrade) {
        this.tradeTime = tradeTime;
        this.securityId = securityId;
        this.totalVolumeTrade = totalVolumeTrade;
        this.totalValueTrade = totalValueTrade;
    }

    public LocalDateTime getTradeTime() {
        return tradeTime;
    }

    public void setTradeTime(LocalDateTime tradeTime) {
        this.tradeTime = tradeTime;
    }

    public String getSecurityId() {
        return securityId;
    }

    public void setSecurityId(String securityId) {
        this.securityId = securityId;
    }

    public long getTotalVolumeTrade() {
        return totalVolumeTrade;
    }

    public void setTotalVolumeTrade(long totalVolumeTrade) {
        this.totalVolumeTrade = totalVolumeTrade;
    }

    public Double getTotalValueTrade() {
        return totalValueTrade;
    }

    public void setTotalValueTrade(Double totalValueTrade) {
        this.totalValueTrade = totalValueTrade;
    }
}

Controller

java 复制代码
package com.mqq.dd.controller;

import com.mqq.dd.entity.TradeSummary;
import com.mqq.dd.service.DolphinDBService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.List;

@RestController
public class DolphinDBController {

    @Autowired
    private DolphinDBService dolphinDBService;

    @GetMapping("/trades")
    public List<TradeSummary> getTrades(
            @RequestParam String securityId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime
    ) throws Exception {
        return dolphinDBService.queryTradeData(securityId, startTime, endTime);
    }

    @PostMapping("/trades")
    public void insertTrade(@RequestBody TradeSummary trade) throws Exception {
        dolphinDBService.insertTrade(trade);
    }

    @PostMapping("/trades/batch")
    public void insertTrades(@RequestBody List<TradeSummary> trades) throws Exception {
        dolphinDBService.insertTrades(trades);
    }

    @PutMapping("/trades")
    public void updateTrade(@RequestBody TradeSummary trade) throws Exception {
        dolphinDBService.updateTrade(trade);
    }

    @DeleteMapping("/trades")
    public void deleteTrade(
            @RequestParam String securityId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime tradeTime
    ) throws Exception {
        dolphinDBService.deleteTrade(securityId, tradeTime);
    }
}

Service

java 复制代码
package com.mqq.dd.service;

import com.mqq.dd.entity.TradeSummary;
import com.mqq.dd.util.DolphinDBTradeUtils;
import com.xxdb.DBConnection;
import com.xxdb.data.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class DolphinDBService {

    @Autowired
    private DBConnection connection;

    @Value("${dolphindb.database:dfs://db}")
    private String database;

    @Value("${dolphindb.table:tb}")
    private String tableName;

    /**
     * 查询某证券在指定时间范围内的成交汇总
     */
    public List<TradeSummary> queryTradeData(String securityId, LocalDateTime start, LocalDateTime end) throws Exception {

        if (securityId == null || securityId.isBlank()) {
            throw new IllegalArgumentException("securityId is blank");
        }
        if (start == null || end == null) {
            throw new IllegalArgumentException("start/end is null");
        }

        String script = ""
                + "select TradeTime, SecurityID, TotalVolumeTrade, TotalValueTrade "
                + "from loadTable('" + DolphinDBTradeUtils.escapeSingleQuoted(database) + "', '" + DolphinDBTradeUtils.escapeSingleQuoted(tableName) + "') "
                + "where SecurityID = " + DolphinDBTradeUtils.toDdbStringLiteral(securityId) + " "
                + "and TradeTime >= " + DolphinDBTradeUtils.toDdbTimestampLiteral(start) + " "
                + "and TradeTime <= " + DolphinDBTradeUtils.toDdbTimestampLiteral(end);

        Entity result = connection.run(script);
        if (!(result instanceof BasicTable)) {
            throw new RuntimeException("Query did not return a table");
        }

        BasicTable table = (BasicTable) result;
        int rows = table.rows();
        List<TradeSummary> list = new ArrayList<>();

        BasicTimestampVector timeCol = (BasicTimestampVector) table.getColumn("TradeTime");
        BasicStringVector secCol = (BasicStringVector) table.getColumn("SecurityID");
        BasicLongVector volCol = (BasicLongVector) table.getColumn("TotalVolumeTrade");
        BasicDoubleVector valCol = (BasicDoubleVector) table.getColumn("TotalValueTrade");

        for (int i = 0; i < rows; i++) {
            LocalDateTime tradeTime = timeCol.getTimestamp(i);
            String secId = secCol.getString(i);
            long volume = volCol.getLong(i);
            Double value = valCol.isNull(i) ? null : valCol.getDouble(i);

            list.add(new TradeSummary(tradeTime, secId, volume, value));
        }

        return list;
    }

    public void insertTrade(TradeSummary trade) throws Exception {
        insertTrades(List.of(trade));
    }

    public void insertTrades(List<TradeSummary> trades) throws Exception {
        if (trades == null || trades.isEmpty()) {
            return;
        }

        Entity inMemoryTable = DolphinDBTradeUtils.toTradeSummaryTable(trades);
        String script = "tableInsert{loadTable('" + DolphinDBTradeUtils.escapeSingleQuoted(database) + "', '" + DolphinDBTradeUtils.escapeSingleQuoted(tableName) + "')}";
        connection.run(script, List.of(inMemoryTable));
    }

    /**
     * Update a trade row by (SecurityID, TradeTime).
     */
    public void updateTrade(TradeSummary trade) throws Exception {
        if (trade == null) {
            throw new IllegalArgumentException("trade is null");
        }
        if (trade.getTradeTime() == null) {
            throw new IllegalArgumentException("tradeTime is null");
        }
        if (trade.getSecurityId() == null || trade.getSecurityId().isBlank()) {
            throw new IllegalArgumentException("securityId is blank");
        }

        String script = ""
                + "t=loadTable('" + DolphinDBTradeUtils.escapeSingleQuoted(database) + "', '" + DolphinDBTradeUtils.escapeSingleQuoted(tableName) + "');"
                + "update t set "
                + "TotalVolumeTrade=" + trade.getTotalVolumeTrade() + ","
                + "TotalValueTrade=" + (trade.getTotalValueTrade() == null ? "NULL" : trade.getTotalValueTrade())
                + " where SecurityID=" + DolphinDBTradeUtils.toDdbStringLiteral(trade.getSecurityId())
                + " and TradeTime=" + DolphinDBTradeUtils.toDdbTimestampLiteral(trade.getTradeTime());

        connection.run(script);
    }

    /**
     * Delete a trade row by (SecurityID, TradeTime).
     */
    public void deleteTrade(String securityId, LocalDateTime tradeTime) throws Exception {
        if (tradeTime == null) {
            throw new IllegalArgumentException("tradeTime is null");
        }
        if (securityId == null || securityId.isBlank()) {
            throw new IllegalArgumentException("securityId is blank");
        }

        String script = ""
                + "t=loadTable('" + DolphinDBTradeUtils.escapeSingleQuoted(database) + "', '" + DolphinDBTradeUtils.escapeSingleQuoted(tableName) + "');"
                + "delete from t where SecurityID=" + DolphinDBTradeUtils.toDdbStringLiteral(securityId)
                + " and TradeTime=" + DolphinDBTradeUtils.toDdbTimestampLiteral(tradeTime);

        connection.run(script);
    }

util 工具类

java 复制代码
package com.mqq.dd.util;

import com.mqq.dd.entity.TradeSummary;
import com.xxdb.data.BasicDoubleVector;
import com.xxdb.data.BasicLongVector;
import com.xxdb.data.BasicStringVector;
import com.xxdb.data.BasicTable;
import com.xxdb.data.BasicTimestampVector;
import com.xxdb.data.Entity;
import com.xxdb.data.Vector;

import java.time.LocalDateTime;
import java.util.List;

public final class DolphinDBTradeUtils {

    private DolphinDBTradeUtils() {
    }

    public static String escapeSingleQuoted(String s) {
        if (s == null) {
            return "";
        }
        return s.replace("'", "''");
    }

    /**
     * DolphinDB string literal uses double quotes.
     */
    public static String toDdbStringLiteral(String s) {
        if (s == null) {
            return "NULL";
        }
        return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
    }

    /**
     * DolphinDB TIMESTAMP literal: yyyy.MM.ddTHH:mm:ss.SSS (no quotes).
     */
    public static String toDdbTimestampLiteral(LocalDateTime t) {
        if (t == null) {
            throw new IllegalArgumentException("timestamp is null");
        }
        return String.format(
                "%04d.%02d.%02dT%02d:%02d:%02d.%03d",
                t.getYear(), t.getMonthValue(), t.getDayOfMonth(),
                t.getHour(), t.getMinute(), t.getSecond(),
                t.getNano() / 1_000_000
        );
    }

    /**
     * Build an in-memory DolphinDB table for tableInsert.
     */
    public static Entity toTradeSummaryTable(List<TradeSummary> dataList) {
        if (dataList == null) {
            throw new IllegalArgumentException("dataList is null");
        }

        int n = dataList.size();
        BasicTimestampVector timeVec = new BasicTimestampVector(n);
        BasicStringVector secVec = new BasicStringVector(n);
        BasicLongVector volVec = new BasicLongVector(n);
        BasicDoubleVector valVec = new BasicDoubleVector(n);

        for (int i = 0; i < n; i++) {
            TradeSummary t = dataList.get(i);
            if (t == null) {
                throw new IllegalArgumentException("trade is null at index " + i);
            }
            if (t.getTradeTime() == null) {
                throw new IllegalArgumentException("tradeTime is null at index " + i);
            }
            if (t.getSecurityId() == null || t.getSecurityId().isBlank()) {
                throw new IllegalArgumentException("securityId is blank at index " + i);
            }

            timeVec.setTimestamp(i, t.getTradeTime());
            secVec.setString(i, t.getSecurityId());
            volVec.setLong(i, t.getTotalVolumeTrade());
            if (t.getTotalValueTrade() == null) {
                valVec.setNull(i);
            } else {
                valVec.setDouble(i, t.getTotalValueTrade());
            }
        }

        return new BasicTable(
                List.of("TradeTime", "SecurityID", "TotalVolumeTrade", "TotalValueTrade"),
                List.<Vector>of(timeVec, secVec, volVec, valVec)
        );
    }
}
相关推荐
云边有个稻草人2 小时前
MySQL迁金仓:高兼容+自动化,国产化迁移低成本落地实战
数据库·mysql·国产数据库·kingbasees·金仓数据库·mysql迁移金仓
MrMua2 小时前
mysql与postgresql对比
数据库·mysql·postgresql
梦游人布拿拿2 小时前
【各数据库中sql复制表结构】
数据库·sql
hua872222 小时前
【Springboot3+vue3】从零到一搭建Springboot3+vue3前后端分离项目之后端环境搭建
java
不光头强2 小时前
LinkedList知识点
java
顶点多余2 小时前
Mysql --- 内置函数
数据库·mysql
beata2 小时前
Spring Boot基础-1:用5分钟搭建第一个REST API应用(含深度原理解析)
spring boot
小码哥_常2 小时前
JWT从入门到精通:一文解锁生成、验证与防篡改秘籍
后端
小码哥_常2 小时前
Spring Boot 实现分片上传+断点续传+实时进度条,彻底解决大文件上传痛点!
后端