Interface CustomCondition

All Superinterfaces:
Condition

public sealed interface CustomCondition extends Condition
A custom Condition based on a ConditionString.

Custom conditions are used to create query conditions that cannot be created with the standard Condition, ColumnConditions or ForeignKeyConditions APIs. They enable complex SQL constructs such as subqueries, JOINs, window functions, and database-specific functionality.

A ConditionType is associated with a ConditionString, which is responsible for creating the condition string via ConditionString.get(List, List). The ? substitute character is replaced with condition values when the statement is prepared.

Custom conditions provide the flexibility to use any SQL construct while maintaining type safety and parameter binding:

// Define custom condition types in the entity interface
interface Track {
	EntityType TYPE = DOMAIN.entityType("chinook.track");

	Column<Long> ID = TYPE.longColumn("id");
	Column<String> NAME = TYPE.stringColumn("name");

	// Custom condition with any number of values
	ConditionType NOT_IN_PLAYLISTS = TYPE.conditionType("not_in_playlists");
}

// Register custom conditions in the entity definition
EntityDefinition track() {
	return Track.TYPE.as()
					.attributes(
									Track.ID.as()
													.primaryKey(),
									Track.NAME.as()
													.column()
													.caption("Name"))
					.condition(Track.NOT_IN_PLAYLISTS, (columns, values) ->
									// A parameter placeholder for each value
									"track.id NOT IN (SELECT track_id FROM chinook.playlisttrack WHERE playlist_id IN (" +
													String.join(", ", Collections.nCopies(values.size(), "?")) + "))")
					.build();
}

List<Entity> tracks(EntityConnection connection) {
	// Tracks not in specific playlists
	List<Entity> notInPlaylists = connection.select(
					Track.NOT_IN_PLAYLISTS.get(Playlist.ID, List.of(1L, 5L, 10L)));

	// Combine custom conditions with standard conditions
	Condition condition = and(
					Track.NAME.like("The%"),
					Track.NOT_IN_PLAYLISTS.get(Playlist.ID, List.of(1L)));

	// Use a Select for additional control
	return connection.select(
					Select.where(condition)
									.attributes(Track.NAME)
									.orderBy(ascending(Track.NAME)));
}
See Also:
  • Method Details

    • conditionType

      ConditionType conditionType()
      Returns:
      the condition type