日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

mongodb 3.2 實(shí)戰(zhàn)(三)整合Spring Data MongoDB

 Bladexu的文庫 2019-04-10

1.簡(jiǎn)介

Spring Data for MongoDB 作為 Spring 大家族中的一員,為MongoDB定制了類似于關(guān)系型數(shù)據(jù)庫的ORM框架。

  • 與hibernate mybatis 等ORM框架類似,都需要一個(gè)pojo的bean。所不同的是,關(guān)系型數(shù)據(jù)庫對(duì)應(yīng)的是table,而此處對(duì)應(yīng)到MongoDB中的collection。

  • 由于 MongoDB 本身并沒有事務(wù)支持,所以spring 也無法維護(hù)事務(wù)。但是在mongoDB的操作手冊(cè)提供了這樣一個(gè)方式來維護(hù)多文檔操作的事務(wù)。

原文是這樣說的:


Because only single-document operations are atomic with MongoDB, two-phase commits can
only offer transaction-like semantics. It is possible for applications to return intermediate data at
intermediate points during the two-phase commit or rollback.


只有單文檔操作是原子性的,兩階段提交可以提供這樣一個(gè)類似事務(wù)的模式。這樣來為應(yīng)用程序可以返回一個(gè)再兩階段提交或者回滾的中間點(diǎn)。直接略去我的翻譯,大致的意思,就是MongoDB僅僅支持單文檔的原子性操作,但是提供了一個(gè)兩階段方式來維護(hù)事務(wù)。也就是說在多個(gè)文檔操作時(shí),MongoDB提供了一個(gè)兩階段提交模式來維護(hù)事務(wù)。

具體的操作方式,具體參考一下
https://docs./manual/tutorial/perform-two-phase-commits/
對(duì)于這個(gè)MongoDB事務(wù),個(gè)人的觀點(diǎn)是不建議使用事務(wù),因?yàn)樵跀?shù)據(jù)庫選型的時(shí)候,如果希望事務(wù)比較強(qiáng),那么建議選用關(guān)系型數(shù)據(jù)庫來存儲(chǔ)數(shù)據(jù)。對(duì)于MongoDB的應(yīng)用,一般是用來查詢,或者是存儲(chǔ)日志等對(duì)事務(wù)要求比較弱的應(yīng)用場(chǎng)景。

2.spring data MongoDB 整合

環(huán)境:

spring.data.mongodb.1.7.2.RELEASE.jar
mongo-java-driver-2.13.3.jar

配置連接池:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www./schema/beans"
    xmlns:xsi="http://www./2001/XMLSchema-instance" xmlns:context="http://www./schema/context"
    xmlns:mongo="http://www./schema/data/mongo"
    xsi:schemaLocation="http://www./schema/beans
            http://www./schema/beans/spring-beans-4.1.xsd
            http://www./schema/context
            http://www./schema/context/spring-context-4.1.xsd
            http://www./schema/data/mongo
           http://www./schema/data/mongo/spring-mongo-1.0.xsd">

    <!-- 配置mongoTemplate -->
    <mongo:mongo host="${mongo.host}" port="${mongo.port}"></mongo:mongo>


    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg ref="mongo" />
        <constructor-arg name="databaseName" value="${mongo.dbname}" />
    </bean>

</beans>

MongoTemplate 是spring data MongoDB 中的的操作類,繼承了MongoOperations 與ApplicationContextAware ,這個(gè)MongoOperations里面封裝了基礎(chǔ)CRUD操作,有興趣直接閱讀以下源碼很快能看懂。

基礎(chǔ)的操作接口

package edu.yingding.core.mongo;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import edu.yingding.core.entity.PagerDTO;

//mongo操作接口
public interface IBaseMongo {

    public List selectPage(Map<String, Object> param, Class entityClass,  PagerDTO pagerDto) throws Exception;

    public List selectPage(String queryStr, Class entityClass,  PagerDTO pagerDto) throws Exception;

    List find( Query query,Class entityClass);

    public List selectPage(Query query,Class entityClass,PagerDTO pagerDto)throws Exception;

    /**
     * 分組取數(shù)據(jù)
     * @param collectionName mongo表名
     * @param fieldName
     * @param param
     * @return
     * @throws Exception
     */
    public List distinct(String collectionName, String fieldName, Map<String, Object> param) throws Exception;

    /**
     * 得到一個(gè)實(shí)體
     * @param param
     * @param entityClass
     * @return
     * @throws Exception
     */
    public Object findOne(Map<String, Object> param, Class entityClass) throws Exception;

    /**
     * 保存結(jié)果集
     * @param entity
     * @return
     * @throws Exception
     */
    public boolean insert(Object entity) throws Exception;

    /**
     * 按id更新數(shù)據(jù)
     * @param id
     * @param param
     * @return
     * @throws Exception
     */
    public boolean updateById(String id, Map<String, Object> param, Class entityClass) throws Exception;


    List selectPage(String queryStr, Criteria criteria, Class entityClass, PagerDTO pagerDto) throws Exception;
}
package edu.yingding.core.mongo;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import com.mongodb.WriteResult;
import edu.yingding.core.entity.PagerDTO;
import net.sf.json.JSONObject;

/**
 * @Author:chenfanglin 【chenfanglincfl@163.com】
 * @Description:
 * @Date: 15:53 2017/1/4
 * @Version 1.0.0
 */
@Service
public class BaseMongoImpl implements IBaseMongo {

    @Autowired
    protected MongoTemplate mongoTemplate;

    /**
     * @param param       查詢參數(shù)【map類型】
     * @param entityClass 反射類
     * @param pagerDto    分頁實(shí)體
     * @Author:chenfanglin 【chenfanglincfl@163.com】
     * @Description: 分頁方法【支持map類型參數(shù)】
     * @Date: 15:52 2017/1/4
     * @Version 1.0.0
     */
    @Override
    public List selectPage(Map<String, Object> param, Class entityClass, PagerDTO pagerDto) throws Exception {
        Query query = parseParams(param);

        long total = mongoTemplate.count(query, entityClass);
        List results = null;
        if (total > 0) {
            pagerDto.init(total);
            query.skip((pagerDto.getPageNum() - 1) * pagerDto.getPageSize());
            query.limit(pagerDto.getPageSize());

            if (StringUtils.isNotEmpty(pagerDto.getOrderBy())) {
                JSONObject orderObj = JSONObject.fromObject(pagerDto.getOrderBy());
                if (orderObj != null) {
                    Iterator it = orderObj.keys();
                    while (it.hasNext()) {
                        String key = (String) it.next();
                        int value = orderObj.getInt(key);
                        if (value == 1) {
                            query.with(new Sort(Direction.ASC, key));
                        } else {
                            query.with(new Sort(Direction.DESC, key));
                        }
                    }
                }
            }

            System.out.println(query.toString());
            results = mongoTemplate.find(query, entityClass);
            pagerDto.setResult(results);
        } else {
            pagerDto.setResult(Collections.emptyList());
        }
        return results;
    }

    /**
     * @param queryStr    查詢字符串
     * @param entityClass 反射類
     * @param pagerDto    分頁實(shí)體
     * @Author:chenfanglin 【chenfanglincfl@163.com】
     * @Description: 分頁方法 【支持查詢字符串】
     * @Date: 15:54 2017/1/4
     * @Version 1.0.0
     */
    @Override
    public List selectPage(String queryStr, Class entityClass, PagerDTO pagerDto) throws Exception {
        if (queryStr == null) {
            queryStr = "";
        }
        BasicQuery query = new BasicQuery(queryStr);
        long total = mongoTemplate.count(query, entityClass);
        List results = null;
        if (total > 0) {
            pagerDto.init(total);
            query.skip((pagerDto.getPageNum() - 1) * pagerDto.getPageSize());
            query.limit(pagerDto.getPageSize());

            if (StringUtils.isNotEmpty(pagerDto.getOrderBy())) {
                JSONObject orderObj = JSONObject.fromObject(pagerDto.getOrderBy());
                if (orderObj != null) {
                    Iterator it = orderObj.keys();
                    while (it.hasNext()) {
                        String key = (String) it.next();
                        int value = orderObj.getInt(key);
                        if (value == 1) {
                            query.with(new Sort(Direction.ASC, key));
                        } else {
                            query.with(new Sort(Direction.DESC, key));
                        }
                    }
                }
            }
            results = mongoTemplate.find(query, entityClass);
            pagerDto.setResult(results);
        } else {
            pagerDto.setResult(Collections.emptyList());
        }
        return results;
    }

    /**
     * @param queryStr
     * @param criteria
     * @param entityClass
     * @param pagerDto
     * @Author:chenfanglin 【chenfanglincfl@163.com】
     * @Description: 分頁方法 【支持查詢字符串與Criteria對(duì)象】
     * @Param:
     * @Date: 15:55 2017/1/4
     * @Version 1.0.0
     */
    @Override
    public List selectPage(String queryStr, Criteria criteria, Class entityClass, PagerDTO pagerDto) throws Exception {
        if (queryStr == null) {
            queryStr = "";
        }
        BasicQuery query = new BasicQuery(queryStr);
        query.addCriteria(criteria);
        long total = mongoTemplate.count(query, entityClass);
        List results = null;
        if (total > 0) {
            pagerDto.init(total);
            query.skip((pagerDto.getPageNum() - 1) * pagerDto.getPageSize());
            query.limit(pagerDto.getPageSize());

            if (StringUtils.isNotEmpty(pagerDto.getOrderBy())) {
                JSONObject orderObj = JSONObject.fromObject(pagerDto.getOrderBy());
                if (orderObj != null) {
                    Iterator it = orderObj.keys();
                    while (it.hasNext()) {
                        String key = (String) it.next();
                        int value = orderObj.getInt(key);
                        if (value == 1) {
                            query.with(new Sort(Direction.ASC, key));
                        } else {
                            query.with(new Sort(Direction.DESC, key));
                        }
                    }
                }
            }
            results = mongoTemplate.find(query, entityClass);
            pagerDto.setResult(results);
        } else {
            pagerDto.setResult(Collections.emptyList());
        }
        return results;
    }

    /**
     * @Author:chenfanglin 【chenfanglincfl@163.com】
     * @Description: 查詢實(shí)體list
     * @Param: query 查詢對(duì)象
     * @Param: entityClass 反射類
     * @Date: 15:57 2017/1/4
     * @Version 1.0.0
     */
    @Override
    public List find(Query query, Class entityClass) {
        return mongoTemplate.find(query, entityClass);
    }

    /**
     * @Author:chenfanglin 【chenfanglincfl@163.com】
     * @Description: 查詢分頁 【支持query對(duì)象】
     * @Param: * @param query 查詢對(duì)象
     * @Param: * @param entityClass 反射類
     * @Param: * @param pagerDto 分頁實(shí)體
     * @Date: 15:58 2017/1/4
     * @Version 1.0.0
     */
    @Override
    public List selectPage(Query query, Class entityClass, PagerDTO pagerDto) throws Exception {
        List results = null;
        if (query != null) {
            long count = mongoTemplate.count(query, entityClass);
            if (count > 0) {
                pagerDto.init(count);
                query.skip((pagerDto.getPageNum() - 1) * pagerDto.getPageSize());
                query.limit(pagerDto.getPageSize());
                if (StringUtils.isNotEmpty(pagerDto.getOrderBy())) {
                    JSONObject orderObj = JSONObject.fromObject(pagerDto.getOrderBy());
                    if (orderObj != null) {
                        Iterator it = orderObj.keys();
                        while (it.hasNext()) {
                            String key = (String) it.next();
                            int value = orderObj.getInt(key);
                            if (value == 1) {
                                query.with(new Sort(Direction.ASC, key));
                            } else {
                                query.with(new Sort(Direction.DESC, key));
                            }
                        }
                    }
                }

                System.out.println(query.toString());
                results = mongoTemplate.find(query, entityClass);
                pagerDto.setResult(results);
            } else {
                pagerDto.setResult(Collections.emptyList());
            }
        } else {
            pagerDto.setResult(Collections.EMPTY_LIST);
        }
        return results;
    }

    /**
     * @Author:chenfanglin 【chenfanglincfl@163.com】
     * @Description: 查詢?nèi)ブ貙?shí)體集合
     * @Param: * @param collectionName 集合名稱
     * @Param: * @param fieldName 去重字段名
     * @Param: * @param param 查詢條件
     * @Date: 15:59 2017/1/4
     * @Version 1.0.0
     */
    @Override
    public List distinct(String collectionName, String fieldName, Map<String, Object> param) throws Exception {
        if (StringUtils.isEmpty(collectionName) || StringUtils.isEmpty(fieldName)) {
            return Collections.emptyList();
        }
        Query query = parseParams(param);
        return mongoTemplate.getCollection(collectionName).distinct(fieldName, query.getQueryObject());
    }

    /**
     * @Author:chenfanglin 【chenfanglincfl@163.com】
     * @Description: 格式化查詢條件
     * @Param: * @param param 查詢條件
     * @Date: 16:00 2017/1/4
     * @Version 1.0.0
     */
    private Query parseParams(Map<String, Object> param) {
        Query query = new Query();
        if (param != null && !param.isEmpty()) {
            Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, Object> entry = it.next();
                String key = entry.getKey();
                if (StringUtils.isEmpty(key)) {
                    continue;
                }
                if (key.endsWith("Ignore")) {
                    continue;
                }
                if (key.startsWith("$")) {
                } else if (key.endsWith("Contains")) {
                    query.addCriteria(Criteria.where(key.replaceFirst("Contains", "")).regex((String) entry.getValue()));
                } else {
                    query.addCriteria(Criteria.where(key).is(entry.getValue()));
                }
            }
        }
        return query;
    }

    @Override
    public Object findOne(Map<String, Object> param, Class entityClass) throws Exception {
        Query query = parseParams(param);
        return mongoTemplate.findOne(query, entityClass);
    }

    @Override
    public boolean insert(Object entity) throws Exception {
        try {
            mongoTemplate.insert(entity);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public boolean updateById(String id, Map<String, Object> param, Class entityClass) throws Exception {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        Update update = parseUpdate(param);
        WriteResult result = mongoTemplate.updateFirst(query, update, entityClass);
        return result.getN() > 0 ? true : false;
    }

    private Update parseUpdate(Map<String, Object> param) {
        Update update = new Update();
        if (param != null && !param.isEmpty()) {
            Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, Object> entry = it.next();
                String key = entry.getKey();
                if (StringUtils.isEmpty(key)) {
                    continue;
                }
                if (key.endsWith("Ignore")) {
                    continue;
                }
                if (key.startsWith("$")) {
                } else {
                    update.set(key, entry.getValue());
                }
            }
        }
        return update;
    }
}

分頁實(shí)體

    package edu.yingding.core.entity;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

/**
* @Author:chenfanglin 【chenfanglincfl@163.com】
* @Description:  分頁實(shí)體
* @Param:  * @param null
* @Date: 16:01 2017/1/4
* @Version 1.0.0
*/
public class PagerDTO {

    //當(dāng)前第幾頁
    private int pageNum=1;

    //總共多少頁
    private long pageCount;

    //每頁顯示幾條數(shù)據(jù)
    private int pageSize = 10;

    //總共多少條
    private long total;

    /* 排序方式 */
    private String orderBy;

    /* 查詢字符串 */
    private String queryStr;

    /* 表單防止重復(fù)提交碼 */
    private String formToken;

    /* 必須有參數(shù)才能做分頁查詢 */
    private boolean argsCanSearch;

    /* 如果為真,并且pageCount > 0 ,則在數(shù)據(jù)庫中不進(jìn)行查詢 */
    private boolean userPageCount;

    //分頁返回的數(shù)據(jù)
    private Object result;

    public boolean isUserPageCount() {
        return userPageCount;
    }

    public void setUserPageCount(boolean userPageCount) {
        this.userPageCount = userPageCount;
    }

    public boolean isArgsCanSearch() {
        return argsCanSearch;
    }

    public void setArgsCanSearch(boolean argsCanSearch) {
        this.argsCanSearch = argsCanSearch;
    }

    public String getFormToken() {
        return formToken;
    }

    public void setFormToken(String formToken) {
        this.formToken = formToken;
    }

    public void init(long total) {
        this.setTotal(total);
        boolean flag = (total%this.getPageSize() == 0) ? false : true;
        long iPageSize = flag ? (total/this.getPageSize()+1) : (total/this.getPageSize());
        if(this.getPageNum() > iPageSize) {
            this.setPageNum(1);
        }
        this.setPageCount(iPageSize);
    }

    public int getPageNum() {
        return pageNum;
    }

    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }

    public long getPageCount() {
        return pageCount;
    }

    public void setPageCount(long pageCount) {
        this.pageCount = pageCount;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPerPage(int pageSize) {
        if(pageSize > 100) {
            this.pageSize = 100;
        } else {
            this.pageSize = pageSize;
        }
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        this.total = total;
    }

    public String getOrderBy() {
        return orderBy;
    }

    public void setOrderBy(String orderBy) {
        this.orderBy = orderBy;
    }

    public String getQueryStr() {
        return queryStr;
    }

    public Object getResult() {
        return result;
    }

    public void setResult(Object result) {
        this.result = result;
    }

    public String getEncodeQueryStr() {
        if(queryStr != null && !"".equals(queryStr)) {
            try {
                return URLEncoder.encode(queryStr, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    public String getDecodeQueryStr() {
        if(queryStr != null && !"".equals(queryStr)) {
            try {
                return URLDecoder.decode(queryStr, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    public void setQueryStr(String queryStr) {
        this.queryStr = queryStr;
    }

    public String getCacheString() {
        StringBuffer cacheKey = new StringBuffer();
        cacheKey.append(this.getPageNum()).append("#");
        cacheKey.append(this.getPageSize()).append("#");
        if(StringUtils.isNotEmpty(this.getOrderBy())) {
            cacheKey.append(this.getOrderBy()).append("#");
        }
        List<String> args = new ArrayList<String>();
        setCacheList(args);
        if(args != null && !args.isEmpty()) {
            for(String arg : args) {
                if(StringUtils.isNotEmpty(arg)) {
                    cacheKey.append(arg).append("#");
                }
            }
        }
        return cacheKey.toString();
    }

    /**
     * 設(shè)置緩存KEY
     * @param cacheKeys
     */
    public void setCacheList(List<String> args) {

    }

}

總結(jié)

總的來說,Spring Data MongoDB 整體架構(gòu)方式還是類似于hibernate mybatis,只是相應(yīng)的會(huì)有一些概念的變動(dòng)。就操作性來說,對(duì)于開發(fā)人員只是熟悉相關(guān)API以及相關(guān)的概念,觸類旁通。使用來說還是很方便的。

擴(kuò)展:
諸如類似Spring Data MongoDB ORM 框架還有諸如 morphia
https://github.com/mongodb/morphia。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多