一.简介

   今天我们要介绍Java代码实现对MongoDB实现添加和删除操作。

二.添加

Spring  Data  MongoDB 的MongoTemplate提供了两种存储文档方式,分别是save和insert方法,这两种的区别:

  (1)save :我们在新增文档时,如果有一个相同_ID的文档时,会覆盖原来的。

  (2)insert:我们在新增文档时,如果有一个相同的_ID时,就会新增失败。

 

 1.接下来我们分别介绍的两种方式的具体语法。

 

(1)Save方式

        方法:

        1)void save (Object objectToSave) 保存文档到默认的集合。

        2)void save(Object objectToSave, String collectionName) 对指定的集合进行保存。

(2) Insert方式

     方法:

      1)void insert(Object objectToSave) 保存文档到默认的集合。

      2)void insertAll(Object objectsToSave) 批量添加到默认的集合。

      3)void insert(Object objectToSave, String collectionName) 对指定的集合进行保存。


 2. Spring实现MongoDB的添加操作

     我们在上一篇有介绍了,Spring Data MongoDB环境的搭建,这里不在具体介绍,我们直接实战。

    (1)介绍接口以及实现方法


第一步:实现一个基础接口,是比较通用的 MongoBase.java类 



[java]  view plain  copy




1.      public interface MongoBase<T> {  
2. // insert添加  
3. public void insert(T object,String collectionName);   
4. // save添加  
5. public void save(T object,String collectionName);   
6. //批量添加  
7. public void insertAll(List<T> object);   
8.      }


        

第二步:我们实现文档的结构,也是实体类。

      我们这边有两个实体类,订单类(Orders.java)和对应订单详情类(Item.java),这里我们实现内嵌文档。如果没有内嵌文档的结构,只要对一个实体类的操作就OK。


         1)Orders.Java


[java]  view plain  copy



1. /**
2.  * 订单
3.  * @author zhengcy
4.  *
5.  */  
6. public class Orders implements Serializable {  
7. /**
8.      * 
9.      */  
10. private static final long serialVersionUID = 1L;  
11. //ID  
12. private String id;  
13. //订单号  
14. private String onumber;  
15. //日期  
16. private Date date;  
17. //客户名称  
18. private String cname;  
19. //订单  
20. private List<Item> items;  
21.       
22. public String getId() {  
23. return id;  
24.     }  
25. public void setId(String id) {  
26. this.id = id;  
27.     }  
28. public Date getDate() {  
29. return date;  
30.     }  
31. public void setDate(Date date) {  
32. this.date = date;  
33.     }  
34. public String getCname() {  
35. return cname;  
36.     }  
37. public void setCname(String cname) {  
38. this.cname = cname;  
39.     }  
40. public String getOnumber() {  
41. return onumber;  
42.     }  
43. public void setOnumber(String onumber) {  
44. this.onumber = onumber;  
45.     }  
46. public List<Item> getItems() {  
47. return items;  
48.     }  
49. public void setItems(List<Item> items) {  
50. this.items = items;  
51.     }  
52.   
53. }


        2) Item.java  

[java]  view plain  copy



1. /**
2.  * 产品订购表
3.  * @author zhengcy
4.  *
5.  */  
6. public class Item {  
7.       
8. //数量  
9. private Integer quantity;  
10. //单价  
11. private Double price;  
12. //产品编码  
13. private String pnumber;  
14. public Integer getQuantity() {  
15. return quantity;  
16.     }  
17. public void setQuantity(Integer quantity) {  
18. this.quantity = quantity;  
19.     }  
20. public Double getPrice() {  
21. return price;  
22.     }  
23. public void setPrice(Double price) {  
24. this.price = price;  
25.     }  
26. public String getPnumber() {  
27. return pnumber;  
28.     }  
29. public void setPnumber(String pnumber) {  
30. this.pnumber = pnumber;  
31.     }  
32. }


       第三步:实现OrdersDao类,就是实现Orders自己操作数据库的接口,这个OrdersDao也继承了MongoBase接口,我们这边OrdersDao没实现其他额外的接口。


         

[java]  view plain  copy




    1. /**
    2.  * 订单Dao
    3.  * @author zhengcy
    4.  *
    5.  */  
    6. public interface OrdersDao extends MongoBase<Orders> {  
    7.   
    8.   
    9. }



      第四步:实现OrdersDaoImpl具体类,这边是实际操作数据库。

             


    [java]  view plain  copy



    1.  /**
    2.  * 订单实现
    3.  * @author zhengcy
    4.  *
    5.  */  
    6. @Repository("ordersDao")  
    7. public class OrdersDaoImpl implements OrdersDao {  
    8. @Resource  
    9. private MongoTemplate mongoTemplate;  
    10.   
    11. @Override  
    12. public void insert(Orders object, String collectionName) {  
    13.         mongoTemplate.insert(object, collectionName);  
    14.           
    15.     }  
    16.       
    17.       
    18. @Override  
    19. public void save(Orders object, String collectionName) {  
    20.         mongoTemplate.save(object, collectionName);  
    21.           
    22.     }  
    23.       
    24. @Override  
    25. public void insertAll(List<Orders> objects) {  
    26.         mongoTemplate.insertAll(objects);  
    27.           
    28.     }  
    29. }


        

    (2)实现测试类,我们进行测试

          我们这边为了节省时间,就没写服务类,我们直接调用dao就可以了,实现了TestOrders.java类

            


    [java]  view plain  copy



    1. /**
    2.  * 测试订单
    3.  * @author zhengcy
    4.  *
    5.  */  
    6. public class TestOrders {  
    7. private static OrdersDao ordersDao;  
    8. private static  ClassPathXmlApplicationContext  app;  
    9. private static String collectionName;  
    10. @BeforeClass    
    11. public static void initSpring() {   
    12. try {  
    13. new ClassPathXmlApplicationContext(new String[] { "classpath:applicationContext-mongo.xml",    
    14. "classpath:spring-dispatcher.xml" });    
    15. "ordersDao");   
    16. "orders";  
    17. catch (Exception e) {  
    18.             e.printStackTrace();  
    19.         }  
    20.          }   
    21.       
    22. //测试Save方法添加  
    23. @Test   
    24. public void testSave() throws ParseException  
    25.     {  
    26.           
    27.     }  
    28. //测试Insert方法添加  
    29. @Test   
    30. public void testInsert() throws ParseException  
    31.     {  
    32.           
    33.     }  
    34. //测试InsertAll方法添加  
    35. @Test   
    36. public void testInsertAll() throws ParseException  
    37.     {  
    38.           
    39.     }  
    40. }

       

               

          1)测试Save方法添加


                

    [java]  view plain  copy



    1.        //测试Save方法添加  
    2. @Test   
    3. public void testSave() throws ParseException  
    4. {  
    5. new SimpleDateFormat("yyyy-mm-dd");  
    6. //订单  
    7. new Orders();  
    8. "001");  
    9. "2015-07-25"));  
    10. "zcy");  
    11. //订单详情  
    12. new ArrayList<Item>();  
    13. new Item();  
    14. "p001");  
    15. 4.0);  
    16. 5);  
    17.         items.add(item1);  
    18. new Item();  
    19. "p002");  
    20. 8.0);  
    21. 6);  
    22.         items.add(item2);  
    23.         order.setItems(items);  
    24.         ordersDao.insert(order,collectionName);  
    25. }


              

    mongodb insert 时序数据 mongodb insert save_Test


            我们到MongoDB查询时,订单内嵌订单详情的文档,说明我们成功新增文档。

             测试Insert方法添加,这边就不在详情的介绍,跟Save方法一样。

           

            2)测试InsertALL方法添加

                


    [java]  view plain  copy



    1.       //测试InsertAll方法添加  
    2. @Test   
    3. public void testInsertAll() throws ParseException  
    4. {  
    5. new ArrayList<Orders>();  
    6. for(int i=1;i<=10;i++){  
    7. new SimpleDateFormat("yyyy-mm-dd");  
    8. //订单  
    9. new Orders();  
    10. "00"+i);  
    11. "2015-07-25"));  
    12. "zcy"+i);  
    13. //订单详情  
    14. new ArrayList<Item>();  
    15. new Item();  
    16. "p00"+i);  
    17. 4.0+i);  
    18. 5+i);  
    19.         items.add(item1);  
    20. new Item();  
    21. "p00"+(i+1));  
    22. 8.0+i);  
    23. 6+i);  
    24.         items.add(item2);  
    25.         order.setItems(items);  
    26.         orders.add(order);  
    27.     }  
    28.     ordersDao.insertAll(orders);  
    29. }<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>

            我们批量添加10条订单内嵌订单详情的文档,我们在MongoDB查询时,有查到数据,说明我们插入成功。



          

    [sql]  view plain  copy



    1. > db.orders.find()  
    2. "_id" : ObjectId("55b387ebee10f907f1c9d461"), "_class" : "com.mongo.model.Orders", "onumber" : "001", "date" : ISODate("2015-01-24T16:07:00Z"), "cname"        : "zcy1", "items" : [ { "quantity" : 6, "price" : 5, "pnumber" : "p001" }, { "quantity" : 7, "price" : 9, "pnumber" : "p002" } ] }  
    3. "_id" : ObjectId("55b387ebee10f907f1c9d462"), "_class" : "com.mongo.model.Orders", "onumber" : "002", "date" : ISODate("2015-01-24T16:07:00Z"), "cname"        : "zcy2", "items" : [ { "quantity" : 7, "price" : 6, "pnumber" : "p002" }, { "quantity" : 8, "price" : 10, "pnumber" : "p003" } ] }  
    4. "_id" : ObjectId("55b387ebee10f907f1c9d463"), "_class" : "com.mongo.model.Orders", "onumber" : "003", "date" : ISODate("2015-01-24T16:07:00Z"), "cname" :      "zcy3", "items" : [ { "quantity" : 8, "price" : 7, "pnumber" : "p003" }, { "quantity" : 9, "price" : 11, "pnumber" : "p004" } ] }  
    5. { "_id" : ObjectId("55b387ebee10f907f1c9d464"), "_class" : "com.mongo.model.Orders", "onumber" : "004", "date" : ISODate("2015-01-24T16:07:00Z"), "cname" :       "zcy4", "items" : [ { "quantity" : 9, "price" : 8, "pnumber" : "p004" }, { "quantity" : 10, "price" : 12, "pnumber" : "p005" } ] }  
    6. { "_id" : ObjectId("55b387ebee10f907f1c9d465"), "_class" : "com.mongo.model.Orders", "onumber" : "005", "date" : ISODate("2015-01-24T16:07:00Z"), "cname" :       "zcy5", "items" : [ { "quantity" : 10, "price" : 9, "pnumber" : "p005" }, { "quantity" : 11, "price" : 13, "pnumber" : "p006" } ] }  
    7. ...........  
    8. >


        

        3)如果面对相同的_ID时,我们在使用Save和Insert时,会碰到我们前面介绍的那样?我们测试一下就知道了。

              我们在新增文档时,如果不设置_ID属性值,文档添加到MongoDB时,对于objectID的ID属性/字段自动生成一个字符串,带有索引和唯一性。如果我们指定_ID属性值时,速度会很慢,因为_ID默认是有索引的。


               

    [sql]  view plain  copy



    1. > db.orders.find()  
    2. "_id" : "1", "_class" : "com.mongo.model.Orders", "onumber" : "001", "date" :ISODate("2015-01-24T16:07:00Z"), "cname" : "zcy1", "items" : [ { "quantit       y" : 5,"price" : 4, "pnumber" : "p001" }, { "quantity" : 6, "price" : 8, "pnumber" : "p002" } ] }

          ObjectId值"_id": "1"已经存在,我们分别对Save和Insert方法新增文档时,指定已经存在"_id": "1"。


            1.测试Insert方法添加

                   


    [java]  view plain  copy



    1.       //测试Insert方法添加  
    2. @Test   
    3. public void testInsert() throws ParseException  
    4. {  
    5. new SimpleDateFormat("yyyy-mm-dd");  
    6. //订单  
    7. new Orders();  
    8. "1");  
    9. "002");  
    10. "2015-07-25"));  
    11. "zcy2");  
    12. //订单详情  
    13. new ArrayList<Item>();  
    14. new Item();  
    15. "p003");  
    16. 4.0);  
    17. 5);  
    18.         items.add(item1);  
    19. new Item();  
    20. "p003");  
    21. 8.0);  
    22. 6);  
    23.         items.add(item2);  
    24.         order.setItems(items);  
    25.         ordersDao.insert(order,collectionName);  
    26. }

            我们添加相同的ID时,执行添加文档时,添加出现错误

         

    org.springframework.dao.DuplicateKeyException:insertDocument :: caused by :: 11000 E11000 duplicate key error index:test.orders.$_id_  dup key: { :"1" }; nested exception is com.mongodb.MongoException$DuplicateKey:insertDocument :: caused by :: 11000 E11000 duplicate key error index:test.orders.$_id_  dup key: { :"1" }

               

         调用持久层类的进行保存域更新的时候,主键或唯一性约束冲突。

           2.测试Save方法添加

              


    [java]  view plain  copy



    1.       //测试Save方法添加    
    2. @Test   
    3. public void testSave() throws ParseException  
    4. {  
    5. new SimpleDateFormat("yyyy-mm-dd");  
    6. //订单  
    7. new Orders();  
    8. "1");  
    9. "002");  
    10. "2015-07-25"));  
    11. "zcy2");  
    12. //订单详情  
    13. new ArrayList<Item>();  
    14. new Item();  
    15. "p003");  
    16. 4.0);  
    17. 5);  
    18.         items.add(item1);  
    19. new Item();  
    20. "p003");  
    21. 8.0);  
    22. 6);  
    23.         items.add(item2);  
    24.         order.setItems(items);  
    25.         ordersDao.save(order,collectionName);  
    26. }

                  

         我们添加相同的ID时,如果已经存在,会对相对应的文档进行更新,调用update更新里面的文档。

         


    [sql]  view plain  copy



    1. > db.orders.find()  
    2. "_id" : "1", "_class" :"com.mongo.model.Orders", "onumber" : "002","date" :ISODate("2015-01-24T16:07:00Z"),"cname" : "zcy2", "items" : [ {"quantity"        : 5,"price": 4, "pnumber" : "p003" }, { "quantity" : 6,"price" : 8, "pnumber" : "p003" } ] }


      说明:

        (1)save :我们在新增文档时,如果有一个相同_ID的文档时,会覆盖原来的。

        (2)insert:我们在新增文档时,如果有一个相同的_ID时,就会新增失败。


         (3)MongoDB提供了insertAll批量添加,可以一次性插入一个列表,效率比较高,save则需要一个一个的插入文档,效率比较低。


        

    三、删除文档、删除集合

     

        1.      删除文档

     

                    Spring  Data MongoDB 的MongoTemplate提供删除文档如下几个方法:

                    

    mongodb insert 时序数据 mongodb insert save_mongodb insert 时序数据_02

                   1) 我们这边重点根据条件删除文档

                      第一步:我们在基础接口MongoBase.java类新增一个根据条件删除文档的接口  。    


    [java]  view plain  copy



    1. //根据条件删除  
    2. public void remove(String field,String value,String collectionName);

                  第二步:我们在OrdersDaoImpl类添加一个具体根据条件删除文档的实现方法。


                          

    [java]  view plain  copy



                   

    1.        @Override  
    2. ublic void remove(Map<String, Object> params,String collectionName) {  
    3. mongoTemplate.remove(new Query(Criteria.where("id").is(params.get("id"))),User.class,collectionName);

    [sql]  view plain  copy



    1. > db.orders.find()  
    2. { "_id" : "1", "_class" : "com.mongo.model.Orders", "onumber" : "001", "date" :ISODate("2015-01-24T16:07:00Z"), "cname" : "zcy1", "items" : [ { "quantity" :   5,"price" : 4, "pnumber" : "p001" }, { "quantity" : 6, "price" : 8, "pnumber" : "p002" } ] }  
    3. { "_id" : "2", "_class" : "com.mongo.model.Orders", "onumber" : "002", "date" :ISODate("2015-01-24T16:07:00Z"), "cname" : "zcy2", "items" : [ { "quantity" :   5,"price" : 4, "pnumber" : "p003" }, { "quantity" : 6, "price" : 8, "pnumber" : "p004" } ] }  
    4. >


       现在查询MongoDB有两条文档

           2)实现测试类


                        

    [java]  view plain  copy



    1.        @Test   
    2. public void testRemove() throws ParseException  
    3. {  
    4. "onumber","002", collectionName);  
    5. }

         

            我们根据onumber=002条件删除文档


    [sql]  view plain  copy




      1. > db.orders.find()  
      2. "_id" : "1", "_class" : "com.mongo.model.Orders", "onumber" : "001", "date" :ISODate("2015-01-24T16:07:00Z"), "cname" : "zcy1", "items" : [ { "quantity" :  5,"price" : 4, "pnumber" : "p001" }, { "quantity" : 6, "price" : 8, "pnumber" : "p002" } ] }



              只剩下onumber=001的文档。

             删除orders的数据,集合还存在,索引都还存在,相当与SQ的truncate命令。


           2.      删除集合

       

                       第一步:我们在基础接口MongoBase.java类新增一个根据条件删除集合的接口。       


      [java]  view plain  copy




        1. //删除集合  
        2. public void dropCollection(String collectionName);


                           

                       第二步:我们在OrdersDaoImpl类添加一个具体根据条件删除集合的实现方法。

                                    


        [java]  view plain  copy



        1.        @Override  
        2. ublic void dropCollection(String collectionName) {  
        3. mongoTemplate.dropCollection(collectionName);

                         集合、索引都不存在了,类型SQL的drop。