dbMongoDB Research

Morphia入门

2019-08-16  本文已影响0人  animagus

Morphia官网

开发环境

  1. Jetbrain IDEA
  2. Maven

一: maven依赖

官方依赖

<dependency>
    <groupId>dev.morphia.morphia<groupId>
    <artifactId>core</artifactId>
    <version>1.5.3</version>
</dependency>

二: 入门设置

@Service(value = "morphiaDatastore")
public class MorphiaDatastore {
    @Value("${mongodb.db}")
    private String dbName;     //mongodb.uri=mongodb://${mongodb.username}:${mongodb.password} @${mongodb.ip}:${mongodb.port}/${mongodb.db}?authSource=admin
    @Value("${mongodb.uri}")
    private String mongodbUri;

    private Morphia morphia;
    private Datastore datastore;
    private MongoClient mongoClient;

    private void init() {
        if (morphia != null && datastore != null && mongoClient != null) {
            return;
        }
        morphia = new Morphia();
//        设置配置实体的包
        morphia.mapPackage("project.morphia.domain");

        MongoClientURI mongoClientURI = new MongoClientURI(mongodbUri);
        mongoClient = new MongoClient(mongoClientURI);
        datastore = morphia.createDatastore(mongoClient, dbName);
        datastore.ensureIndexes();
    }

    @Bean
    public Datastore getDatastoreInstance() {
        this.init();
        return datastore;
    }
}

三:实体类配置

@Entity("qs_answer")
public class MorphiaQsAnswerPO {
    @Id
    @Property("_id")
    private ObjectId id;
    @Property("question_id")
    private Long questionId;
    @Property("map")
    private Map<String, String> map;
    @Property("patient_id")
    private Long patientId;
    @Property("task_id")
    private Long taskId;
    private Long version;
    @Property("delete_flag")
    private Integer deleteFlag;
    @Property("create_date")
    private Date createDate;
    @Property("update_date")
    private Date updateDate;

    @PrePersist
    private void prePersist() {
        deleteFlag = deleteFlag == null ? DeleteEnum.NOT.value() : deleteFlag;
        createDate = createDate == null ? new Date() : createDate;
        updateDate = new Date();
    }

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    public Long getQuestionId() {
        return questionId;
    }

    public void setQuestionId(Long questionId) {
        this.questionId = questionId;
    }

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public Long getPatientId() {
        return patientId;
    }

    public void setPatientId(Long patientId) {
        this.patientId = patientId;
    }

    public Long getTaskId() {
        return taskId;
    }

    public void setTaskId(Long taskId) {
        this.taskId = taskId;
    }

    public Long getVersion() {
        return version;
    }

    public void setVersion(Long version) {
        this.version = version;
    }

    public DeleteEnum getDeleteFlag() {
        return DeleteEnum.get(deleteFlag);
    }

    /**
     * @see MorphiaQsAnswerPO#prePersist 持久化之前自动设置
     * @param deleteFlag
     */
    public void setDeleteFlag(DeleteEnum deleteFlag) {
        this.deleteFlag = deleteFlag.value();
    }

    public Date getCreateDate() {
        return createDate;
    }

    /**
     * @see MorphiaQsAnswerPO#prePersist 持久化之前自动设置
     * @param createDate
     */
    @Deprecated
    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public Date getUpdateDate() {
        return updateDate;
    }

    /**
     * @see MorphiaQsAnswerPO#prePersist 持久化之前自动设置
     * @param updateDate
     */
    @Deprecated
    public void setUpdateDate(Date updateDate) {
        this.updateDate = updateDate;
    }

    /**
     * 使用MongoDB Java Drive时用到
     * 等到Morphia支持事务时重构这部分
     */
    @SuppressWarnings("all")
    public Document toDocument() {
        Document document = new Document();
        document.put("_id", id);
        document.put("question_id", questionId);
        document.put("map", map);
        document.put("patient_id", patientId);
        document.put("task_id", taskId);
        document.put("version", version);
        document.put("delete_flag", deleteFlag);
        document.put("create_date", createDate);
        document.put("update_date", updateDate);
        for (Iterator<Map.Entry<String, Object>> it = document.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry<String, Object> entry = it.next();
            if (entry.getValue() == null) {
                it.remove();
            }
        }
        return document;
    }
}

四:增删改查demo

public class MorphiaBaseImpl {
    @Resource
    private Datastore datastore;

    /**
     * 事务操作说明
     * 由于morphia还没有原生的事务支持(请看morphia包下的README.md)
     * 所以需要用到mongoClient
     * 请不要在非事务的情况下使用
     * 相关操作参考链接如下
     * https://docs.mongodb.com/v4.0/core/transactions/
     * https://docs.mongodb.com/manual/core/transactions/
     */
//    以下三个字段是为事务操作准备的,请不要滥用
    @Value("${mongodb.db}")
    private String dbName;
    @Value("${mongodb.collection}")
    private String dbCollectionName;
    @Value("${mongodb.uri}")
    private String mongodbUri;

    // 导入的 T 的类的类型,通过构造类装载
    private Class<T> clazz;

    @SuppressWarnings("unchecked")
    public MorphiaBaseImpl() {
        this.clazz = (Class<T>) ((ParameterizedType) super.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    public T save(T po) {
        datastore.save(po);
        return po;
    }

    /**
     * 对于morphia的merge操作
     * po的id为null会报MappingException
     * 找不到匹配的id会报UpdateException
     * @param po 需要持久化的实体类
     * @return 持久化后的类
     */
    public T update(T po) {
        datastore.merge(po);
        return po;
    }

    /**
     * 根据id找到数据
     * @param id 实体类的主键 id 需要是ObjectId类型
     * @return null if not found
     */
    public T get(Serializable id) {
        return datastore.createQuery(clazz).field("id").equal(id).first();
    }


    /**
     * @param pageNumber 需要查询第几页
     * @param pageSize   每页包含多少条记录
     */
    public Page<T> findAll(int pageNumber, int pageSize) {
 

        // Morphia  创建查询
        Query<T> query = datastore.createQuery(clazz);

        // 按照要求分页
        return query.find(new FindOptions()
                .skip(pageNumber > 0 ? ((pageNumber - 1) * pageSize) : 0)
                .limit(pageSize))
                .toList();
    }

    public Page<T> findByAND(int pageNumber, int pageSize, MorphiaQueryCondition queryCondition) {

        Query<T> query = datastore.createQuery(clazz);
        //按照条件获取查询结果
        if (null != queryCondition){
            query = queryCondition.andCriteria(query);
        }

        return query.find(new FindOptions()
                .skip(pageNumber > 0 ?((pageNumber-1)*pageSize) : 0)
                .limit(pageSize))
                .toList();
    }

    /**
     * 实现分页逻辑
     * @param pageNumber     需要查询第几页
     * @param pageSize       每页包含多少条记录
     * @param queryCondition 查询对象
     * @return
     */
    public Page<T> findByOR(int pageNumber, int pageSize, MorphiaQueryCondition queryCondition) {
        Query<T> query = datastore.createQuery(clazz);
        //按照条件获取查询结果
        if (null != queryCondition){
            query = queryCondition.orCriteria(query);
        }
        // 查询总记录数
        Long totalCount = query.count();
        
        retutn query.find(new FindOptions()
                .skip(pageNumber > 0 ?((pageNumber-1)*pageSize) : 0)
                .limit(pageSize))
                .toList();
    }

    /**
     * 将PO转到mongodb原生的Document
     * @return
     */
    private List<Document> posToDocuments(List<T> pos) {
        List<Document> list = new ArrayList<>();
        for (T po : pos) {
            Document document = po.toDocument();
            list.add(document);
        }
        return list;
    }

//mongodb的事务操作请参阅其他文档
//此处是插入多条数据,使用了原子性的操作insertMany
    public void saveList(List<T> pos) throws MongoException {
        final MongoClient client = MongoClients.create(mongodbUri);

        MongoCollection<Document> collection = client.getDatabase(dbName).getCollection(dbCollectionName);
        List<Document> documents = posToDocuments(pos);
        collection.insertMany(documents, new InsertManyOptions());
    }

//此处更新列表不是事务操作,事务操作需要在MongoDB建立replica set
    public List<T> updateListWithoutTransaction(List<T> pos, Boolean bool) throws MongoException {
        ArrayList<T> errorList = new ArrayList<>();
        for (T po : pos) {
            try {
                update(po);
            } catch (Exception e) {
                errorList.add(po);
            }
        }
        return errorList;
    }
}
上一篇下一篇

猜你喜欢

热点阅读