1. 程式人生 > >Spring boot中mongodb的使用

Spring boot中mongodb的使用

MongoDB是一個介於關係資料庫和非關係資料庫之間的產品,是非關係資料庫當中功能最豐富,最像關係資料庫的。他支援的資料結構非常鬆散,是類似json的bjson格式,因此可以儲存比較複雜的資料型別。Mongo最大的特點是他支援的查詢語言非常強大,其語法有點類似於面向物件的查詢語言,幾乎可以實現類似關係資料庫單表查詢的絕大部分功能,而且還支援對資料建立索引。


傳統的關係資料庫一般由資料庫(database)、表(table)、記錄(record)三個層次概念組成,MongoDB是由資料庫(database)、集合(collection)、文件物件(document)三個層次組成。MongoDB對於關係型資料庫裡的表,但是集合中沒有列、行和關係概念,這體現了模式自由的特點。


MongoDB中的一條記錄就是一個文件,是一個數據結構,由欄位和值對組成。MongoDB文件與JSON物件類似。欄位的值有可能包括其它文件、陣列以及文件陣列。MongoDB支援OS X、Linux及Windows等作業系統,並提供了Python,PHP,Ruby,Java及C++語言的驅動程式,社群中也提供了對Erlang及.NET等平臺的驅動程式。


MySQL的適合對大量或者無固定格式的資料進行儲存,比如:日誌、快取等。對事物支援較弱,不適用複雜的多文件(多表)的級聯查詢。

MongoTemplate是資料庫和程式碼之間的介面,對資料庫的操作都在它裡面。


注:MongoTemplate是執行緒安全的.

mongodb的增刪改查 

所有先在pom.xml裡面加上下面的依賴

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
 </dependency>
然後在配置檔案中application.yml中加入以下配置。據瞭解這個是適合3.0x以上的版本,這個配置是多個庫的配置,其實單個也可以這樣配
spring:
  data:
    mongodb:
     uri: mongodb://192.168.234.28:27017,192.168.234.29:27017,192.168.234.30:27017/*****
啟用moogo的可以在整合ApplicationListener這個監聽啟動,也有在mian方法上面加註解啟動的
public class SmartTalkApplicationListener implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        if (applicationEvent instanceof ContextRefreshedEvent) {
            ApplicationContext applicationContext = ((ContextRefreshedEvent) applicationEvent).getApplicationContext();
            MongoTemplate mongoTemplate = null;
            try {
                mongoTemplate = (MongoTemplate) applicationContext.getBean("mongoTemplate");
                mongoTemplate.setReadPreference(ReadPreference.secondaryPreferred());
            } catch (BeansException e) {

            }
            new SpringContextUtil().setApplicationContext(applicationContext);
        }
    }
}
使用MongoTemplate進行CRUD
@Service
public class TalkSingleService {

    private static final String SMART_TALK__SINGLE_NAME = "SmartTalkSingle";

    @Autowired
    MongoTemplate mongoTemplate;

    /**
     * 新增
     * @param talkSingle
     */
    public void createSingle(TalkSingle talkSingle) {
        try {
            mongoTemplate.insert(talkSingle, SMART_TALK__SINGLE_NAME);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 更新
     * @param body
     * @param id
     * @return
     */
    public Boolean updateSingle(String body,Integer id){
        Update update = new Update();
        update.set("body",body);
        update.set("lastUpdateTime", (new Date()).getTime());
        Query query = new Query();
        Criteria criteria = new Criteria().orOperator(Criteria.where("id").is(id));
        query.addCriteria(criteria);
        WriteResult reslut =  mongoTemplate.updateMulti(query, update, TalkSingle.class, SMART_TALK__SINGLE_NAME);
        return reslut.isUpdateOfExisting();
    }

    /**
     * 模糊查詢列表
     * @param view
     * @return
     */
    public List<TalkSingle> getSinglePage(TalkSingleQueryDto view){
        Query query =new Query();
        Criteria criteria = Criteria.where("themeId").is(view.getThemeId());
        query.addCriteria(criteria);
        if(StringUtils.isNotBlank(view.getBody())){
            query.addCriteria(Criteria.where("body").regex(".*?"+view.getBody()+".*"));
        }
        query.addCriteria(Criteria.where("status").is(false));
        query.with(new PageRequest(view.getPageNo(),view.getPageSize()));
        List<TalkSingle> list=mongoTemplate.find(query, TalkSingle.class, SMART_TALK__SINGLE_NAME);
        return list;
    }
    /**
     *
     * @param view
     * @return
     */
    public long getSingleCount(TalkSingleQueryDto view){
        Query query =new Query();
        Criteria criteria = Criteria.where("themeId").is(view.getThemeId());
        query.addCriteria(criteria);
        if(StringUtils.isNotBlank(view.getBody())){
            query.addCriteria(Criteria.where("body").regex(".*?"+view.getBody()+".*"));
        }
        query.addCriteria(Criteria.where("status").is(false));
        return mongoTemplate.count(query, TalkSingle.class, SMART_TALK__SINGLE_NAME);
    }

    /**
     * 刪除
     * @param id
     * @return
     */
    public boolean removeSingle(Integer id){
        Update update = new Update();
        update.set("status", true);
        update.set("lastUpdateTime", (new Date()).getTime());
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        WriteResult reslut =  mongoTemplate.updateMulti(query, update, TalkSingle.class, SMART_TALK__SINGLE_NAME);
        return reslut.isUpdateOfExisting();
    }

    /**
     * 根據ID 獲取資訊
     * @param id
     * @return
     */
    public TalkSingle getSingle(Integer id){
        TalkSingle talkSingle =mongoTemplate.findOne(new Query().addCriteria(Criteria.where("id").is(id)), TalkSingle.class, SMART_TALK__SINGLE_NAME);
        return talkSingle;
    }
}

接下來討論一些跟別的資料的差別吧

moogoDB的主鍵_id

MongoDB預設會為每個document生成一個 _id 屬性,作為預設主鍵,且預設值為ObjectId,可以更改 _id 的值(可為空字串),但每個document必須擁有 _id 屬性。如果你不想使用預設的主鍵你需要插入自己的主鍵名和值(自行管理、維護),例如:userId: 20140600001。
為什麼是這樣的?粗略說來大概是這麼一句話:MongoDB是以空間換取時間和效率,本身不提供關係資料庫中常見的主鍵生成策略、事務。因此使用者或者說伺服器端需要有自己的處理邏輯。

MongoDB中的一對多、多對多關係(MongoDB中資料關係的處理)

MongoDB的基本單元是Document(文件),通過文件的巢狀(關聯)來組織、描述資料之間的關係。
例如我們要表示一對多關係,在關係型資料庫中我們通常會設計兩張表A(一)、B(多),然後在B表中存入A的主鍵,以此做關聯關係。然後查詢的時候需要從兩張表分別取資料。MongoDB中的Document是通過巢狀來描述資料之間的關係

"body":{
    "questions":[
      {"question":"問題1","key1":"value1", ...},
      {"question":"問題2"}
    ],
    "answer":"答案"
  },

mongodb 表名和欄位名統一用小寫字母
mongodb 是預設區分大小寫的,為了避免以前在 mysql 下遇到的大小寫敏感導致程式訪問頻頻出錯,
建立規範,mongodb 的表名和欄位名都用小寫字母命名。

參考一下: