Java Client

Enterprise-grade Java client for NexaDB with full Spring Boot support. Perfect for production applications requiring high performance, type safety, and seamless Spring integration.

Binary Protocol

MessagePack-based protocol for 10x faster performance than REST APIs

Spring Boot Ready

Auto-configuration and dependency injection out of the box

Auto-Reconnection

Automatic reconnection with exponential backoff for reliability

Thread-Safe

Production-ready concurrency support for high-load applications

Installation

Maven

pom.xml
<dependency>
    <groupId>com.nexadb</groupId>
    <artifactId>nexadb-java-client</artifactId>
    <version>2.3.0</version>
</dependency>

Gradle

build.gradle
implementation 'com.nexadb:nexadb-java-client:2.3.0'

Standalone Java Application

Simple Example
import com.nexadb.client.NexaClient;
import java.util.Map;
import java.util.List;

public class Example {
    public static void main(String[] args) {
        // Create and connect
        try (NexaClient client = new NexaClient("localhost", 6970, "root", "nexadb123")) {
            client.connect();

            // Create document
            Map<String, Object> user = Map.of(
                "name", "Alice",
                "email", "alice@example.com",
                "age", 28
            );
            Map<String, Object> result = client.create("users", user);
            String docId = (String) result.get("document_id");

            // Query documents
            List<Map<String, Object>> users = client.query("users",
                Map.of("age", Map.of("$gte", 18)), 10);
            System.out.println("Found " + users.size() + " users");

            // Update document
            client.update("users", docId, Map.of("age", 29));

            // Delete document
            client.delete("users", docId);
        }
    }
}

Spring Boot Integration

NexaDB provides seamless Spring Boot integration with auto-configuration. Just add the dependency and configure via properties.

Step 1: Add Dependency

pom.xml
<dependency>
    <groupId>com.nexadb</groupId>
    <artifactId>nexadb-java-client</artifactId>
    <version>2.3.0</version>
</dependency>

Step 2: Configure Properties

application.properties
# NexaDB Configuration
nexadb.host=localhost
nexadb.port=6970
nexadb.username=root
nexadb.password=nexadb123
nexadb.timeout=30000
nexadb.max-retries=3

Or use YAML format:

application.yml
nexadb:
  host: localhost
  port: 6970
  username: root
  password: nexadb123
  timeout: 30000
  max-retries: 3

Step 3: Create a Service

UserService.java
import com.nexadb.client.NexaClient;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.List;

@Service
public class UserService {

    private final NexaClient nexaClient;

    // Constructor injection
    public UserService(NexaClient nexaClient) {
        this.nexaClient = nexaClient;
    }

    public String createUser(String name, String email) {
        Map<String, Object> user = Map.of("name", name, "email", email);
        Map<String, Object> result = nexaClient.create("users", user);
        return (String) result.get("document_id");
    }

    public List<Map<String, Object>> getAllUsers() {
        return nexaClient.query("users");
    }

    public Map<String, Object> getUserById(String id) {
        return nexaClient.get("users", id);
    }

    public void updateUser(String id, Map<String, Object> updates) {
        nexaClient.update("users", id, updates);
    }

    public void deleteUser(String id) {
        nexaClient.delete("users", id);
    }
}

Step 4: Create REST Controller

UserController.java
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping
    public Map<String, String> createUser(@RequestBody Map<String, String> request) {
        String id = userService.createUser(
            request.get("name"),
            request.get("email")
        );
        return Map.of("id", id);
    }

    @GetMapping
    public List<Map<String, Object>> listUsers() {
        return userService.getAllUsers();
    }

    @GetMapping("/{id}")
    public Map<String, Object> getUser(@PathVariable String id) {
        return userService.getUserById(id);
    }

    @PutMapping("/{id}")
    public void updateUser(@PathVariable String id, @RequestBody Map<String, Object> updates) {
        userService.updateUser(id, updates);
    }

    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable String id) {
        userService.deleteUser(id);
    }
}

API Reference

CRUD Operations

// Create
Map<String, Object> result = client.create("users", Map.of("name", "Alice"));

// Read
Map<String, Object> user = client.get("users", "doc_id");

// Update
client.update("users", "doc_id", Map.of("age", 30));

// Delete
client.delete("users", "doc_id");

// Query with filters
List<Map<String, Object>> users = client.query("users",
    Map.of("age", Map.of("$gte", 25)), 10);

// Count documents
long count = client.count("users", Map.of("age", Map.of("$lt", 30)));

Query Operators

// Greater than
Map.of("age", Map.of("$gt", 25))

// Greater than or equal
Map.of("age", Map.of("$gte", 25))

// Less than
Map.of("age", Map.of("$lt", 50))

// Less than or equal
Map.of("age", Map.of("$lte", 50))

// Equal
Map.of("status", "active")

// Not equal
Map.of("status", Map.of("$ne", "deleted"))

// In array
Map.of("role", Map.of("$in", List.of("admin", "user")))

// Not in array
Map.of("role", Map.of("$nin", List.of("guest", "banned")))

Vector Search (AI/ML)

// Vector similarity search for AI/ML embeddings
double[] queryVector = new double[768];  // Your embedding vector

List<Map<String, Object>> results = client.vectorSearch("embeddings",
    queryVector, 10, 768);

for (Map<String, Object> result : results) {
    System.out.println("Similarity: " + result.get("similarity"));
    System.out.println("Document: " + result.get("document"));
}

Batch Operations

// Batch insert for better performance
List<Map<String, Object>> documents = List.of(
    Map.of("name", "Alice", "age", 28),
    Map.of("name", "Bob", "age", 32),
    Map.of("name", "Charlie", "age", 25)
);

Map<String, Object> result = client.batchWrite("users", documents);
System.out.println("Inserted: " + result.get("count"));

Change Streams (Real-Time Events)

// Watch for real-time changes (MongoDB-style)
new Thread(() -> {
    client.watch("orders", null, event -> {
        String operation = (String) event.get("operationType");
        Map<String, Object> document = (Map<String, Object>) event.get("fullDocument");

        if ("insert".equals(operation)) {
            System.out.println("New order: " + document);
            // Handle new order...
        }
    });
}).start();

Collection Management

// List all collections
List<String> collections = client.listCollections();

// Drop collection
boolean dropped = client.dropCollection("old_data");

// Get collection statistics
Map<String, Object> stats = client.getCollectionStats("users");

Error Handling

import com.nexadb.client.*;

try {
    client.create("users", Map.of("name", "Alice"));
} catch (ConnectionException e) {
    // Handle connection errors
    logger.error("Connection failed", e);
} catch (AuthenticationException e) {
    // Handle authentication errors
    logger.error("Authentication failed", e);
} catch (OperationException e) {
    // Handle operation errors
    logger.error("Operation failed", e);
} catch (NexaDBException e) {
    // Handle general NexaDB errors
    logger.error("NexaDB error", e);
}

Advanced Configuration

Builder Pattern
// Fine-grained control with Builder pattern
NexaClient client = new NexaClient.Builder()
    .host("localhost")
    .port(6970)
    .username("root")
    .password("nexadb123")
    .timeout(30000)   // 30 seconds
    .maxRetries(3)
    .build();

client.connect();

Performance Tips

1. Reuse Connections

NexaClient is thread-safe. Create once, reuse across your application. Perfect for Spring singleton beans.

2. Use Batch Operations

For bulk inserts, use batchWrite() instead of multiple create() calls for better performance.

3. Binary Protocol Advantage

The Java client uses MessagePack binary protocol, providing 10x faster performance than REST APIs.

4. Appropriate Query Limits

Only query the documents you need. Use limit parameter to avoid loading excessive data.

Requirements

  • Java 11 or higher
  • NexaDB Server 2.3.0+
  • Spring Boot 3.x (optional, for Spring integration)

Resources