Java & Spring Boot Integration
This guide covers connecting to every WeftKit engine from Java. All examples use standard, widely-available drivers and frameworks — no WeftKit-specific SDK is required. Point your existing driver at weftkit-standalone and your existing application code works as-is.
Prerequisites
Add the following dependencies to your project. Pick the sections relevant to the engines you are using.
Maven (pom.xml)
xml<!-- WeftKitRel — PostgreSQL JDBC --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.7.3</version> </dependency> <!-- WeftKitRel — Spring Boot + Spring Data JDBC --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jdbc</artifactId> </dependency> <!-- WeftKitRel — Hibernate / JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- WeftKitDoc — MongoDB Java Driver (sync) --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver-sync</artifactId> <version>5.1.0</version> </dependency> <!-- WeftKitDoc — Spring Data MongoDB --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <!-- WeftKitMem — Jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>5.1.2</version> </dependency> <!-- WeftKitMem — Lettuce (async) --> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>6.3.2.RELEASE</version> </dependency> <!-- WeftKitMem — Spring Data Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- WeftKitGraph — Neo4j Java Driver --> <dependency> <groupId>org.neo4j.driver</groupId> <artifactId>neo4j-java-driver</artifactId> <version>5.21.0</version> </dependency> <!-- WeftKitKV — AWS SDK for Java v2 (DynamoDB) --> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>dynamodb</artifactId> <version>2.25.60</version> </dependency>
Gradle (build.gradle)
groovydependencies { // WeftKitRel — PostgreSQL JDBC implementation 'org.postgresql:postgresql:42.7.3' // WeftKitRel — Spring Boot Data JDBC implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' // WeftKitRel — Hibernate / JPA implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // WeftKitDoc — MongoDB Java Driver implementation 'org.mongodb:mongodb-driver-sync:5.1.0' // WeftKitDoc — Spring Data MongoDB implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' // WeftKitMem — Jedis implementation 'redis.clients:jedis:5.1.2' // WeftKitMem — Lettuce implementation 'io.lettuce:lettuce-core:6.3.2.RELEASE' // WeftKitMem — Spring Data Redis implementation 'org.springframework.boot:spring-boot-starter-data-redis' // WeftKitGraph — Neo4j Java Driver implementation 'org.neo4j.driver:neo4j-java-driver:5.21.0' // WeftKitKV — AWS SDK v2 DynamoDB implementation 'software.amazon.awssdk:dynamodb:2.25.60' }
WeftKitRel — PostgreSQL via JDBC
WeftKitRel speaks the PostgreSQL v3 wire protocol, so the standard PostgreSQL JDBC driver connects without any modification.
Default port: 5432
Basic Connection and Query
javaimport java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class RelExample { private static final String URL = "jdbc:postgresql://localhost:5432/mydb"; private static final String USER = "app_user"; private static final String PASS = "secret"; public static void main(String[] args) throws ClassNotFoundException { // Load driver explicitly (optional with JDBC 4+) Class.forName("org.postgresql.Driver"); // Try-with-resources closes the connection automatically try (Connection conn = DriverManager.getConnection(URL, USER, PASS)) { // --- INSERT with PreparedStatement (always use ? placeholders) --- String insertSql = "INSERT INTO products (name, price, stock) VALUES (?, ?, ?)"; try (PreparedStatement ps = conn.prepareStatement(insertSql)) { ps.setString(1, "Widget Pro"); ps.setDouble(2, 29.99); ps.setInt(3, 250); int rowsInserted = ps.executeUpdate(); System.out.println("Inserted: " + rowsInserted + " row(s)"); } // --- SELECT with ResultSet iteration --- String selectSql = "SELECT id, name, price FROM products WHERE price < ? ORDER BY price"; try (PreparedStatement ps = conn.prepareStatement(selectSql)) { ps.setDouble(1, 50.00); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { long id = rs.getLong("id"); String name = rs.getString("name"); double price = rs.getDouble("price"); System.out.printf(" [%d] %s — $%.2f%n", id, name, price); } } } } catch (SQLException e) { System.err.println("Database error: " + e.getMessage()); } } }
Transaction Management
javaimport java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class TransactionExample { public static void transferFunds(long fromId, long toId, double amount) throws SQLException { try (Connection conn = DriverManager.getConnection( "jdbc:postgresql://localhost:5432/mydb", "app_user", "secret")) { // Disable auto-commit to open a manual transaction conn.setAutoCommit(false); try { String debit = "UPDATE accounts SET balance = balance - ? WHERE id = ?"; try (PreparedStatement ps = conn.prepareStatement(debit)) { ps.setDouble(1, amount); ps.setLong(2, fromId); ps.executeUpdate(); } String credit = "UPDATE accounts SET balance = balance + ? WHERE id = ?"; try (PreparedStatement ps = conn.prepareStatement(credit)) { ps.setDouble(1, amount); ps.setLong(2, toId); ps.executeUpdate(); } conn.commit(); System.out.println("Transfer committed successfully."); } catch (SQLException e) { conn.rollback(); System.err.println("Transfer rolled back: " + e.getMessage()); throw e; } } } }
WeftKitRel — Spring Boot + Spring Data JDBC
application.properties
propertiesspring.datasource.url=jdbc:postgresql://localhost:5432/mydb spring.datasource.username=app_user spring.datasource.password=secret spring.datasource.driver-class-name=org.postgresql.Driver
application.yml (alternative)
yamlspring: datasource: url: jdbc:postgresql://localhost:5432/mydb username: app_user password: secret driver-class-name: org.postgresql.Driver
JdbcTemplate
javaimport org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import java.util.List; import java.util.Map; @Repository public class ProductRepository { private final JdbcTemplate jdbc; // Spring injects the JdbcTemplate bean backed by the configured DataSource public ProductRepository(JdbcTemplate jdbc) { this.jdbc = jdbc; } // --- SELECT returning a list of maps --- public List<Map<String, Object>> findCheapProducts(double maxPrice) { return jdbc.queryForList( "SELECT id, name, price FROM products WHERE price < ? ORDER BY price", maxPrice ); } // --- SELECT returning a single scalar value --- public int countProducts() { Integer count = jdbc.queryForObject( "SELECT COUNT(*) FROM products", Integer.class ); return count != null ? count : 0; } // --- SELECT mapping rows to a POJO --- public List<Product> findByCategory(String category) { return jdbc.query( "SELECT id, name, price FROM products WHERE category = ?", (rs, rowNum) -> new Product( rs.getLong("id"), rs.getString("name"), rs.getDouble("price") ), category ); } // --- INSERT / UPDATE / DELETE --- public int createProduct(String name, double price) { return jdbc.update( "INSERT INTO products (name, price) VALUES (?, ?)", name, price ); } public int updatePrice(long id, double newPrice) { return jdbc.update( "UPDATE products SET price = ? WHERE id = ?", newPrice, id ); } }
WeftKitRel — Hibernate / JPA
persistence.xml
xml<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="https://jakarta.ee/xml/ns/persistence" version="3.0"> <persistence-unit name="weftkit-pu" transaction-type="RESOURCE_LOCAL"> <properties> <property name="jakarta.persistence.jdbc.driver" value="org.postgresql.Driver"/> <property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/mydb"/> <property name="jakarta.persistence.jdbc.user" value="app_user"/> <property name="jakarta.persistence.jdbc.password" value="secret"/> <!-- Schema management — use "validate" or "none" in production --> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> <property name="hibernate.show_sql" value="false"/> </properties> </persistence-unit> </persistence>
Entity Class
javaimport jakarta.persistence.*; @Entity @Table(name = "orders") @NamedQuery( name = "Order.findByStatus", query = "SELECT o FROM Order o WHERE o.status = :status ORDER BY o.createdAt DESC" ) public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "customer_id", nullable = false) private Long customerId; @Column(name = "total_amount", nullable = false) private Double totalAmount; @Column(name = "status", length = 32) private String status; @Column(name = "created_at", updatable = false) private java.time.LocalDateTime createdAt; // Standard constructors, getters, and setters public Order() {} public Order(Long customerId, Double totalAmount, String status) { this.customerId = customerId; this.totalAmount = totalAmount; this.status = status; this.createdAt = java.time.LocalDateTime.now(); } public Long getId() { return id; } public Long getCustomerId() { return customerId; } public Double getTotalAmount() { return totalAmount; } public String getStatus() { return status; } public void setStatus(String s) { this.status = s; } }
EntityManager Operations
javaimport jakarta.persistence.*; import java.util.List; public class OrderDao { private final EntityManagerFactory emf = Persistence.createEntityManagerFactory("weftkit-pu"); // --- Persist (INSERT) --- public Order create(Long customerId, Double amount) { EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); try { Order order = new Order(customerId, amount, "pending"); em.persist(order); em.getTransaction().commit(); return order; } catch (Exception e) { em.getTransaction().rollback(); throw e; } finally { em.close(); } } // --- Find by primary key --- public Order findById(Long id) { EntityManager em = emf.createEntityManager(); try { return em.find(Order.class, id); // returns null if not found } finally { em.close(); } } // --- Merge (UPDATE) --- public Order updateStatus(Long id, String newStatus) { EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); try { Order order = em.find(Order.class, id); if (order == null) throw new IllegalArgumentException("Order not found: " + id); order.setStatus(newStatus); Order merged = em.merge(order); em.getTransaction().commit(); return merged; } catch (Exception e) { em.getTransaction().rollback(); throw e; } finally { em.close(); } } // --- Remove (DELETE) --- public void delete(Long id) { EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); try { Order order = em.find(Order.class, id); if (order != null) em.remove(order); em.getTransaction().commit(); } catch (Exception e) { em.getTransaction().rollback(); throw e; } finally { em.close(); } } // --- JPQL query --- public List<Order> findByStatus(String status) { EntityManager em = emf.createEntityManager(); try { return em.createQuery( "SELECT o FROM Order o WHERE o.status = :status ORDER BY o.createdAt DESC", Order.class ) .setParameter("status", status) .getResultList(); } finally { em.close(); } } // --- Named query --- public List<Order> findByStatusNamed(String status) { EntityManager em = emf.createEntityManager(); try { return em.createNamedQuery("Order.findByStatus", Order.class) .setParameter("status", status) .getResultList(); } finally { em.close(); } } }
WeftKitRel — Spring Data JPA
application.properties
propertiesspring.datasource.url=jdbc:postgresql://localhost:5432/mydb spring.datasource.username=app_user spring.datasource.password=secret spring.jpa.hibernate.ddl-auto=validate spring.jpa.show-sql=false spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
Repository Interface
javaimport org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Optional; @Repository public interface OrderRepository extends JpaRepository<Order, Long> { // Spring Data derives the query from the method name List<Order> findByStatus(String status); List<Order> findByCustomerIdOrderByCreatedAtDesc(Long customerId); Optional<Order> findTopByCustomerIdAndStatus(Long customerId, String status); // Custom JPQL query @Query("SELECT o FROM Order o WHERE o.totalAmount BETWEEN :min AND :max") List<Order> findByAmountRange(@Param("min") double min, @Param("max") double max); // Modifying query for bulk updates @Modifying @Transactional @Query("UPDATE Order o SET o.status = :newStatus WHERE o.status = :oldStatus") int bulkUpdateStatus(@Param("oldStatus") String oldStatus, @Param("newStatus") String newStatus); }
Service Using the Repository
javaimport org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @Transactional(readOnly = true) public class OrderService { private final OrderRepository orders; public OrderService(OrderRepository orders) { this.orders = orders; } public List<Order> getPendingOrders() { return orders.findByStatus("pending"); } @Transactional public Order placeOrder(Long customerId, double amount) { Order order = new Order(customerId, amount, "pending"); return orders.save(order); // triggers INSERT } @Transactional public Order shipOrder(Long orderId) { Order order = orders.findById(orderId) .orElseThrow(() -> new IllegalArgumentException("Order not found: " + orderId)); order.setStatus("shipped"); return orders.save(order); // triggers UPDATE } }
WeftKitDoc — MongoDB Java Driver
WeftKitDoc speaks the MongoDB Wire protocol. The standard MongoDB Java Driver connects directly.
Default port: 27017
Connection and Basic CRUD
javaimport com.mongodb.client.*; import com.mongodb.client.model.*; import org.bson.Document; import org.bson.conversions.Bson; import java.util.Arrays; import java.util.List; public class DocExample { public static void main(String[] args) { String connectionString = "mongodb://app_user:secret@localhost:27017/catalog"; try (MongoClient client = MongoClients.create(connectionString)) { MongoDatabase db = client.getDatabase("catalog"); MongoCollection<Document> products = db.getCollection("products"); // --- InsertOne --- Document newProduct = new Document("name", "Widget Pro") .append("category", "widgets") .append("price", 29.99) .append("tags", Arrays.asList("sale", "featured")) .append("stock", 250); products.insertOne(newProduct); System.out.println("Inserted id: " + newProduct.getObjectId("_id")); // --- InsertMany --- List<Document> batch = List.of( new Document("name", "Gadget A").append("price", 9.99).append("stock", 100), new Document("name", "Gadget B").append("price", 14.99).append("stock", 50) ); products.insertMany(batch); // --- Find with Filters --- Bson filter = Filters.and( Filters.eq("category", "widgets"), Filters.gt("price", 10.00) ); try (MongoCursor<Document> cursor = products.find(filter) .sort(Sorts.ascending("price")) .limit(20) .iterator()) { while (cursor.hasNext()) { Document doc = cursor.next(); System.out.printf(" %s — $%.2f%n", doc.getString("name"), doc.getDouble("price")); } } // --- UpdateOne --- products.updateOne( Filters.eq("name", "Widget Pro"), Updates.combine( Updates.set("price", 24.99), Updates.inc("stock", -10), Updates.addToSet("tags", "clearance") ) ); // --- DeleteOne --- products.deleteOne(Filters.eq("name", "Gadget A")); } } }
Aggregation Pipeline
javaimport com.mongodb.client.*; import com.mongodb.client.model.*; import org.bson.Document; import java.util.Arrays; import java.util.List; public class AggregationExample { public static void summarizeByCategory(MongoCollection<Document> products) { List<Document> pipeline = Arrays.asList( // Stage 1: filter to in-stock items Aggregates.match(Filters.gt("stock", 0)).toBsonDocument(), // Stage 2: group by category and compute aggregates Aggregates.group( "$category", Accumulators.sum("totalStock", "$stock"), Accumulators.avg("avgPrice", "$price"), Accumulators.sum("count", 1) ).toBsonDocument(), // Stage 3: sort by count descending Aggregates.sort(Sorts.descending("count")).toBsonDocument() ); // Use typed Document pipeline via the fluent API instead AggregateIterable<Document> results = products.aggregate(Arrays.asList( Aggregates.match(Filters.gt("stock", 0)), Aggregates.group( "$category", Accumulators.sum("totalStock", "$stock"), Accumulators.avg("avgPrice", "$price"), Accumulators.sum("count", 1) ), Aggregates.sort(Sorts.descending("count")) )); for (Document result : results) { System.out.printf("Category: %s | count=%d | avgPrice=$%.2f%n", result.getString("_id"), result.getInteger("count"), result.getDouble("avgPrice")); } } }
WeftKitDoc — Spring Data MongoDB
application.properties
propertiesspring.data.mongodb.uri=mongodb://app_user:secret@localhost:27017/catalog
application.yml
yamlspring: data: mongodb: uri: mongodb://app_user:secret@localhost:27017/catalog
Document Entity and Repository
javaimport org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.Query; import org.springframework.stereotype.Repository; import java.util.List; // --- Entity --- @Document(collection = "products") public class Product { @Id private String id; private String name; private String category; private double price; private int stock; public Product() {} public Product(String name, String category, double price, int stock) { this.name = name; this.category = category; this.price = price; this.stock = stock; } // Getters and setters omitted for brevity public String getId() { return id; } public String getName() { return name; } public double getPrice() { return price; } public int getStock() { return stock; } public String getCategory() { return category; } } // --- Repository --- @Repository public interface ProductRepository extends MongoRepository<Product, String> { List<Product> findByCategory(String category); List<Product> findByPriceLessThanOrderByPriceAsc(double maxPrice); // Custom query using MongoDB JSON syntax @Query("{ 'price': { $gte: ?0, $lte: ?1 }, 'stock': { $gt: 0 } }") List<Product> findInPriceRange(double min, double max); }
MongoTemplate for Complex Queries
javaimport org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Service; import java.util.List; @Service public class ProductService { private final MongoTemplate mongo; private final ProductRepository productRepo; public ProductService(MongoTemplate mongo, ProductRepository productRepo) { this.mongo = mongo; this.productRepo = productRepo; } public List<Product> findFeaturedWidgets(double maxPrice) { Query query = new Query( Criteria.where("category").is("widgets") .and("price").lte(maxPrice) .and("stock").gt(0) ); query.limit(10); return mongo.find(query, Product.class); } public void restock(String productId, int quantity) { Query query = new Query(Criteria.where("id").is(productId)); Update update = new Update().inc("stock", quantity); mongo.updateFirst(query, update, Product.class); } public Product save(Product product) { return productRepo.save(product); } }
WeftKitMem — Jedis (Sync)
WeftKitMem speaks the Redis RESP3 protocol. Jedis is a simple, synchronous Java client.
Default port: 6379
JedisPool Configuration and Basic Commands
javaimport redis.clients.jedis.*; import java.util.Map; public class JedisExample { // JedisPool is thread-safe; create once and share across your application private static final JedisPool POOL = new JedisPool( new JedisPoolConfig(), "localhost", 6379, 2000, // connection timeout (ms) "secret" // password — omit if unauthenticated ); public static void basicOperations() { try (Jedis jedis = POOL.getResource()) { // SET with expiry jedis.set("session:abc123", "user-id:42"); jedis.expire("session:abc123", 3600L); // expire in 1 hour // SET with options in one call jedis.setex("cache:product:99", 300L, "{\"name\":\"Widget Pro\"}"); // GET String value = jedis.get("session:abc123"); System.out.println("Session value: " + value); // EXISTS / DEL boolean exists = jedis.exists("session:abc123"); jedis.del("session:abc123"); // --- Hash operations --- jedis.hset("user:42", Map.of( "name", "Alice", "email", "alice@example.com", "role", "admin" )); String name = jedis.hget("user:42", "name"); Map<String, String> user = jedis.hgetAll("user:42"); System.out.println("User: " + user); // --- Counter --- jedis.incr("stats:page_views"); jedis.incrBy("stats:bytes_served", 4096L); } } public static void pipelineExample() { try (Jedis jedis = POOL.getResource()) { Pipeline pipeline = jedis.pipelined(); // Queue multiple commands without waiting for each response for (int i = 0; i < 1000; i++) { pipeline.set("key:" + i, "value:" + i); } // Send all commands and receive responses in one round trip pipeline.sync(); System.out.println("Pipeline: 1000 keys written."); } } public static void shutdown() { POOL.close(); } }
WeftKitMem — Lettuce (Async)
Lettuce provides fully asynchronous and reactive Redis access backed by Netty.
javaimport io.lettuce.core.*; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.async.RedisAsyncCommands; import io.lettuce.core.api.reactive.RedisReactiveCommands; import java.util.concurrent.CompletableFuture; public class LettuceExample { public static void main(String[] args) throws Exception { RedisClient client = RedisClient.create( RedisURI.builder() .withHost("localhost") .withPort(6379) .withPassword("secret".toCharArray()) .withDatabase(0) .build() ); try (StatefulRedisConnection<String, String> connection = client.connect()) { // --- Async commands --- RedisAsyncCommands<String, String> async = connection.async(); CompletableFuture<String> setFuture = async.set("async:key", "hello").toCompletableFuture(); CompletableFuture<String> getFuture = setFuture .thenCompose(ok -> async.get("async:key").toCompletableFuture()); String result = getFuture.join(); System.out.println("Async GET: " + result); // --- Reactive commands (Project Reactor) --- RedisReactiveCommands<String, String> reactive = connection.reactive(); reactive.set("reactive:key", "world") .then(reactive.get("reactive:key")) .subscribe(v -> System.out.println("Reactive GET: " + v)); Thread.sleep(500); // wait for reactive pipeline } client.shutdown(); } }
WeftKitMem — Spring Data Redis
application.properties
propertiesspring.data.redis.host=localhost spring.data.redis.port=6379 spring.data.redis.password=secret spring.data.redis.timeout=2000ms
RedisTemplate Bean and Operations
javaimport org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } }
javaimport org.springframework.data.redis.core.*; import org.springframework.stereotype.Service; import java.time.Duration; import java.util.List; import java.util.Map; @Service public class CacheService { private final RedisTemplate<String, Object> redis; public CacheService(RedisTemplate<String, Object> redis) { this.redis = redis; } // --- Value (String) operations --- public void cacheProduct(String id, Object product) { ValueOperations<String, Object> values = redis.opsForValue(); values.set("product:" + id, product, Duration.ofMinutes(10)); } public Object getProduct(String id) { return redis.opsForValue().get("product:" + id); } // --- Hash operations --- public void setUserFields(String userId, Map<String, Object> fields) { redis.opsForHash().putAll("user:" + userId, fields); redis.expire("user:" + userId, Duration.ofHours(1)); } public Object getUserField(String userId, String field) { return redis.opsForHash().get("user:" + userId, field); } // --- List operations --- public void pushToQueue(String queueName, Object item) { redis.opsForList().rightPush(queueName, item); } public List<Object> drainQueue(String queueName, long count) { return redis.opsForList().range(queueName, 0, count - 1); } }
WeftKitGraph — Neo4j Java Driver
WeftKitGraph speaks the Bolt protocol. The standard Neo4j Java Driver connects without modification.
Default port: 7687
Driver Setup and Session Usage
javaimport org.neo4j.driver.*; import org.neo4j.driver.summary.ResultSummary; import java.util.List; import java.util.Map; public class GraphExample implements AutoCloseable { private final Driver driver; public GraphExample(String uri, String user, String password) { this.driver = GraphDatabase.driver( uri, AuthTokens.basic(user, password), Config.builder() .withMaxConnectionPoolSize(50) .withConnectionAcquisitionTimeout(30, java.util.concurrent.TimeUnit.SECONDS) .build() ); driver.verifyConnectivity(); } // --- Write transaction: CREATE nodes and relationships --- public void createUserFollows(String fromName, String toName) { try (Session session = driver.session()) { session.executeWrite(tx -> { tx.run( "MERGE (a:User {name: $from}) " + "MERGE (b:User {name: $to}) " + "MERGE (a)-[:FOLLOWS]->(b)", Map.of("from", fromName, "to", toName) ); return null; }); } } // --- Read transaction: traverse relationships --- public List<String> getFollowers(String userName) { try (Session session = driver.session()) { return session.executeRead(tx -> { Result result = tx.run( "MATCH (follower:User)-[:FOLLOWS]->(u:User {name: $name}) " + "RETURN follower.name AS followerName " + "ORDER BY followerName", Map.of("name", userName) ); return result.list(r -> r.get("followerName").asString()); }); } } // --- Read: shortest path between two users --- public int shortestPathLength(String fromName, String toName) { try (Session session = driver.session()) { return session.executeRead(tx -> { Result result = tx.run( "MATCH p = shortestPath(" + " (a:User {name: $from})-[:FOLLOWS*]-(b:User {name: $to})" + ") RETURN length(p) AS hops", Map.of("from", fromName, "to", toName) ); return result.hasNext() ? result.single().get("hops").asInt() : -1; }); } } // --- Write: delete a relationship --- public void unfollow(String fromName, String toName) { try (Session session = driver.session()) { session.executeWrite(tx -> { ResultSummary summary = tx.run( "MATCH (a:User {name: $from})-[r:FOLLOWS]->(b:User {name: $to}) DELETE r", Map.of("from", fromName, "to", toName) ).consume(); System.out.println("Relationships deleted: " + summary.counters().relationshipsDeleted()); return null; }); } } @Override public void close() { driver.close(); } public static void main(String[] args) { try (GraphExample graph = new GraphExample("bolt://localhost:7687", "neo4j", "secret")) { graph.createUserFollows("Alice", "Bob"); graph.createUserFollows("Alice", "Carol"); graph.createUserFollows("Bob", "Carol"); List<String> followers = graph.getFollowers("Carol"); System.out.println("Carol's followers: " + followers); int hops = graph.shortestPathLength("Alice", "Carol"); System.out.println("Shortest path Alice -> Carol: " + hops + " hop(s)"); } } }
WeftKitKV — AWS SDK for Java v2
WeftKitKV exposes a DynamoDB REST API. Point the AWS SDK at WeftKit's endpoint instead of AWS.
Default port: 8000
Client Setup and Item Operations
javaimport software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.*; import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; public class KeyValueExample { private static final DynamoDbClient dynamo = DynamoDbClient.builder() .endpointOverride(URI.create("http://localhost:8000")) .region(Region.US_EAST_1) // any value works; WeftKit ignores it .credentialsProvider(StaticCredentialsProvider.create( AwsBasicCredentials.create("weftkit", "secret") )) .build(); // --- PutItem (INSERT or full REPLACE) --- public static void putProduct(String productId, String name, double price, int stock) { Map<String, AttributeValue> item = new HashMap<>(); item.put("productId", AttributeValue.fromS(productId)); item.put("name", AttributeValue.fromS(name)); item.put("price", AttributeValue.fromN(String.valueOf(price))); item.put("stock", AttributeValue.fromN(String.valueOf(stock))); dynamo.putItem(PutItemRequest.builder() .tableName("products") .item(item) .build()); System.out.println("PutItem succeeded for: " + productId); } // --- GetItem --- public static Map<String, AttributeValue> getProduct(String productId) { GetItemResponse response = dynamo.getItem(GetItemRequest.builder() .tableName("products") .key(Map.of("productId", AttributeValue.fromS(productId))) .build()); if (!response.hasItem()) { System.out.println("Item not found: " + productId); return Map.of(); } Map<String, AttributeValue> item = response.item(); System.out.printf("Found: %s | price=%s | stock=%s%n", item.get("name").s(), item.get("price").n(), item.get("stock").n()); return item; } // --- UpdateItem (partial update) --- public static void decrementStock(String productId, int quantity) { dynamo.updateItem(UpdateItemRequest.builder() .tableName("products") .key(Map.of("productId", AttributeValue.fromS(productId))) .updateExpression("SET stock = stock - :qty") .conditionExpression("stock >= :qty") .expressionAttributeValues(Map.of( ":qty", AttributeValue.fromN(String.valueOf(quantity)) )) .build()); } // --- DeleteItem --- public static void deleteProduct(String productId) { dynamo.deleteItem(DeleteItemRequest.builder() .tableName("products") .key(Map.of("productId", AttributeValue.fromS(productId))) .build()); System.out.println("Deleted: " + productId); } // --- Query with KeyConditionExpression --- // Assumes table has partition key "category" and sort key "productId" public static List<Map<String, AttributeValue>> queryByCategory(String category) { QueryResponse response = dynamo.query(QueryRequest.builder() .tableName("products") .keyConditionExpression("category = :cat") .expressionAttributeValues(Map.of( ":cat", AttributeValue.fromS(category) )) .limit(100) .build()); System.out.println("Items found: " + response.count()); return response.items(); } // --- Query with sort key range --- public static List<Map<String, AttributeValue>> queryByPriceRange( String category, double minPrice, double maxPrice) { QueryResponse response = dynamo.query(QueryRequest.builder() .tableName("products") .keyConditionExpression("category = :cat AND price BETWEEN :min AND :max") .expressionAttributeValues(Map.of( ":cat", AttributeValue.fromS(category), ":min", AttributeValue.fromN(String.valueOf(minPrice)), ":max", AttributeValue.fromN(String.valueOf(maxPrice)) )) .build()); return response.items(); } public static void main(String[] args) { putProduct("prod-001", "Widget Pro", 29.99, 250); putProduct("prod-002", "Gadget Ultra", 99.99, 50); getProduct("prod-001"); decrementStock("prod-001", 10); List<Map<String, AttributeValue>> items = queryByCategory("widgets"); items.forEach(item -> System.out.println(item.get("name").s())); deleteProduct("prod-002"); } }
Connection String Reference
| Engine | Driver | Connection String Format |
|---|---|---|
| WeftKitRel | JDBC / Spring / Hibernate | jdbc:postgresql://localhost:5432/mydb |
| WeftKitDoc | MongoDB Java Driver | mongodb://user:pass@localhost:27017/catalog |
| WeftKitMem | Jedis / Lettuce | redis://:secret@localhost:6379/0 |
| WeftKitGraph | Neo4j Java Driver | bolt://localhost:7687 |
| WeftKitKV | AWS SDK v2 | endpointOverride("http://localhost:8000") |
All ports are configurable in weftkit.toml. See the Integration Guides overview for TLS/SSL and authentication details.
On this page