Unreleased version v6.3.0-SNAPSHOT. This page describes the alpha branch and may change at any time; it is not part of any released version.

commit 49619c6 · 2026-09-13 12:23 UTC

Skip to content

Query DSL

Since v6.2.0

The fluent Query DSL is available starting from UltiTools-API v6.2.0.

UltiTools provides a fluent Query DSL that lets you build data queries using a readable, chainable API. Instead of manually constructing WhereCondition objects, you can write expressive queries directly.

Basic Usage

Get a Query builder from any DataOperator:

java
DataOperator<HomeEntity> dataOperator = plugin.getDataOperator(HomeEntity.class);

// Find all homes belonging to a player
List<HomeEntity> homes = dataOperator.query()
    .where("player_id").eq(playerUuid)
    .list();

Conditions

where / and

Use where() to start your first condition, and and() to add additional conditions:

java
// Find a specific home by player and name
HomeEntity home = dataOperator.query()
    .where("player_id").eq(playerUuid)
    .and("name").eq("base")
    .first();

Comparison Operators

After calling where() or and(), chain one of these operators:

OperatorDescriptionExample
eq(value)Equal to.where("name").eq("base")
ne(value)Not equal to.where("status").ne("disabled")
gt(value)Greater than.where("level").gt(10)
lt(value)Less than.where("balance").lt(1000.0)
gte(value)Greater than or equal.where("level").gte(5)
lte(value)Less than or equal.where("balance").lte(500.0)
like(pattern)SQL LIKE pattern.where("name").like("%base%")
in(collection)Value in collection.where("world").in(worldList)
java
// Find players with balance between 100 and 1000
List<PlayerEntity> players = dataOperator.query()
    .where("balance").gte(100.0)
    .and("balance").lte(1000.0)
    .list();

// Find homes in specific worlds
List<String> worlds = Arrays.asList("world", "world_nether");
List<HomeEntity> homes = dataOperator.query()
    .where("world").in(worlds)
    .list();

Ordering

Sort results using orderBy() (ascending) or orderByDesc() (descending):

java
// Get players sorted by balance, highest first
List<PlayerEntity> richest = dataOperator.query()
    .orderByDesc("balance")
    .list();

// Sort by level ascending
List<PlayerEntity> sorted = dataOperator.query()
    .orderBy("level")
    .list();

Pagination

Use limit() and offset() to paginate results:

java
// Get page 2 with 10 items per page
int pageSize = 10;
int page = 2;
List<PlayerEntity> pageResults = dataOperator.query()
    .limit(pageSize)
    .offset((page - 1) * pageSize)
    .list();

Terminal Operations

Every query chain must end with a terminal operation:

MethodReturn TypeDescription
list()List<T>Returns all matching results
first()T (nullable)Returns the first match, or null
exists()booleanReturns true if any match exists
count()longCounts matching results
delete()intDeletes matching results, returns count
java
// Check if a player has any homes
boolean hasHomes = dataOperator.query()
    .where("player_id").eq(playerUuid)
    .exists();

// Count homes for a player
long homeCount = dataOperator.query()
    .where("player_id").eq(playerUuid)
    .count();

// Delete all homes in a specific world
int deleted = dataOperator.query()
    .where("world").eq("old_world")
    .delete();

Complete Example

Here is a complete example of a service using the Query DSL:

java
package com.ultikits.docs.query;

import com.ultikits.ultitools.abstracts.UltiToolsPlugin;
import com.ultikits.ultitools.abstracts.data.AuditableDataEntity;
import com.ultikits.ultitools.abstracts.data.BaseDataEntity;
import com.ultikits.ultitools.annotations.*;
import com.ultikits.ultitools.interfaces.DataOperator;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.bukkit.entity.Player;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class HomeServiceImpl implements HomeService {

    private final UltiToolsPlugin plugin;

    @Autowired
    public HomeServiceImpl(UltiToolsPlugin plugin) {
        this.plugin = plugin;
    }

    @Override
    public HomeEntity getHome(String playerUuid, String homeName) {
        return plugin.getDataOperator(HomeEntity.class).query()
            .where("player_id").eq(playerUuid)
            .and("name").eq(homeName)
            .first();
    }

    @Override
    public List<HomeEntity> getAllHomes(String playerUuid) {
        return plugin.getDataOperator(HomeEntity.class).query()
            .where("player_id").eq(playerUuid)
            .orderBy("name")
            .list();
    }

    @Override
    public boolean homeExists(String playerUuid, String homeName) {
        return plugin.getDataOperator(HomeEntity.class).query()
            .where("player_id").eq(playerUuid)
            .and("name").eq(homeName)
            .exists();
    }

    @Override
    public void deleteHome(String playerUuid, String homeName) {
        plugin.getDataOperator(HomeEntity.class).query()
            .where("player_id").eq(playerUuid)
            .and("name").eq(homeName)
            .delete();
    }
}

Legacy API

The WhereCondition API still works and is not deprecated. The Query DSL is a higher-level alternative that is more readable for complex queries. You can mix both approaches freely.

Contributors

No contributors

Released under the MIT License.