DEV Community

Shelner
Shelner

Posted on

How to get Bitcoin data and save it in MySQL using Spring Boot

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) ); 
Enter fullscreen mode Exit fullscreen mode

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> 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 } 
Enter fullscreen mode Exit fullscreen mode

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) } 
Enter fullscreen mode Exit fullscreen mode

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(); } } } 
Enter fullscreen mode Exit fullscreen mode

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 } } 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.