mongodb基礎操作

jopen 9年前發布 | 45K 次閱讀 MongoDB NoSQL數據庫

mongodb是一種基于文檔類型的高性能nosql數據庫,在高并發下具有優秀的表現,因此,在互聯網行業中,mongodb的使用場景將非常廣泛。

當然,mongodb主要對性能關注很多,因而沒有提供類似于關系數據庫的事務的功能,對于復雜的業務及嚴格數據一致性要求很高有企業級應用,不建議使用 mongodb(網上也有自己去實現事務提交的方案,但實現起來比較繁瑣,類似于我們早期dbase,access文件型數據庫的事務解決方案)。

其實,也不排除在企業級應用上把某些訪問壓力大的,對事務要求不嚴格的數據保存到nosql數據庫中。

spring data框架,提供了對mongodb的支持,大家可以到http://mongojack.org/,及http://www.springsource.org/spring-data/mongodb

上了解更多信息mongodb及sprig data for mongodb相關信息。

下面,我用一個簡單的實例,給大家講解mongodb的使用,在這之前,你需要下載mongodb java驅動包,spring data commons, spring data for mongodb這些組件包。

共兩個對象,客戶,客戶訂單,一對多關系,單向關聯。

客戶:

@Document
public class Customer {

    @Id
    private int id;
    private String loginCode;
    private String name;
    private String pwd;
    
    @Version
    private long varsion;
    
    private Date birthday = new Date();
    
    private Set<Order> orders = new HashSet<Order>();


訂單:

@Document
public class Order {
    @Id
    private int id;
    private String code;
    private String orderName;


spring data的配置:

@Configuration
public class MongoConfiguration {
  
    public @Bean MongoDbFactory mongoDbFactory() throws Exception {
        //需要用戶名、密碼驗證
        UserCredentials userCredentials = new UserCredentials("yq", "123");
        return new SimpleMongoDbFactory(new Mongo(), "exam", userCredentials);
        //return new SimpleMongoDbFactory(new Mongo(), "exam");
      }

      public @Bean MongoTemplate mongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactory());
      }
}

當然,上面這段信息可以配置在xml中,也可以像我上面一樣用寫在java代碼中。

這里要建立exam庫,可以在mongodb命令行下,使用 use 命令建立,比如:use exam,然后隨便添點東西在里面,庫就建好了。另外,如果要啟用認證功能,需要大家通過命令向某個庫中添加用戶(具體如db.addUser(“用戶名”,”密碼”)),啟動mongodb時使用-auth參數。

在整合過程中,如果報:

tried to access methodorg.springframework.core.GenericTypeResolver.getTypeVariableMap錯誤,是由于包版本沖突所至,請下載新的spring核心包。

下面給大家舉例說明api的使用:

我們的所有操作只需要一個MongoTemplate

@Resource
    private MongoTemplate mt;



(1)檢測一個空間是否存在 

mt.collectionExists(Customer.class);


(2)建立新空間

mt.createCollection("myCollection");


(3)統計總記錄條數,其中query可以為null,或一個建好的帶條件查數據的query,如需分頁,請先count,再查分頁數據

mt.count(new Query(), Customer.class);


(4)刪除空間,其中的數據會一并清除

mt.dropCollection("myCollection");


(5)按id號查詢

Customer c = mt.findById(1, Customer.class);


(6)刪除id號為1的客戶

mt.remove(mt.findById(1, Customer.class));


(7)刪除id號小于5的客戶
mt.remove(new Query(Criteria.where("id").lt(5)), Customer.class);


(8)查詢姓名是:張三5,并且密碼是:111的用戶
     List<Customer> cc = mt.find(new Query(Criteria.where("name").is("張三5").and("pwd").is("111")), Customer.class);
    或 List<Customer> cs = mt.find(new Query(Criteria.where("name").is("張三5").andOperator(Criteria.where("pwd").is("111"))), Customer.class);

要注意,一個criteria中只能有一個andOperator,如果要寫并列條件,直接用and就可以了。


(9)查詢姓名是:張三5,或者 密碼是:111的用戶
       List<Customer> cs = mt.find(new Query(new Criteria().orOperator(Criteria.where("name").is(" 張三5"),Criteria.where("pwd").is("111"))), Customer.class);


(10)查詢出生日期小于2013年6月6日的客戶
        List<Customer> cs = mt.find(new Query(Criteria.where("birthday").lt(new Date())), Customer.class);
        
(11)查詢出生日期等于2013年6月6日的客戶
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd-hh:mm:ss");
        List<Customer> cs = mt.find(new Query(
                Criteria.where("birthday").gte(sf.parse("2013-06-06-00:00:00"))
               .andOperator(Criteria.where("birthday").lte(sf.parse("2013-06-09-23:59:59")))
               ), Customer.class);


(12)查詢定單編號是0015或者0018的客戶
        List<Customer> cs = mt.find(new Query(new Criteria()
              .where("orders.code").in("0015","0018")
                ), Customer.class);

請注意,mongodb可以直接針對集合查詢,比如,上面的orders就是一個set集合。


(13)查詢包含四的,并以0結尾的客戶
        //(正則表 達式,以XX開頭,請用^,以XX結束,請用$,不寫這兩個,表示任意)
       List<Customer> cs = mt.find(new Query(new Criteria()
        .where("name").regex("四.*0$")
       ), Customer.class);

請注意,mongodb不支持在id上的正則查詢。
        
(14)修改對象屬性名,修改后,要同步修改對象中的屬性名,否則,此屬性值為null
        mt.updateMulti(new Query(), new Update().rename("password", "pwd"), "customer");
        
        
(15)批量修改,把id為100的客戶姓名改為tomcat999,密碼改為222
        mt.findAndModify(new Query(Criteria.where("id").is(100)), 
                new Update().set("name", "tomcat999").set("pwd", "222"), 
                Customer.class);
        
(16)修改單個對象
        Customer cc = mt.findById(100, Customer.class);
        cc.setPwd("333");
        mt.save(cc);


(17)排序及分頁實現
    public Page<Customer> getCustomerByPage(int pageNo, int pageSize, Map params) {
        
        Page<Customer> page = new Page<Customer>(pageNo, pageSize);
        
        //查詢數據
        List<Customer>data = mt
        .find(
                new Query().skip(page.getRowStartIndex())
                .limit(pageSize)
                .with(new Sort(Sort.Direction.DESC, "_id"))
        
        , Customer.class);
        
        page.setData(data);
        
        //統計總記錄數
        long count = mt.count(null, Customer.class);
        page.setRowcounts(count);
        
        return page;
    }

最后,給出幾個使用mongodb,在對象設計實踐:

  • 對象id最好設計成String類型,在新增時,如果用戶沒有賦值,mongodb會自動生成的,當然你也可以使用UUID自己賦值。

  • Springmongodb的封裝在對象間存在循環關聯的情況,在新增及查詢時都會出現堆棧溢出情況,目前的解決辦法是:

         A、切斷雙向關聯。比如:一對多雙向關聯,你可以刪除一方的集合屬性,多方對一方的引用采用dbref注解標注。一對多、多對多也如此,盡可能地簡化對象間的關系。

  B、對象間關系,最好直接建立成關系數據庫中的外鍵形式字段,即:以非面向對象的方式去建立,這就是“魚和熊掌,不可兼得”,在追求性能效率的同時,放棄更好理解的對象模型。

  • 有嚴格事務要求的業務系統,不要用mongodb

  • 如有極端的高并發大數據量查詢,請用mongodb,也可以把項目中的部分數據保存在mongodb中。

  • 一般的并發修改,可以使用樂觀鎖解決,spring mongodb支持@Version注銷。


還有,開發中最好準備一個圖型化的mongodb管理工具,比如:MongoCola,隨時查看保存的數據實況,方便調試。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!