morphia操作mongodb

Posted zslm___

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了morphia操作mongodb相关的知识,希望对你有一定的参考价值。

1.加入依赖

      <dependency>
          <groupId>org.mongodb</groupId>
          <artifactId>mongodb-driver</artifactId>
          <version>3.9.1</version>
      </dependency>
 
      <dependency>
          <groupId>org.mongodb.morphia</groupId>
          <artifactId>morphia</artifactId>
          <version>1.3.2</version>
      </dependency>

 

2.配置 MongoClient

class MongoBase {

    static MongoClient client;

    /**
     * MongoClient会自动创建连接池,因此,大部分情况下,整个JVM应用中只需要有一个MongoClient实例就可以。
     */
    static {
        try {

            MongoClientURI clientURI = new MongoClientURI(
                    "mongodb://user:password@192.168.1.22:27017/admin");
            
            client = new MongoClient(clientURI);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Datastore getDatastore() {
        morphia = new Morphia();
        Datastore datastore = morphia.createDatastore(client, "dbName");
        return datastore;
    }

    static Morphia morphia;
}

 

3. 集合MongDbOperator

import com.google.common.collect.ImmutableMap;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.ppmoney.g2.DateHelper;
import com.ppmoney.g2.common.PagedResult;

import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Key;
import org.mongodb.morphia.Morphia;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.Sort;
import org.mongodb.morphia.query.UpdateOperations;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * Created by zhangjy on 2018/11/28.
 */
public class MongDbOperator<T> {
    private Class<T> tClass;

    public MongDbOperator(Class<T> classz) {
        this.tClass = classz;
    }


    public T getOne(ObjectId id) {
        return getQueryFilter(id).get();
    }

    public T getOne(String id) {
        return getQueryFilter(new ObjectId(id)).get();
    }

    public T getOne(Map<String, Object> filter) {
        Assert.notNull(filter, "过滤条件不能为空");
        Query<T> clientDevicesFilter = getQueryFilter(filter);
        return clientDevicesFilter.get();
    }

    public T getOne(Map<String, Object> filter, Sort sort) {
        Assert.notNull(filter, "过滤条件不能为空");
        Query<T> queryFilter = getQueryFilter(filter);
        queryFilter = queryFilter.order(sort);
        return queryFilter.get();
    }

    /**
     * 按访问时间倒序排列
     *
     * @param filter 过滤条件
     * @param sort   排序条件
     * @param limit  前几个(0:不限制)
     */
    public List<T> list(Map<String, Object> filter, Sort sort, int limit) {
        Query<T> queryFilter = getQueryFilter(filter);

        if (sort != null) {
            queryFilter = queryFilter.order(sort);
        }

        if (limit > 0) {
            queryFilter = queryFilter.limit(limit);
        }
        return queryFilter.<T>asList();
    }

    /**
     * 按访问时间倒序排列
     *
     * @param filter 过滤条件
     * @param sort   排序条件
     * @param limit  前几个(0:不限制)
     */
    public long count(Map<String, Object> filter) {
        Query<T> queryFilter = getQueryFilter(filter);

        return count(queryFilter);
    }

    /**
     * 分页查询
     *
     * @param filter 过滤条件
     * @param sort   排序条件
     * @param limit  前几个(0:不限制)
     */
    public PagedResult<T> pagedList(Map<String, Object> filter, Sort sort, int pageIndex, int pageSize) {
        Query<T> queryFilter = getQueryFilter(filter);
        long count = count(queryFilter);
        List<T> subItems = queryFilter.offset((pageIndex - 1) * pageSize).limit(pageSize).asList();
        PagedResult<T> result = new PagedResult<T>(subItems, pageIndex, pageSize, (int) count);

        return result;
    }


    /**
     * 按访问时间倒序排列
     *
     * @param filter 过滤条件
     */
    public List<T> list(Map<String, Object> filter) {
        return list(filter, null, 0);
    }


    public ObjectId insert(T obj) {
        Datastore datastore = MongoBase.getDatastore();
        Key<T> save = datastore.save(obj);
        return (ObjectId) (save.getId());
    }

    public int updateOne(String id, Map<String, Object> filedValues) {
        return updateOne(new ObjectId(id), filedValues);
    }

    public int updateOne(ObjectId id, Map<String, Object> filedValues) {
        Query<T> queryFilter = getQueryFilter(id);

        return updateImpl(queryFilter, filedValues);
    }

    public int update(Map<String, Object> filter, Map<String, Object> filedValues) {
        Query<T> queryFilter = getQueryFilter(filter);

        return updateImpl(queryFilter, filedValues);
    }

    public boolean exists(Map<String, Object> filter) {
        return getOne(filter) != null;
    }

    /**
     * 删除
     *
     * @param filter 用户Id
     */
    public int delete(String id) {
        Query<T> queryFilter = getQueryFilter(new ObjectId(id));

        return delete(queryFilter);
    }

    /**
     * 删除
     *
     * @param filter 用户Id
     */
    public int delete(ObjectId id) {
        Query<T> queryFilter = getQueryFilter(id);

        return delete(queryFilter);
    }

    /**
     * 删除
     *
     * @param filter 用户Id
     */
    public int delete(Map<String, Object> filter) {
        Query<T> queryFilter = getQueryFilter(filter);

        return delete(queryFilter);
    }

    /**
     * 软删除
     *
     * @param filter 用户Id
     */
    public int softDelete(Map<String, Object> filter) {
        Query<T> clientDevicesFilter = getQueryFilter(filter);
        UpdateOperations<T> updateOperations = getDeleteOperations();

        return MongoBase.getDatastore().updateFirst(clientDevicesFilter, updateOperations, false).getUpdatedCount();
    }

    private long count(Query<T> queryFilter) {

        return queryFilter.count();
    }

    /**
     * 删除
     *
     * @param filter 用户Id
     */
    private int delete(Query<T> queryFilter) {
        return MongoBase.getDatastore().delete(queryFilter).getN();
    }

    private int updateImpl(Query<T> queryFilter, Map<String, Object> filedValues) {
        Datastore datastore = MongoBase.getDatastore();

        UpdateOperations<T> updateOperations = datastore.createUpdateOperations(tClass);
        for (Map.Entry<String, Object> entry : filedValues.entrySet()) {
            updateOperations.set(entry.getKey(), entry.getValue());
        }

        return datastore.update(queryFilter, updateOperations, false).getUpdatedCount();
    }

    private Query<T> getQueryFilter(ObjectId id) {
        return getQueryFilter(ImmutableMap.of("_id", id));
    }

    private Query<T> getQueryFilter(Map<String, Object> filter) {
        Query<T> query = MongoBase.getDatastore().createQuery(this.tClass);
        if (CollectionUtils.isEmpty(filter)) {
            return query;
        }

        for (Map.Entry<String, Object> entry : filter.entrySet()) {
            query = query.filter(entry.getKey(), entry.getValue());
        }

        return query;
    }

    private UpdateOperations<T> getUpdateOperations(Map<String, Object> filedValues) {
        UpdateOperations<T> updateOperations = MongoBase.getDatastore().createUpdateOperations(this.tClass);
        updateOperations.inc("version");
        updateOperations.set("lastModifyTime", System.currentTimeMillis());
        for (Map.Entry<String, Object> entry : filedValues.entrySet()) {
            updateOperations.set(entry.getKey(), entry.getValue());
        }
        return updateOperations;
    }

    private UpdateOperations<T> getDeleteOperations() {
        return getUpdateOperations(ImmutableMap.of("deleted", true));
    }
}

 

4.增加model

import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;

import lombok.Data;

/**
 * Created by zhangjy on 2018/11/30.
 */
@Data
@Entity(noClassnameStored = true)
public abstract class BaseMongDbModel {
    /**
     * mongDb的 id
     */
    @Id
    private ObjectId id;

    /**
     * 是否已(软)删除
     */
    private boolean deleted;

    /**
     * 创建时间
     */
    private long createTime;

    /**
     * 最后修改时间
     */
    private long lastModifyTime;

    /**
     * 版本号
     */
    private int version;
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class LoginRecord extends BaseMongDbModel {
    private Integer userId;
    private String phone;
    private String loginIp;
    private Long loginTime;
    private String platform;
    private String deviceId;

    @Override
    public String toString() {
        return super.toString()+"LoginRecord{" +
                "customerId=" + userId +
                ", phone=‘" + phone + ‘‘‘ +
                ", loginIp=‘" + loginIp + ‘‘‘ +
                ", loginTime=" + loginTime +
                ", platform=‘" + platform + ‘‘‘ +
                ", deviceId=‘" + deviceId + ‘‘‘ +
                ‘}‘;
    }
}

 

5.其他辅助类

public class SimplePagedList {
    private static final int DEFALUT_PAGE_SIZE = 10;
    private int pageSize;
    private int totalCount;
    private int firstPageIndex;

    public SimplePagedList(int totalCount, int pageSize) {
        this(totalCount, pageSize, 1);
    }

    public SimplePagedList(int totalCount, int pageSize, int firstPageIndex) {
        this.pageSize = pageSize <= 0?10:pageSize;
        this.totalCount = totalCount;
        this.firstPageIndex = firstPageIndex;
    }

    public int getPageCount() {
        return this.totalCount % this.pageSize == 0?this.totalCount / this.pageSize:this.totalCount / this.pageSize + 1;
    }

    public int getStartIndex(int pageIndex) {
        if(pageIndex < this.firstPageIndex) {
            throw new IllegalArgumentException("pageIndex不合法");
        } else {
            return (pageIndex - 1) * this.pageSize + 1;
        }
    }

    public int getEndIndex(int pageIndex) {
        if(pageIndex < this.firstPageIndex) {
            throw new IllegalArgumentException("pageIndex不合法");
        } else {
            return pageIndex * this.pageSize;
        }
    }
}
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import lombok.Data;

@Data
public class PagedResult<T> {
    private static final int DEFALUT_PAGE_SIZE = 10;
    private boolean hasNextPage;
    private boolean hasPreviousPage;
    private List<T> items;
    private int pageIndex;
    private int pageSize;
    private int totalCount;
    private int totalPages;

    public PagedResult() {
    }

    public PagedResult(List<T> subItems, int pageIndex, int pageSize, int totalCount) {
        if(pageSize <= 0) {
            throw new IllegalArgumentException("pageSize非法");
        } else {
            this.init(subItems, pageIndex, pageSize, totalCount);
        }
    }

    public PagedResult(List<T> source, int pageIndex, int pageSize, Predicate<T> function) {
        if(pageSize <= 0) {
            throw new IllegalArgumentException("pageSize非法");
        } else {
            List<T> filtedItems = source.stream().filter(function).collect(Collectors.toList());
            int count = filtedItems.size();
            SimplePagedList simplePagedList = new SimplePagedList(count, pageSize);
            List<T> subItems = filtedItems.stream().skip((long)simplePagedList.getStartIndex(pageIndex) - 1L).limit((long)pageSize).collect(Collectors.toList());
            this.init(subItems, pageIndex, pageSize, count);
        }
    }

    public PagedResult(List<T> source, int pageIndex, int pageSize) {
        this(source, pageIndex, pageSize, (m) -> {
            return true;
        });
    }

    private void init(List<T> subItems, int pageIndex, int pageSize, int totalCount) {
        if(pageIndex == 0) {
            this.hasNextPage = false;
        } else {
            this.hasNextPage = pageIndex * pageSize < totalCount;
        }

        this.hasPreviousPage = pageIndex > 1 && totalCount > 0;
        this.pageIndex = pageIndex;
        this.pageSize = pageSize;
        this.totalCount = totalCount;
        this.totalPages = totalCount % pageSize == 0?totalCount / pageSize:totalCount / pageSize + 1;
        this.items = subItems;
    }


    @Override
    public String toString() {
        return "PagedResult(hasNextPage=" + this.isHasNextPage() + ", hasPreviousPage=" + this.isHasPreviousPage() + ", items=" + this.getItems() + ", pageIndex=" + this.getPageIndex() + ", pageSize=" + this.getPageSize() + ", totalCount=" + this.getTotalCount() + ", totalPages=" + this.getTotalPages() + ")";
    }
}

 

7.测试代码

public static void main(String[] args) {
        MongDbOperator<LoginRecord> operator = new MongDbOperator<>(LoginRecord.class);
        LoginRecord model;
        List<LoginRecord> models;
        int cutomerId = 50000133;
        // 1.普通查询(根据id查询)
        model = operator.getOne("5e1444b0b58fe60001fcd4eb");
        System.out.println(String.format("根据id获取mode,结果为:%s", model.toString()));

        // 2.普通查询(根据业务主键查询)
        model = operator.getOne(ImmutableMap.of("userId", cutomerId));
        System.out.println(String.format("根据业务主键customerId获取mode,结果为:%s", model));

        // 3.普通查询(根据业务查询)
        models = operator.list(ImmutableMap.of("platform", "app"));
        System.out.println(String.format("根据业务platform获取mode集合,结果为:%s", models));

        // 4.模糊查询(根据正则匹配)
        models = operator.list(ImmutableMap.of("phone", Pattern.compile("^158*")));
        System.out.println(String.format("获取186开头的手机号的登陆记录集合,结果为:%s", models));

        // 5.区间查询
        models = operator.list(ImmutableMap.<String, Object>builder()
                .put("loginTime >=", DateHelper.toTimeStamp(LocalDateTime.of(2019, 1, 1, 0, 0, 0)))
                .put("loginTime <", DateHelper.toTimeStamp(LocalDateTime.of(2021, 1, 1, 0, 0, 0)))
                .build());
        System.out.println(String.format("获取2019年所有用户登陆记录集合,结果为:%s", models));

        //6.分页查询
        PagedResult<LoginRecord> models2 = operator.pagedList(ImmutableMap.of(), Sort.ascending("_id"), 1, 10);
        System.out.println(String.format("获取2019年所有用户登陆记录集合,结果为:%s", models2));

        //7.新增记录
        model = new LoginRecord();
        model.setUserId(cutomerId);
        model.setDeviceId("Q100000");
        model.setLoginIp("186.26.56.25");
        model.setPhone("18626562155");
        model.setPlatform("app");
        long second = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).getEpochSecond();
        model.setLoginTime(second);
        ObjectId id = operator.insert(model);
        System.out.println(String.format("新增记录,新增id为:%s", id));
    }

以上是关于morphia操作mongodb的主要内容,如果未能解决你的问题,请参考以下文章

基于Morphia实现MongoDB按小时按天聚合操作

mongodb morphia怎么获取最大的id

Spring Data MongoDB 五:进阶文档查询(分页Morphia)

Morphia:将MongoDb文档检索为Java对象

java 使用 morphia 存取枚举为值

Playframework + Morphia + MongoDb + ElasticSearch = Disater?