Spring boot配置MongoDB以及Morphia踩坑记录
程序员文章站
2022-05-26 14:27:54
pom 因为项目中采用 (`MongoDB ORM pom`文件中引入相应依赖: 因为 依赖于 ,因此无需在 文件中继续导入 . 配置 (1) 配置文件 中配置如下所示: 上述配置中, 包围的地方请按照各自项目实际情况填写. (2) 代码配置 代码中无需自行配置 (`Spring boot Mong ......
pom
因为项目中采用morphia
(mongodb
的orm
框架),因此需要在pom
文件中引入相应依赖:
<dependency> <groupid>dev.morphia.morphia</groupid> <artifactid>core</artifactid> <version>1.5.3</version> </dependency>
因为morphia
依赖于mongo-java-driver
,因此无需在pom
文件中继续导入mongo-java-driver
.
配置
(1) 配置文件
application.yaml
中配置如下所示:
data: mongodb: database: {数据库名称} uri: mongodb://{用户名}:{密码}@{服务器地址}:27017/{数据库名称}
上述配置中,
{}
包围的地方请按照各自项目实际情况填写.
(2) 代码配置
@data @configuration public class morphiaconfig { private mongoclient mongoclient; /** * 设置连接最大空闲时间(到达时间,连接关闭) * @return mongo client属性 */ @autowired public mongoclientoptions mongoclientoptions() { return mongoclientoptions.builder() .maxconnectionidletime(6000 * 5) .maxconnectionlifetime(0) .build(); } @autowired public morphiaconfig(mongoclient mongoclient) { this.mongoclient = mongoclient; } @bean public datastore datastore(@autowired mongoclient mongoclient) { morphia res = new morphia(); // 确定mongo实体类的存放包名 res.mappackage("com.test.log.entity"); datastore datastore = res.createdatastore(mongoclient, "ops"); // 确保实体类的映射建立 datastore.ensureindexes(); return datastore; } }
代码中无需自行配置mongoclient
(spring boot
会自动完成mongoclient
的初始化),当然也允许自行设置mongo
的连接参数.
实体类
项目中需要存放日志,并且通过mongodb
的ttl
特性设置过期时间,以便通过mongodb
完成日志删除任务.
@builder @noargsconstructor @allargsconstructor @data // 必须添加,以便morphia识别此类为`mongodb`的实体类,`loginfo`是表名 @entity(value = "loginfo", noclassnamestored = true) @indexes({ // expiretime存放日志过期时间,创建ttl index @index(fields = @field(value = "expiretime"), options = @indexoptions(expireafterseconds = 0)), // 创建复合索引 @index(fields = {@field("deviceid"), @field("module"), @field(value = "time", type = desc)}), @index(fields = {@field("deviceid"), @field(value = "time", type = desc)}) }) public class loginfo { @id private objectid id; private date time; @jsonignore private date expiretime; private string module; private string level; private string deviceid; private string msg; }
日志的存放和读取是在不同的项目完成,在查询mongodb
时遇到反序列化问题,异常如下所示:
warn dev.morphia.mapping.defaultcreator - class not found defined in dbobj:
查询源码分析,是因为morphia
在存储数据的时候,会将实体类
的名称
存入数据库中.
查询时morphia
根据类名
查找相应的实体类
并进行反序列化
.
因为不同的项目中,实体类的包名不一致导致出现以上错误.
解决方案比较简单,通过注解告知morphia
存储数据时不要存储包名即可,具体如下所示:
`@entity(value = "loginfo", noclassnamestored = true)`.
crud
操作
(1) 存储操作
loginfo loginfo = loginfo.builder() .time(datetime) .expiretime(dateexpiretime) .level(level) .module(module) .deviceid(deviceid) .msg(msg) .build(); try { //插入日志到mongodb datastore.save(loginfo); } catch (runtimeexception e) { log.error(appstatus.idb_write_fail.geterror(), e); }
(2) 查询操作
final query<loginfo> query = datastore.createquery(loginfo.class).filter("deviceid = ", request.getdeviceid()); // 列表查询 if (!collectionutils.isempty(request.getmodules())) { query.filter("module in ", request.getmodules().toarray()); } // 根据时间查询,使用filter就不太恰当了 if (null != request.getstarttime()) { query.field("time").greaterthanoreq(request.getstarttime()); } if (null != request.getfinishtime()) { query.field("time").lessthanoreq(request.getfinishtime()); } // 查询记录总数 int count = query.count()); // 设置排序规则,查询具体数据 query.order(sort.descending("time")); // 获取数据游标 mongocursor<loginfo> loginfomongocursor = query.find( new findoptions() .skip((request.getpagenum() - 1) * request.getpagesize()) .limit(request.getpagesize()) ); // 通过数据游标,逐个获取数据记录 while (loginfomongocursor.hasnext()) { loginfopage.add(loginfomongocursor.next()); }
删除以及更新操作就不再赘述,
morphia
接口比较明晰,容易入门.
上一篇: numpy中的高维数组转置实例