Query Operations
dbVisitor treats MongoDB commands as executable statements: queryForList reads results, and ? and #{...} bind parameters. No SQL translation is required. Connection setup: JDBC MongoDB.
Entity Mapping
@Table(value = "user_info", catalog = "test")
public class UserInfo {
@Column(primary = true)
private String uid;
private String name;
// Getters and setters omitted
}
uid is a business field. primary=true does not create a unique index; updates and deletes by uid affect all matches. For MongoDB _id, see Key Generation.
Executing Query Commands
JdbcTemplate jdbc = new JdbcTemplate(dataSource);
List<UserInfo> rows = jdbc.queryForList(
"test.user_info.find({uid: ?})",
new Object[] { "1001" }, UserInfo.class);
Querying Through Different APIs
- Builder API
- Method Annotations
- Mapper File
LambdaTemplate lambda = new LambdaTemplate(dataSource);
UserInfo item = lambda.query(UserInfo.class)
.eq(UserInfo::getUid, "1001")
.queryForObject();
Ordinary filter queries generate MongoDB find commands.
@SimpleMapper
public interface UserInfoMapper {
@Query("test.user_info.find({uid: #{uid}})")
UserInfo findById(@Param("uid") String uid);
}
Session session = new Configuration().newSession(dataSource);
UserInfoMapper mapper = session.createMapper(UserInfoMapper.class);
UserInfo item = mapper.findById("1001");
<mapper namespace="com.example.UserInfoMapper">
<select id="findById" resultType="com.example.UserInfo">
test.user_info.find({uid: #{uid}})
</select>
</mapper>
@RefMapper("/mapper/mongo-user.xml")
public interface UserInfoMapper {
UserInfo findById(@Param("uid") String uid);
}
Save the XML as the resource named in @RefMapper; the example classes use package com.example. Create the Mapper through Session as in the annotation example.
Use Commands for Complex Filters
Bind values in a MongoDB filter directly:
List<Map<String, Object>> rows = jdbc.queryForList(
"test.user_info.find({$or: [{name: ?}, {uid: ?}]})",
new Object[] { "mali", "1001" });
Aggregation and Projections
applySelect accepts MongoDB expressions, not SQL such as SUM(age). With groupBy, supply an accumulator document:
List<Map<String, Object>> groups = lambda.query(UserInfo.class)
.applySelect("{cnt: {$sum: 1}}")
.groupBy("age")
.orderBy("age")
.queryForMapList();
This groups documents by age and returns age and cnt. The driver generates $group and expands the grouping fields into result columns.
Without groupBy, an expression document defines $project; an array defines an aggregation pipeline:
Long total = lambda.query(UserInfo.class)
.applySelect("[{$group: {_id: null, value: {$sum: '$age'}}}, {$project: {_id: 0, value: 1}}]")
.eq("name", name)
.queryForObject(Long.class);
Bound conditions become a preceding $match; orderBy adds a final $sort. Do not combine a pipeline array with groupBy or ordinary field projections.
applySelect contains command expressions. Use expressions defined by your application. Pass user input through condition parameters such as eq, never concatenate it into expressions.
For more native commands, see Command Syntax.
Computing values in an aggregation
MongoDB calculates values with aggregation expressions such as $add, rather than JDBC stored functions. This example assumes the collection contains one document:
Integer sum = jdbc.queryForObject(
"test.calculation.aggregate([{$project: {_id: 0, value: "
+ "{$add: [{$literal: ?}, {$literal: ?}]}}}])",
new Object[] { 10, 5 }, Integer.class);
Positional and named arguments and scalar conversion are supported. An aggregation returns one computed result per matching document; an empty collection does not produce a standalone calculation row. Use query methods, not CallableStatement callbacks or OUT-parameter records. SQL table-function syntax is not supported.
See Where Builder for collection predicates and explicit null filtering.
Query Errors
Invalid commands report errors. Querying a missing collection normally returns an empty result rather than a missing-table error, so a query that does not throw cannot establish that the collection exists.
Query Execution Options
Mapper files accept statementType, timeout, and fetchSize; their effect follows the driver settings. For resultSetType, keep DEFAULT or use FORWARD_ONLY. Scrollable result sets (SCROLL_INSENSITIVE and SCROLL_SENSITIVE) are not supported. See Execution Options for XML configuration.
See Result Reading for result columns.