• MongoDB SpringBoot 批量更新


    • 最近考虑对原有得Mongo库操作进行优化,老的逻辑会频繁得操纵库,而且还是单条得,性能担忧啊,所以考虑将单条更新转换成批量更新,话不多说,直接上代码.
    1. 添加一个供批量操作得对象
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class BatchUpdateOptions {
        private Query query;
        private Update update;
        private boolean upsert = true;
        private boolean multi = false;
    }
    
    1. 创建批量操作的Dao
    public class MongoBaseDao {
        /**
         * 批量更新
         * @param ordered 如果为true,一条语句更新失败,剩下的语句将不再执。如果为false,一条语句更新失败,剩下的将继续执行。默认为true。
         * @return
         */
        public static int batchUpdate(MongoTemplate mongoTemplate, String collectionName, List<BatchUpdateOptions> options, boolean ordered) {
            return doBatchUpdate(mongoTemplate, collectionName, options, ordered);
        }
        private static int doBatchUpdate(MongoTemplate mongoTemplate, String collName, List<BatchUpdateOptions> options, boolean ordered) {
            try{
                //        BasicDBObject command = new BasicDBObject();
                Document command = new Document();
                command.put("update", collName);
                List<Document> updateList = options.stream().map(option -> {
                    Document update = new Document();
                    update.put("q", option.getQuery().getQueryObject());
                    update.put("u", option.getUpdate().getUpdateObject());
                    update.put("upsert", option.isUpsert());
                    update.put("multi", option.isMulti());
                    return update;
                }).collect(Collectors.toList());
                command.put("updates", updateList);
                command.put("ordered", ordered);
                Document document = mongoTemplate.getDb().runCommand(command);
                System.out.println("doc:"+document);
                System.out.println("doc--n:"+document.get("n"));
                System.out.println("doc--nModified:"+document.get("nModified"));
                // n为符合Query查询的记录总数 因为是根据id进行的查询, 原则上只要符合查询的记录数等于要更新的数量就代表成功
                Object n = document.get("n");
                System.out.println("doc--n--class:"+n.getClass());
                if(n.getClass()==Integer.class){
                    return (Integer)n;
                }
                return Integer.parseInt(String.valueOf(n));
            }catch (Exception e){
                e.printStackTrace();
            }
            return 0;
        }
    
    1. Test
    List<User> userList = new ArrayList();
    User us = new User();
    us.setId(1);
    us.setName("张三");
    userList.add(us);
    
    List<BatchUpdateOptions> collect = userList.stream().map(user -> {
    	Update update = BeanConversionValue.setUpdateValue(user,mongoConverter);
    	Query query = Query.query(Criteria.where("id").is(user.getId()).and("name").is("张三"));
    	return new BatchUpdateOptions(query, update, true, true);
    }).collect(Collectors.toList());
    int num = MongoBaseDao.batchUpdate(mongoTemplate, HotelConstant.EBK_INVENTORY_COLLECTION, collect, true);
    System.out.println("更新数量是:{}",num);
    
    1. 添加一个工具类
    public class BeanConversionValue {
    
        public static Update setUpdateValue(Object op,MongoConverter mongoConverter){
            Update update = new Update();
            Field[] declaredFields = op.getClass().getDeclaredFields();
            for(Field field: declaredFields){
                String key = field.getName();// 获取属性名
                String method = key.substring(0,1).toUpperCase()+key.substring(1);// 将属性首字符大写,方便get & set 方法
                try {
                    Method setmethod = null;
                    if(StringUtils.equals(field.getType().getName(),"boolean")){
                        setmethod = op.getClass().getMethod("is"+method);// 获取 get 方法
                    }else{
                        setmethod = op.getClass().getMethod("get"+method);// 获取 get 方法
                    }
                    Object value = setmethod.invoke(op);// 通过 get 获取值
                    System.out.println(key + "--" + value);
                    if(!StringUtils.equalsIgnoreCase("id",key)){
                        update.set(key, mongoConverter.convertToMongoType(value));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Sentry.capture(e);
                }
            }
            return update;
        }
    }
    
    1. 注意事项
    update.set(key, mongoConverter.convertToMongoType(value));
    

    这句代码,如果不使用mongoConverter.convertToMongoType 进行转换,部分类型MongoDB 无法直接转换,在执行

    Document document = mongoTemplate.getDb().runCommand(command);
    

    就会报错,报错内容大致是:

    org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.cn.local.list……
    

    6. 所以一定要使用 mongoConverter.convertToMongoType(obj) 来设置 update的的value值.

  • 相关阅读:
    JavaScript向input标签的value赋值
    thinkphp关于本地引用图片
    jquery中得到input的值
    HTML的video标签,不能下载视频代码
    PHP数据库类
    MySQL数据库之MyISAM与InnoDB的区别
    php函数ob_start(),解决header输出头报错问题
    eps图片中文乱码问题
    感悟----程序员需要养成的习惯
    <前m大的数>的妙解
  • 原文地址:https://www.cnblogs.com/joinlemon/p/13825540.html
Copyright © 2020-2023  润新知