MongoDB 数据源特异性
dbVisitor 通过 JDBC-Mongo 驱动,基于 JDBC 协议访问 MongoDB 数据源。
支持的能力:
- 使用 MongoDB 命令操作数据(支持的命令列表)
- JdbcTemplate、构造器 API、BaseMapper、方法注解、Mapper 文件
- 对象映射、结果集映射、规则、参数传递、ResultSetExtractor/RowMapper
- Mapper File 中的动态 SQL 标签、
Statement.RETURN_GENERATED_KEYS(自动获取_id)
不支持: executeBatch、存储过程
概念类比
不同 MongoDB 命令的执行结果分为三种:
- 更新数 — 类比 INSERT/UPDATE/DELETE,用
executeUpdate获取 - 单行/多行结果 — 类比 SELECT 结果集,第一列为
_ID,第二列为_JSON(均为字符串)
命令方式(JdbcTemplate)
使用 JdbcTemplate 可以直接执行 MongoDB 命令,在此之前请确保已经正确配置好 MongoDB 数据源,具体请参考 MongoDB 驱动使用指南。
提示
更多使用方式请参考 JdbcTemplate 类,在使用过程中下面两个特性由于驱动原因无法支持:
- 批量化
- 存储过程
创建 JdbcTemplate
JdbcTemplate jdbc = new JdbcTemplate(dataSource);
// 或者
JdbcTemplate jdbc = new JdbcTemplate(connection);
插入数据
// 直接命令方式
jdbc.execute("test.user_info.insert({name: 'mali', age: 26})");
// 参数化命令方式
jdbc.execute("test.user_info.insert(?)", new Object[] { "{name: 'mali', age: 26}" });
查询数据
// 查询所有
List<Map<String, Object>> list = jdbc.queryForList("test.user_info.find()");
// 条件查询
Map<String, Object> mali = jdbc.queryForMap("test.user_info.find({name: 'mali'})");
String json = (String) mali.get("_JSON");
更新数据
jdbc.execute("test.user_info.update({name: 'mali'}, {$set: {age: 27}})");
删除数据
jdbc.execute("test.user_info.remove({name: 'mali'})");
构造器 API(LambdaTemplate)
构造器 API 提供了一种类型安全、流式调用的方式操作 MongoDB,用法与 RDBMS 一致,详细请参考 构造器 API。
初始化
LambdaTemplate lambda = new LambdaTemplate(dataSource);
新增
UserInfo user = new UserInfo();
user.setUid("1001");
user.setName("test_user");
int result = lambda.insert(UserInfo.class)
.applyEntity(user)
.executeSumResult();
查询
// 根据条件查询
UserInfo user = lambda.query(UserInfo.class)
.eq(UserInfo::getUid, "1001")
.queryForObject();
// 列表查询
List<UserInfo> users = lambda.query(UserInfo.class)
.like(UserInfo::getName, "test%")
.queryForList();
更新
int result = lambda.update(UserInfo.class)
.eq(UserInfo::getUid, "1001")
.updateTo(UserInfo::getName, "New Name")
.doUpdate();
删除
int result = lambda.delete(UserInfo.class)
.eq(UserInfo::getUid, "1001")
.doDelete();
BaseMapper 接口
BaseMapper 提供了通用 CRUD 方法,用法与 RDBMS 一致,详细请参考 BaseMapper。
定义 Mapper 接口
@SimpleMapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
// 可以在此添加自定义方法
}
使用 Mapper 进行 CRUD
Session session = ...;
UserInfoMapper mapper = session.createMapper(UserInfoMapper.class);
// 新增
mapper.insert(user);
// 查询
UserInfo loadedUser = mapper.selectById(user.getUid());
// 更新
loadedUser.setName("updated_name");
mapper.update(loadedUser);
// 删除
mapper.deleteById(user.getUid());
注解方式
提示
对于 核心 API 提供的注解 方式除了 @Call 注解不支持之外,其它所有注解都可以在 MongoDB 数据源上正常使用。
1. 定义对象
@Table("user_info")
public class UserInfo {
@Column(value = "uid", primary = true)
private String uid;
@Column("name")
private String name;
... // 省略 getter/setter 方法
}
2. 定义 Mapper 接口
@SimpleMapper()
public interface UserInfoMapper {
@Insert("test.user_info.insert(#{info, typeHandler=net.hasor.dbvisitor.types.handler.json.JsonTypeHandler})")
int saveUser(@Param("info") UserInfo info);
@Query("test.user_info.find({uid: #{uid}})")
UserInfo loadUser(@Param("uid") String uid);
@Delete("test.user_info.remove({uid: #{uid}})")
int deleteUser(@Param("uid") String uid);
}
3. 创建并使用 Mapper
Configuration config = new Configuration();
Session session = config.newSession(dataSource);
UserInfoMapper mapper = session.createMapper(UserInfoMapper.class);
映射 ObjectId
MongoDB 的 _id 字段通常是 ObjectId 类型,而在 Java 对象中我们通常使用 String 类型。
定义对象(ObjectId 映射)
@Table("user_info")
public class UserInfo {
@Column(value = "_id", primary = true, keyType = KeyType.Auto, whereValueTemplate = "ObjectId(?)")
private String id;
@Column("name")
private String name;
...
}
Mapper 定义(使用 ObjectId 查询)
@SimpleMapper()
public interface UserInfoMapper {
@Query("test.user_info.find({_id: ObjectId(#{id})})")
UserInfo loadById(@Param("id") String id);
}
分页查询
在 Mapper 方法中添加 Page 参数即可实现分页查询。
Mapper 定义
@SimpleMapper()
public interface UserInfoMapper {
@Query("test.user_info.find({name: #{name}})")
List<UserInfo> queryByName(@Param("name") String name, Page page);
}
调用分页
Page page = new PageObject();
page.setPageSize(10);
List<UserInfo> list = mapper.queryByName("mali", page);
文件方式(Mapper File)
1. 定义对象
@Table("user_info")
public class UserInfo {
@Column(value = "uid", primary = true)
private String uid;
@Column("name")
private String name;
... // 省略 getter/setter 方法
}
2. 定义 Mapper 文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//dbvisitor.net//DTD Mapper 1.0//EN"
"https://www.dbvisitor.net/schema/dbvisitor-mapper.dtd">
<mapper namespace="net.test.dto.UserInfoMapper">
<insert id="saveUser">
test.user_info.insert(#{info, typeHandler=net.hasor.dbvisitor.types.handler.json.JsonTypeHandler})
</insert>
<select id="loadUser" resultType="net.test.dto.UserInfo">
test.user_info.find({uid: #{uid}})
</select>
<delete id="deleteUser">
test.user_info.remove({uid: #{uid}})
</delete>
</mapper>
3. 定义 Mapper 接口
@RefMapper("/path/to/mapper.xml")
public interface UserInfoMapper {
int saveUser(@Param("info") UserInfo info);
UserInfo loadUser(@Param("uid") String uid);
int deleteUser(@Param("uid") String uid);
}