跳到主要内容

MongoDB 数据源特异性

dbVisitor 通过 JDBC-Mongo 驱动,基于 JDBC 协议访问 MongoDB 数据源。

支持的能力:

不支持: 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);
}