CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-querydsl--querydsl-sql

SQL support for Querydsl - enables type-safe SQL query construction in Java

Pending
Overview
Eval results
Files

query-construction.mddocs/

Query Construction

QueryDSL SQL provides a fluent, type-safe API for building SELECT queries with support for complex joins, conditions, grouping, ordering, and advanced SQL features like subqueries, CTEs, and window functions.

Capabilities

Query Factory

Creates new query instances and provides the primary entry point for query construction.

/**
 * Creates a new empty query
 * @return New SQLQuery instance
 */
public SQLQuery<?> query();

/**
 * Creates a query with a single projection
 * @param expr Expression to select
 * @return SQLQuery with specified projection type
 */
public <T> SQLQuery<T> select(Expression<T> expr);

/**
 * Creates a query with multiple projections
 * @param exprs Expressions to select
 * @return SQLQuery with Tuple projection
 */
public SQLQuery<Tuple> select(Expression<?>... exprs);

/**
 * Creates a query selecting all columns from a table
 * @param expr Table path to select from
 * @return SQLQuery selecting from specified table
 */
public <T> SQLQuery<T> selectFrom(RelationalPath<T> expr);

Usage Examples:

// Basic query creation
SQLQuery<?> query = queryFactory.query();

// Query with projection
SQLQuery<String> nameQuery = queryFactory.select(qUser.name);

// Query with multiple projections
SQLQuery<Tuple> userQuery = queryFactory.select(qUser.name, qUser.email, qUser.age);

// Query with table selection
SQLQuery<User> allUsers = queryFactory.selectFrom(qUser);

Query Building

Core query building methods for constructing SELECT statements with FROM, WHERE, and other clauses.

/**
 * Adds FROM clause to specify source tables
 * @param sources One or more table sources
 * @return Query builder for method chaining
 */
public Q from(Expression<?>... sources);

/**
 * Adds WHERE conditions to filter results
 * @param conditions Boolean expressions for filtering
 * @return Query builder for method chaining
 */
public Q where(Predicate... conditions);

/**
 * Adds GROUP BY clause for aggregation
 * @param columns Columns to group by
 * @return Query builder for method chaining
 */
public Q groupBy(Expression<?>... columns);

/**
 * Adds HAVING clause for aggregate filtering
 * @param conditions Boolean expressions for aggregate filtering
 * @return Query builder for method chaining
 */
public Q having(Predicate... conditions);

/**
 * Adds ORDER BY clause for result ordering
 * @param specifiers Order specifications
 * @return Query builder for method chaining
 */
public Q orderBy(OrderSpecifier<?>... specifiers);

Usage Examples:

// Basic query with WHERE
List<User> activeUsers = queryFactory
    .selectFrom(qUser)
    .where(qUser.active.isTrue())
    .fetch();

// Query with multiple conditions
List<User> results = queryFactory
    .selectFrom(qUser)
    .where(qUser.age.gt(18)
        .and(qUser.country.eq("US"))
        .and(qUser.active.isTrue()))
    .orderBy(qUser.name.asc())
    .fetch();

// Aggregation query
List<Tuple> countByCountry = queryFactory
    .select(qUser.country, qUser.count())
    .from(qUser)
    .where(qUser.active.isTrue())
    .groupBy(qUser.country)
    .having(qUser.count().gt(10))
    .fetch();

Join Operations

Type-safe join operations supporting inner, left, right, and full outer joins with automatic foreign key relationship detection.

/**
 * Performs an inner join
 * @param target Join target expression
 * @return Query builder for method chaining
 */
public Q join(EntityPath<?> target);

/**
 * Performs an inner join with explicit condition
 * @param target Join target
 * @param condition Join condition
 * @return Query builder for method chaining
 */
public Q join(EntityPath<?> target, Predicate condition);

/**
 * Performs a left outer join
 * @param target Join target expression
 * @return Query builder for method chaining
 */
public Q leftJoin(EntityPath<?> target);

/**
 * Performs a right outer join
 * @param target Join target expression
 * @return Query builder for method chaining
 */
public Q rightJoin(EntityPath<?> target);

/**
 * Performs a full outer join
 * @param target Join target expression
 * @return Query builder for method chaining
 */
public Q fullJoin(EntityPath<?> target);

Usage Examples:

// Simple join using foreign key
List<Tuple> userOrders = queryFactory
    .select(qUser.name, qOrder.total)
    .from(qUser)
    .join(qOrder).on(qUser.id.eq(qOrder.userId))
    .fetch();

// Left join with null handling
List<Tuple> usersWithOptionalOrders = queryFactory
    .select(qUser.name, qOrder.total.coalesce(0.0))
    .from(qUser)
    .leftJoin(qOrder).on(qUser.id.eq(qOrder.userId))
    .fetch();

// Multiple joins
List<Tuple> userOrderDetails = queryFactory
    .select(qUser.name, qOrder.total, qOrderItem.quantity)
    .from(qUser)
    .join(qOrder).on(qUser.id.eq(qOrder.userId))
    .join(qOrderItem).on(qOrder.id.eq(qOrderItem.orderId))
    .fetch();

Subqueries

Support for correlated and non-correlated subqueries in SELECT, WHERE, and FROM clauses.

/**
 * Creates a subquery for use in expressions
 * @return New query builder for subquery construction
 */
public <T> SQLQuery<T> select(Expression<T> expr);

/**
 * Checks if value exists in subquery results
 * @param subquery Subquery to check
 * @return Boolean expression for existence check
 */
public BooleanExpression exists(SubQueryExpression<?> subquery);

/**
 * Checks if expression value is in subquery results
 * @param subquery Subquery returning values to check against
 * @return Boolean expression for membership check
 */
public BooleanExpression in(SubQueryExpression<T> subquery);

Usage Examples:

// EXISTS subquery
List<User> usersWithOrders = queryFactory
    .selectFrom(qUser)
    .where(JPAExpressions.exists(
        queryFactory.selectOne()
            .from(qOrder)
            .where(qOrder.userId.eq(qUser.id))
    ))
    .fetch();

// IN subquery
List<User> activeOrderUsers = queryFactory
    .selectFrom(qUser)
    .where(qUser.id.in(
        queryFactory.select(qOrder.userId)
            .from(qOrder)
            .where(qOrder.status.eq("ACTIVE"))
    ))
    .fetch();

// Scalar subquery in SELECT
List<Tuple> usersWithOrderCount = queryFactory
    .select(qUser.name, 
        queryFactory.select(qOrder.count())
            .from(qOrder)
            .where(qOrder.userId.eq(qUser.id)))
    .from(qUser)
    .fetch();

Query Execution

Methods for executing queries and retrieving results in various formats.

/**
 * Executes query and returns all results as a list
 * @return List of query results
 */
public List<T> fetch();

/**
 * Executes query and returns a single result
 * @return Single result or null if no results
 * @throws NonUniqueResultException if multiple results found
 */
public T fetchOne();

/**
 * Executes query and returns first result
 * @return First result or null if no results
 */
public T fetchFirst();

/**
 * Returns count of matching rows without fetching data
 * @return Number of matching rows
 */
public long fetchCount();

/**
 * Executes query with pagination
 * @return Query results page
 */
public QueryResults<T> fetchResults();

Usage Examples:

// Fetch all results
List<User> allUsers = queryFactory
    .selectFrom(qUser)
    .fetch();

// Fetch single result
User user = queryFactory
    .selectFrom(qUser)
    .where(qUser.id.eq(1L))
    .fetchOne();

// Count results
long userCount = queryFactory
    .selectFrom(qUser)
    .where(qUser.active.isTrue())
    .fetchCount();

// Paginated results
QueryResults<User> page = queryFactory
    .selectFrom(qUser)
    .offset(20)
    .limit(10)
    .fetchResults();

Window Functions

Support for SQL window functions including ranking, aggregation, and analytic functions.

/**
 * Creates a ROW_NUMBER() window function
 * @return Window function for row numbering
 */
public static WindowFunction<Long> rowNumber();

/**
 * Creates a RANK() window function
 * @return Window function for ranking
 */
public static WindowFunction<Long> rank();

/**
 * Creates a LAG() window function
 * @param expr Expression to get previous value of
 * @return Window function for accessing previous row value
 */
public static <T> WindowFunction<T> lag(Expression<T> expr);

/**
 * Specifies the window frame for the function
 * @param orderBy Ordering specification for the window
 * @return Window function with ordering
 */
public WindowOver<T> over(OrderSpecifier<?>... orderBy);

Usage Examples:

// Row numbering with ordering
List<Tuple> rankedUsers = queryFactory
    .select(qUser.name, 
        SQLExpressions.rowNumber().over(qUser.score.desc()).as("rank"))
    .from(qUser)
    .fetch();

// Running total
List<Tuple> runningTotals = queryFactory
    .select(qOrder.date, qOrder.amount,
        qOrder.amount.sum().over(qOrder.date.asc()).as("running_total"))
    .from(qOrder)
    .orderBy(qOrder.date.asc())
    .fetch();

// Previous value comparison
List<Tuple> withPrevious = queryFactory
    .select(qStock.date, qStock.price,
        SQLExpressions.lag(qStock.price).over(qStock.date.asc()).as("prev_price"))
    .from(qStock)
    .orderBy(qStock.date.asc())
    .fetch();

Common Table Expressions (CTEs)

Support for WITH clauses and recursive common table expressions.

/**
 * Creates a WITH clause builder
 * @param alias Alias for the CTE
 * @param query Query defining the CTE
 * @return WithBuilder for constructing WITH clauses
 */
public WithBuilder<R> with(Path<?> alias, SubQueryExpression<?> query);

/**
 * Adds a recursive CTE
 * @param alias Alias for the recursive CTE
 * @param query Query defining the recursive CTE
 * @return WithBuilder for method chaining
 */
public WithBuilder<R> withRecursive(Path<?> alias, SubQueryExpression<?> query);

Usage Examples:

// Simple CTE
QUser qActiveUser = new QUser("active_user");
List<String> names = queryFactory
    .with(qActiveUser, 
        queryFactory.selectFrom(qUser)
            .where(qUser.active.isTrue()))
    .select(qActiveUser.name)
    .from(qActiveUser)
    .where(qActiveUser.age.gt(25))
    .fetch();

// Recursive CTE for hierarchical data
QEmployee qSub = new QEmployee("sub");
List<Employee> hierarchy = queryFactory
    .withRecursive(qSub,
        queryFactory.selectFrom(qEmployee)
            .where(qEmployee.managerId.isNull())
            .unionAll(
                queryFactory.selectFrom(qEmployee)
                    .join(qSub).on(qEmployee.managerId.eq(qSub.id))
            ))
    .selectFrom(qSub)
    .fetch();

Install with Tessl CLI

npx tessl i tessl/maven-com-querydsl--querydsl-sql

docs

configuration.md

database-templates.md

dml-operations.md

index.md

query-construction.md

sql-expressions.md

type-system.md

tile.json