Reference
GMO Coin API Documentation
Preparation
Build MySQL Database and Table;
Example:
CREATE DATABASE IF NOT EXISTS coin_db;
USE coin_db;
CREATE TABLE IF NOT EXISTS btc_klines (
id INT AUTO_INCREMENT PRIMARY KEY,
open_time TIMESTAMP,
open DECIMAL(20, 8),
high DECIMAL(20, 8),
low DECIMAL(20, 8),
close DECIMAL(20, 8),
volume DECIMAL(20, 8)
);
Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20240303</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Step-by-Step JPA Implementation
1. application.properties
This is configures DB connection.
# URL to connect to MySQL, including port and database name
spring.datasource.url=jdbc:mysql://localhost:3306/coin_db
# Username for the MySQL database
spring.datasource.username=your_username
# Password for the MySQL database
spring.datasource.password=your_password
# Automatically Creates/updates tables based on entity definitions
spring.jpa.hibernate.ddl-auto=update
2. Kline.java
(Entity)
import jakarta.persistence.*;
import java.math.BigDecimal;
import java.sql.Timestamp;
@Entity
@Table(name = "btc_klines")
public class Kline {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "open_time")
private Timestamp openTime;
private BigDecimal open;
private BigDecimal high;
private BigDecimal low;
private BigDecimal close;
private BigDecimal volume;
// Getters and Setters
}
3. KlineRepository.java
// This interface allows us to perform basic CRUD operations without implementing them manually
import org.springframework.data.jpa.repository.JpaRepository;
// This is the repository (data access layer) for the `Kline` entity
// It inherits method like save, findAll, findById, deleteById, etc.
public interface KlineRepository extends JpaRepository<Kline, Long> {
// JpaRepository<T, ID>:
// - T is the Entity type (Kline)
// - ID is the type of the primary key (long)
}
4. KlineService.java
import org.json.JSONArray; // For parsing arrays in JSON response
import org.json.JSONObject; // For parsing the full JSON object
import org.springframework.stereotype.Service; // Marks this class as a Spring service component
import java.math.BigDecimal; // Used for precise decimal values (e.g., cryptocurrency prices)
import java.net.HttpURLConnection; // For sending HTTP requests
import java.net.URL; // For defining the endpoint
import java.io.BufferedReader; // For reading the response steam line by line
import java.io.InputStreamReader; // Converts byte stream into character stream
import java.sql.Timestamp; // Used to store time (in MySQL) from epoch
// Tells Spring to register this class as a service in the application context
@Service
public class KlineService {
// Reference to the repository to save data into MySQL
private final KlineRepository repository;
// Constructor Injection: Spring injects the repository into this service
public KlineService(KlineRepository repository) {
this.repository = repository;
}
// this method fetches data from the API and saves each record into the database
public void fetchAndSave() {
try {
// Create a URL object with the API endpoint
URL url = new URL("https://api.coin.z.com/public/v1/klines?symbol=BTC&interval=1min&date=20210417");
// Open a connection and cast it to HttpURLConnection to configure the request
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// Set the request method to GET (read-only)
conn.setRequestMethod("GET");
// Prepare to read the API response from the input stream
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
// Append each line of response into one string using StringBuilder
StringBuilder jsonBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) // Keep reading until end of stream
jsonBuilder.append(line);
// Convert the entire response into a JSON object
JSONObject response = new JSONObject(jsonBuilder.toString());
// Extract the "data" array from the JSON response
JSONArray data = response.getJSONArray("data");
// Iterate over each object inside the data array
for (int i = 0; i < data.length(); i++) {
JSONObject obj = data.getJSONObject(i); // Get each kline entry
Kline kline = new Kline(); // Create a new instance of the entry
// Convert string epoch to Timestamp
kline.setOpenTime(new Timestamp(Long.parseLong(obj.getString("openTime"))));
// Parse strings to BigDecimal for financial precision
kline.setOpen(new BigDecimal(obj.getString("open")));
kline.setHigh(new BigDecimal(obj.getString("high")));
kline.setLow(new BigDecimal(obj.getString("low")));
kline.setClose(new BigDecimal(obj.getString("close")));
kline.setVolume(new BigDecimal(obj.getString("volume")));
// Save each Kline record to the database
repository.save(kline);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
5. Application.java
import org.springframework.boot.CommandLineRunner; // Used to run code after the application starts
import org.springframework.boot.SpringApplication; // Class used to launch the application
import org.springframework.boot.autoconfigure.SpringBootApplication; // Enables Spring Boot auto-configuration
// Combines @Configuration, @EnableAutoConfiguration, and @aComponentScan
@SpringBootApplication
public class Application implements CommandLineRunner {
private final KlineService klineService; // Inject the service that fetches and saves data
// Constructor Injection for the KlineService
public Application(KlineService klineService) {
this.klineService = klineService;
}
public static void main(String[] args) {
// Launch the Spring Boot app
SpringApplication.run(Application.class, args);
}
// This method runs immediately after the app starts
@Override
public void run(String... args) {
klineService.fetchAndSave(); // Trigger the data fetch and save process once at startup
}
}
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.