• SpringData实现Mongodb的CRUD:MongoTemplate框架


        MongoTemplate实现了java代码与mongodb数据库之间的连接,是现场安全的。

    一.创建MongoTemplate实例。

        1.java code创建

          1.1)数据库无密码:

              MongoClient mongoClient = new MongoClient( "localhost" , 27017 );

              //"dbName":连接的数据库集合名称

              SimpleMongoDbFactory dbFactory = new SimpleMongoDbFactory(mongoClient , "dbName"); 

              DbRefResolver dbRefResolver = new DefaultDbRefResolver(dbFactory);

              MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext());

             converter.setTypeMapper(new DefaultMongoTypeMapper(null));

             //加入converter是去掉数据库文档中_class字段

             MongoTemplate template = new MongoTemplate(dbFactory, converter);

          1.2)数据库有密码验证

          UserCredentials userCredentials = new UserCredentials( "username", "password" );

          SimpleMongoDbFactory dbFactory = new SimpleMongoDbFactory(mongoClient , "dbName",userCredentials );

                     .....................(下步骤同上).....................

    二.MongoTemplate的Crud操作mongodb数据库

         /* 约定 */

         /*object:新增的javaBean对象。collectionName:集合名称,相当于表名。*/

        /*Collection<? extends Object> collection:批量操作时,对象的集合。例如List<User> collection*/

        /*Query query = new Query()    query:条件*/

        1.新增文档

         MongoTemplate提供了save()和insert()两种方式。

         save:新增文档时,如果有_id文档存在则修改,不存在则增加,相当于根据条件调用insert或update方法。

         insert:新增文档时,如果有_id文档存在则会新增失败,即不会修改之前的值,也不会重新增加。

         用法:

                    template.save(object);

                    template.save(object,collectionName);

                   template.insert(object);

                   template.insert(object,collectionName);

                   //批量插入

                   template.insertAll(collection);

                   template.insert(collection,collectionName);

       2.删除文档

                    template.remove(query,collectionName);

                    template.dropCollection(collectionName);//删除集合,即该张表会被删除

      3.修改文档

                   . updateFirst   只修改符合条件第一条数据

                   . updateMulti  修改符合条件的所有所有

                   . upsert          修改符合条件时如果不存在则会新增加一条数据,相当于执行了insert()方法

                   /************ Update update=new Update() : update 需要更新的内容 *****************************/

    update.set("key1", "value1")  把"key1"对应的值设置为"value1",如果数据中不存在"key1",则会新增加一条信息key1:value1
    update.inc("sum", 100) inc累加计算,即sum在原来基础上加上100,相当于sum=sum+100
    update.multiply("sum", 100) 乘法计算,即sum在原来基础上乘以100,相当于sum=sum*100
    update.rename("key2", "k2") rename用于修改键值, 即把"key2":"value2"修改为"k2":"value2"
    update.unset("key3") 删除键为"key3"的信息,即从文档中移除该键
    update.pull("array", "a1") 删除array数组中的"a1"。 例如"array":["a1","a2","a3"],删除"a1"后的结果 "array":["a2","a3"]
    update.pullAll("array", Object[] values) 可一次性删除数组内多个值
    update.push("array","a3") 向array数组里添加"a3"(不会检查数组中元素是否重复), 数组"array"不存在则会新建该数组。修改后结果"array":["a2","a3","a3"]
    update.pushAll("array", Object[] values) 可一次性向数组内添加多个值
    update.addToSet("array","a3") 向array数组里添加"a3"(会检查数组中元素是否重复), 数组"array"不存在则会新建该数组。修改后结果"array":["a2","a3"]
    update.pop("array",Update.Position.FIRST) 从"array"数组 开头/结尾(Update.Position.FIRST/Update.Position.LAST) 移除一个元素

              /*****************************  执行更新操作 *************************************/

                       //更新符合query条件的第一条数据

                       template.updateFirst(query, update, collectionName);

                       //更新符合query条件的所有数据

                       template.updateMulti(query, update, collectionName);

                      //更新符合条件时如果不存在则会新增加一条数据,相当于执行了insert()方法

                       template. upsert(query, update, collectionName);

        4.查询操作

    /**************************** 准备query *****************************************/     

                              Query query=new Query();

                              Query query=new Query(CriteriaDefinition criteriaDefinition);

         !CriteriaDefinition是接口,Criteria是其实现类

    /**************************** 设置query条件 *****************************************/ 

    一些常用的Query方法
    返回类型 方法 说明 应用例子
    Query addCriteria(Criteria criteria) 向query里追加查询条件 query.addCriteria(Criteria.where("name").is("jack"));
    Query  skip(int skip) 从第skip下标数据开始查询,跳过skip下标之前的数据,小标从0开始 query.skip(skip);
    Query  limit(int limit) 限制返回数据的最大条数 query.limit(limit);
    Query  withHint(String name) 做强迫索引查询用  
    Query  with(Sort sort) 可用于排序用

    query.with(new Sort(Sort.Direction.DESC,"time"));

    query.with(new Sort(Sort.Direction.ASC,"time"));

    Query with(Pageable pageable) Pageable对象里有skip,limit,sort信息,所以做可以分页和排序  
    static Query query(Criteria criteria)   Query.query(Criteria.where("name").is("jack"));
    DBObject  getQueryObject()     
    Field fields()

    Field 可用于做指定字段查询query.fields().include("age").exclude("name");

    还可用做返回指定字段时的工具(后面有例子)

    query.fields()
    Criteria类常用方法
    static Criteria where(String key) 创建一个key,即查询的key键 query.addCriteria(Criteria.where("name").is("jack"));
    static Criteria

    byExample(Object example)

      () 
    static Criteria

    byExample(Example<?> example)

       ()
    Criteria is(Object obj) 等于(==) obj  query.addCriteria(Criteria.where("name").is("obj"));
    Criteria and(String key) 并且,用于多个字段同时查询  query(where("key1").is("value1").and("key2").is("value2")); 
    Criteria ne(Object o) 不为 (不等于)

    query(where("siteId").ne(null));//查询siteId不为空的数据

    query(where("name").ne("不为该值"));//

    Criteria lt(Object o) 小于(<

    query.addCriteria(Criteria.where("insert_date").gte(Date1).lte(Date2));

    query.addCriteria(Criteria.where("age").gte(20).lte(30));

    Criteria lte(Object o) 小于等于(<=
    Criteria gt(Object o) 大于(>)
    Criteria gte(Object o) 大于等于(>=)
    Criteria

    in(Object... co)

     在...里(key对应的数据被包含在 co 里)

        String[] strs=... ;

    query.addCriteria(Criteria.where("name").in((Object[]) strs));

    或query.addCriteria(Criteria.where("name").in(obj1,obj2,obj3,...));

    Criteria

    in(Collection<?> co)

       List<Object> collec=...;

    query.addCriteria(Criteria.where("key").in(collec));

    Criteria

    nin(Object... o)

    不在...里(与in相反)      (略)
    Criteria

    nin(Collection<?> o)

    Criteria mod(Number value, Number remainder)

    取模(求余)运算 ,即:key对应的值%value==remainder(求余是否等于remainder)

       // {key:15} {key2:15}

    query.addCriteria(Criteria.where("key").mod(10,3)); 

     //key条件不成立;key2条件成立

    Criteria

    all(Object... col)

    key键对应的集合包含col(all是包含关系,in是被包含关系)

    query.addCriteria(Criteria.where("key").all("n1","n2"));//此时key对应的值应该是集合 

    query.addCriteria(Criteria.where("nameList").all((Object[]) names)));

    Criteria

    all(Collection<?> col)

         List<Object> collec=...;

    query.addCriteria(Criteria.where("key").all(collec));

    Criteria

    size(int s)

    匹配key所对应的集合的元素的指定数量(!!!不能进行像<5之类的范围匹配) 

     // {key:["foo","lue","cua"]}

    query.addCriteria(Criteria.where("key").size(3));

    Criteria exists(boolean b) 查询字段是否存在(true:存在,false:不存在)  query.addCriteria(Criteria.where("confirmTime").exists(false));
    Criteria type(int t)    
    Criteria not() 取反  

          //注意:not().is()这样是错误的,not()后面不用跟is()

      query.addCriteria(Criteria.where("number").not().lte(2)); //number<=2取反,即number>2

    Criteria regex(String re) 模糊查询用  (例子见下)
    Criteria regex(String re, String options)

    options可选值:i/m/x/s

    //i表示不区分大小写

    //m能使用^以及$等正则表达式来识别数据库中使用 换行的每一行开始字符以及字符。

    //x

    //s如果设置了这个修饰符,模式中的点号元字符匹配所有字符,包含换行符。如果没有这个修饰符,点号不匹配换行符。

    Criteria regex(Pattern pattern)

    Pattern pattern = Pattern.compile("正则表达式"); 

    query.addCriteria(Criteria.where("resourceName").regex(pattern));

           
    Criteria  orOperator(Criteria... criteria)

    多个Criteria多个条件的或(or)操作

    (a || b)

    Criteria c1=Criteria.where("name").is("张三"));

    Criteria c2=Criteria.where("age").is(25));

    query.addCriteria(new Criteria().orOperator(c1, c2)); 

    Criteria  norOperator(Criteria... criteria)

    执行mongodb的$nor操作,意思是:

    返回 不满足$or条件 的文档

    即返回 不满足(a || b)的文档

     (语法同orOperator)
    Criteria  andOperator(Criteria... criteria)

    多条件(and)操作

    (a && b

    (同orOperator
    Criteria  elemMatch(Criteria c)

    对象数组里的参数查询

    "users":[{"name":"张三","age":20,"hobby":"internet"},{},...]

    Criteria cri=Criteria.where("name").is("张三"));

    query.addCriteria(Criteria.where(users).elemMatch(cri);

    Criteria  registerCriteriaChainElement(Criteria criteria)    
           
    Criteria alike(Example<?> sample)    
    Criteria withinSphere(Circle circle)    
    Criteria within(Shape shape)    
    Criteria near(Point point)    
    Criteria nearSphere(Point point)    
    Criteria intersects(GeoJson geoJson)    
    Criteria maxDistance(double maxDistance)    
    Criteria minDistance(double minDistance)    
           
    boolean lastOperatorWasNot()    
    Pattern toPattern(String regex, String options)    
    String getKey()    
    DBObject getCriteriaObject()    
    DBObject getSingleCriteriaObject()    
    BasicDBList createCriteriaList(Criteria[] criteria)    
    void setValue(DBObject dbo, String key, Object value)    
    boolean createNearCriteriaForCommand(String command, String operation, double maxDistance)    
    boolean simpleCriteriaEquals(Criteria left, Criteria right)    
    boolean isEqual(Object left, Object right)    
    int hashCode()    
    static boolean requiresGeoJsonFormat(Object value)    

        /** 利用regex做迷糊查询 **/  

           private String regexFilter(String regex) {
                 if (regex.equals("*")) {
                       return "\" + regex;
                 } else {
                     return regex;
                 }
             }

          query.addCriteria(Criteria.where("name").regex(".*" + regexFilter("StringValue") + ".*"));

       /****/

      /**************************** 分页 *****************************************/

            方式一:   

                 (单个字段排序)

                query.with(new Sort(Sort.Direction.DESC,"time"));

                query.with(new Sort(Sort.Direction.ASC,"time"));

                  (多个字段同事排序)

                 query.with(new Sort(Direction.ASC,"time1","time2","time3"));

                  (不同字段不同排序)

                 List<Sort.Order>orderList=new ArrayList<Sort.Order>();  

                 orderList.add(new Sort.Order(Direction.ASC, "time1"));  

                 orderList.add(new Sort.Order(Direction.DESC, "tim2"));  

                 query.with(new Sort(orderList));  

                  先按照time1升序,在按照time2降序

           方式二:

                 int page=3;//第几页
                 int size=30;//每页条数
                 Sort sort=new Sort(Sort.Direction.ASC, "update_time");//排序,多条件排序同上
                 Pageable pageable=new PageRequest(page, size, sort);
                 query.with(pageable);

    /**************************** 排序 *****************************************/ 

         方式一:

           query.skip(skip);

           query.limit(limit);

         方式二:

            (同上—分页)

    /**************************** 返回指定字段 *****************************************/ 

         利用 BasicQuery指定返回的字段

        方式一:

         BasicDBObject queryObject=new BasicDBObject();

         BasicDBObject  fieldsObject=new BasicDBObject();//fieldsObject可以指定返回字段

         fieldsObject.put(key,val);

          //key:数据库的字段

          //val:1或true表示返回;0或false表示不返回。

          !注:_id默认是1,没指定返回该字段时,默认会返回,只有设置为0就不会返回该字段。

          Query query=new BasicQuery(queryObject, fieldsObject)

         方式二:(利用 Field 类)

         BasicDBObject queryObject=new BasicDBObject();

         Field  field = new Field();  

         field.exclude("key1");//不返回key1,等同于把 fieldsObject.put(key,val)的val设置为0.

         field.include("key2");//返回key2,等同于把 fieldsObject.put(key,val)的val设置为1.

         BasicDBObject  fieldsObject=field.getFieldsObject();

         Query query=new BasicQuery(queryObject, fieldsObject);

     /**************************** 执行template *****************************************/ 

         collectionName:数据库集合名,即表名。

         query:上面生成的条件。

         entityClass:返回的数据被映射成的类型。

    MongoTemplate提供的一些常用crud方法
    返回类型 方法名 example 说明
    <T> T findOne(Query query, Class<T> entityClass, String collectionName) User user=template.findOne(query, User.class, "collectionName"); 查询返回一条数据
    <T> List<T>  find(Query query, Class<T> entityClass, String collectionName) List<User> users= template.find(query, User.class, "collectionName"); 查询满足条件的所有 
    <T> List<T> findAll(Class<T> entityClass, String collectionName)  List<User> users= template.findAll(User.class, "collectionName");  查询该张表所有数据 
    <T> List<T> 

    findAllAndRemove(Query query,Class<T> entityClass,String

    collectionName) 

       
    <T> T  findAndRemove(Query query, Class<T> entityClass, String collectionName)     
    <T> T findAndModify(Query query, Update update, Class<T> entityClass, String collectionName)     
    <T> T  findById(Object id, Class<T> entityClass, String collectionName)     
           
                 插入(新增)相关方法  
    void  save(Object objectToSave, String collectionName) 

    User user=.....;

    template.save(user, "collectionName"); 

     
    void  insert(Object objectToSave, String collectionName)   template.insert(user, "collectionName");   存入单个对象 
    void  insert(Collection<? extends Object> batchToSave, String collectionName) 

    List<User> users=....;

    template.insert(users, "collectionName"); 

    可以存入对象集合 
           
              删除相关方法
    void  dropCollection(String collectionName)    该张表全部数据会被删除 
    WriteResult remove(Query query, String collectionName)  template.remove(query, "collectionName");   
    WriteResult  remove(Query query, Class<?> entityClass, String collectionName)     
           
            修改文档相关方法
    WriteResult  updateFirst(Query query, Update update, String collectionName) template.updateFirst(query, update, "collectionName"); //更新符合query条件的第一条数据
    WriteResult  updateFirst(Query query, Update update, Class<?> entityClass, String collectionName)    
    WriteResult  updateMulti(Query query, Update update, String collectionName) template.updateMulti(query, update, "collectionName"); //更新符合query条件的所有数据
    WriteResult  updateMulti(Query query, Update update, Class<?> entityClass, String collectionName)    
    WriteResult  upsert(Query query, Update update, String collectionName) templateupsert(query, update, collectionName);  //更新符合条件时如果不存在则会新增加一条数据,相当于执行了insert()方法
    WriteResult  upsert(Query query, Update update, Class<?> entityClass, String collectionName)    
           
           统计数据数量
    long  count(Query query, String collectionName)     
           
         查询是否存在
    boolean exists(Query query, String collectionName)    
           
           
           

             

     /**  分组,聚合查询group **/

    方法一:利用 类 DBCollection 的 group 方法。

           方法:1.DBObject group(DBObject key, DBObject cond, DBObject initial, String reduce);

                   2.DBObject group(DBObject key, DBObject cond, DBObject initial, String reduce, String finalize);

                   3.DBObject group(DBObject key, DBObject cond, DBObject initial, String reduce, String finalize, ReadPreference readPreference)

    1. key:指定一个或多个文档字段进行分组。和keyf两者必须有一个
    2. keyf:可以接受一个javascript函数。用来动态的确定分组文档的字段。和key两者必须有一个
    3. initial:reduce中使用变量的初始化, 初始化聚合结果文档。
    4. reduce:执行的reduce函数。函数需要返回值。
    5. cond:执行过滤的条件。
    6. finallize:在reduce执行完成,结果集返回之前对结果集最终执行的函数。可选的

        DBCollection dbc=template.getCollection("collectionName");

        String reduce = "function(doc,prev){ " +
                              " prev.count+=1; " +
                              " }";

        DBObject  key=new BasicDBObject("state",1);

        DBObject cond=query.getQueryObject();

        DBObject initial=new BasicDBObject("count",0);

        DBObject result = dbc.group(key, cond, initial, reduce);

        Map map = result.toMap();

        for (Map.Entry o : map.entrySet()) {

            System.out.println(o.getKey() + " " + o.getValue());

        }

        

    方法二:aggregate聚合

          方法:aggregate(Aggregation aggregation, String collectionName, Class<O> outputType);

    1. Aggregation aggregation
    2. TypedAggregation<?> aggregation
    3. Class<O> outputType: 输出类型,可以指定具体的实体类型。
    4. String inputCollectionName:。
    5. Class<?> inputType:一个输入类型,也就是对哪个集合进行操作。
    6. String collectionName:

          

         !注:Aggregation 提供了一系列mongoDB的操作方法,比如match,unwind,limit...等等。

          Criteria criteria = where("...").....

         AggregationOperation match = new MatchOperation(criteria);

          

         UnwindOperation unwind = new UnwindOperation(Fields.field("values"));

         SortOperation sort = new SortOperation(new Sort("..."));

      

        AggregationOperation group = new GroupOperation(Fields.fields("deviceId")).first("deviceId").as("deviceId").count().as("value");

        

       AggregationOperation projection = new ProjectionOperation(fields("events")).and("_id").as("deviceId").andExclude("_id");

             

         Aggregation aggregation = Aggregation.newAggregation(match, unwind, sort, group, projection);

         AggregationResults<User> aggRes = mongoTemplate.aggregate(aggregation, "collectionName", User.class);

         List<User> listUser = aggRes.getMappedResults();

        (一般可用 BasicDBObject 这个类接受,而不用User)

  • 相关阅读:
    IDEA中写xml配置文件的时候没有代码提示
    Spring事务中的readonly
    解决IDEA项目名称无下标蓝色小方块
    【24小时内第四更】为什么我们要坚持写博客?
    .Net架构篇:实用中小型公司支付中心设计
    .NetCore外国一些高质量博客分享
    .Net业务搭配实用技术栈
    .NetCore实践爬虫系统(一)解析网页内容
    APM实践目录
    docker环境部署
  • 原文地址:https://www.cnblogs.com/qingming/p/6419474.html
Copyright © 2020-2023  润新知