Freedom Map Mode
Freedom Map Mode does not need entity classes and does not read object mapping. It is a peer Map API entrance alongside Mapped Map Mode; the difference is that table and column names are provided directly by the caller.
Suitable For
- There is no entity class, or temporary tables, dynamic tables, or sync tasks should not have entity mappings.
- Table names and column names come from task metadata, configuration, or runtime rules.
- The target is a non-traditional tabular source such as MongoDB, ElasticSearch, or Milvus, while the unified builder API is still preferred.
- Map keys should be organized by database column names rather than Java property names.
Not Suitable For
- Entity-field TypeHandler, write policy, primary-key configuration, or field filtering should be reused.
- Field names need compile-time checks or object-mapping validation.
- Table or column names come directly from user input and cannot be allowlisted.
Mode Relationship
Caller provides table name
lambda.queryFreedom("users")
|
v
Caller provides column names
eq("login_name", "alice")
|
v
SQL identifiers enter the statement directly
Freedom Map Mode reuses the builder API without entity mapping; conditions, sorting, grouping and paging still depend on the dialect and data source. Redis does not support this builder; use native commands.
Entrance
MapQuery query = lambda.queryFreedom("users");
MapInsert insert = lambda.insertFreedom("users");
MapUpdate update = lambda.updateFreedom("users");
MapDelete delete = lambda.deleteFreedom("users");
Use the three-argument entrance when catalog or schema must be explicit:
MapQuery query = lambda.queryFreedom("catalog_name", "schema_name", "users");
Query By Database Columns
Field names are normally interpreted as database column names. Freedom Map Mode does not check them against entity mapping and does not automatically filter unknown columns.
List<Map<String, Object>> rows = lambda.queryFreedom("users")
.eq("login_name", "alice")
.select("id", "login_name", "email")
.queryForList();
SQL shape:
SELECT id, login_name, email FROM users WHERE login_name = ?
If camel-case-to-underscore conversion is enabled, Map keys are converted according to that option; otherwise keys are used as provided.
Insert, Update, And Delete
Map<String, Object> row = new HashMap<>();
row.put("id", 1001);
row.put("login_name", "alice");
row.put("email", "alice@example.com");
int rows = lambda.insertFreedom("users")
.applyMap(row)
.executeSumResult();
Map<String, Object> row = new HashMap<>();
row.put("login_name", "alice_new");
int rows = lambda.updateFreedom("users")
.eq("id", 1001)
.updateTo("login_name", row.get("login_name"))
.doUpdate();
int rows = lambda.deleteFreedom("users")
.eq("id", 1001)
.doDelete();
See Map Insert, Update, And Delete for more write and update differences.
Identifier Safety
SQL values are still bound as parameters; table and column names are SQL identifiers and cannot be bound like values.
Value: eq("id", 1001) -> bound as a parameter
Column: eq("id", 1001) -> id is a SQL identifier
Table: queryFreedom("users") -> users is a SQL identifier
If table or column names come from external input, validate them with an allowlist first.
Boundaries
- Any Map key may become a column name.
- If the column name is wrong, the database usually reports the error when SQL executes.
- Type handling mainly follows Map values and runtime types; entity-field TypeHandler configuration is not used.
- UPDATE and DELETE without WHERE are blocked unless
allowEmptyWhere()is explicit.
Further Reading
- Mapped Map Mode, Map entrance that reuses object mapping.
- Map Insert, Update, And Delete, Map mutation operations.
- Where Builder, scalar predicates and dynamic conditions.