当前位置: 移动技术网 > IT编程>开发语言>Java > Spring boot配置MongoDB以及Morphia踩坑记录

Spring boot配置MongoDB以及Morphia踩坑记录

2019年06月22日  | 移动技术网IT编程  | 我要评论

pom

因为项目中采用morphia(mongodborm框架),因此需要在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的连接参数.

实体类

项目中需要存放日志,并且通过mongodbttl特性设置过期时间,以便通过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接口比较明晰,容易入门.

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网