zoukankan      html  css  js  c++  java
  • MongoDB–Spring Data MongoDB详细操作(增删改查)

    github:https://github.com/Ccww-lx/Sp...

     在NoSQL盛行的时代,App很大可能会涉及到MongoDB数据库的使用,而也必须学会在Spring boot使用Spring Data连接MongoDB进行数据增删改查操作,如下为详细的操作手册。

    依赖

    直接导入spring-data-mongodb包或者使用Spring Boot starter

    <dependencies>
      <!-- other dependency elements omitted -->
      <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>2.2.0.RELEASE</version>
      </dependency>
    </dependencies>
    <!--spring 框架使用最新的 -->
    <spring.framework.version>5.2.0.RELEASE</spring.framework.version>
    
    <!--用一即可-->
    <!--使用Spring Boot starter-->
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    

    属性文件application.properties

    
    #mongodb连接地址,集群用“;”隔开
    spring.mongo.mongoDatabaseAddress=10.110.112.165:27092;10.110.112.166:27092
    #mongo数据名
    spring.mongo.dbname=mongodb
    #mongo用户
    spring.mongo.username=mongodbopr
    #mongo密码
    spring.mongo.password=123456
    #mongo最大连接数
    spring.mongo.connectionsPerHost=50
    

    mongoDB 配置

    注册Mongo实例配置:

    @Configuration
    public class MongodbConfig {
        public static final String COMMA = ";";
        public static final String COLON = ":";
        
        @Value("${spring.mongo.mongoDatabaseAddress}")
        private String mongoDatabaseAddress;
        
        @Value("${spring.mongo.username}")
        private String username;
        @Value("${spring.mongo.dbname}")
        private String dbname;
        
        @Value("${spring.mongo.password}")
        private String password;
        
        @Value("${spring.mongo.connectionsPerHost}")
        private String connectionsPerHost;
        
        /**
         * 获取mongodb的地址
         *
         * @return
         */
        private List<ServerAddress> getMongoDbAddress() {
            List<ServerAddress> serverAddrList = new ArrayList<ServerAddress>();
            //如果有多个服务器的话
            if (this.mongoDatabaseAddress.indexOf(COMMA) > 0) {
                String[] addressArrays = mongoDatabaseAddress.split(COMMA);
                String[] hostPort;
                for (String address : addressArrays) {
                    hostPort = address.split(COLON);
                    ServerAddress serverAdress = new ServerAddress(hostPort[0], Integer.valueOf(hostPort[1]));
                    serverAddrList.add(serverAdress);
                }
            } else {
                String[] hostPort = mongoDatabaseAddress.split(COLON);
                ServerAddress serverAdress = new ServerAddress(hostPort[0], Integer.valueOf(hostPort[1]));
                serverAddrList.add(serverAdress);
            }
            return serverAddrList;
        }
        /**
         * 设置连接参数
         */
        private MongoClientOptions getMongoClientOptions() {
            MongoClientOptions.Builder builder = MongoClientOptions.builder();
            // todo 添加其他参数配置
            //最大连接数
            builder.connectionsPerHost(Integer.valueOf(connectionsPerHost));
            MongoClientOptions options = builder.readPreference(ReadPreference.nearest()).build();
            return options;
        }
        /**
         *
         * @return
         */
        @Bean
        public MongoClient mongoClient() {
            //使用数据库名、用户名密码登录
            MongoCredential credential = MongoCredential.createCredential(username, dbname, password.toCharArray());
            //创建Mongo客户端
            return new MongoClient(getMongoDbAddress(), credential, getMongoClientOptions());
        }
        /**
         * 注册mongodb操作类
         * @param mongoClient
         * @return
         */
        @Bean
        @ConditionalOnClass(MongoClient.class)
        public MongoTemplate mongoTemplate(MongoClient mongoClient) {
            MongoTemplate mongoTemplate = new MongoTemplate(new SimpleMongoDbFactory(mongoClient, dbname));
            return mongoTemplate;
        }
    }
    
    
    

    mongoDB操作

    使用MongoTemplate类进行增删改查

    @Service
    public class MongodbService {
        @Autowired
        private MongoTemplate mongoTemplate;
    
        /**
         * 新增文档
         *
         * @param userDTO
         * @return
         */
        public UserDTO insert(UserDTO userDTO) {
            //insert方法并不提供级联类的保存,所以级联类需要先自己先保存
            return mongoTemplate.insert(userDTO);
        }
    
        public UserDTO save(UserDTO userDTO) {
            Sort sort = new Sort(Sort.Direction.DESC, "name");
            userDTO = mongoTemplate.findOne(Query.query(Criteria.where("")).with(sort), UserDTO.class);
            return mongoTemplate.save(userDTO);
        }
    
        /**
         * 删除文档
         * NOTE:remove方法不支持级联删除所以要单独删除子数据
         * @param name
         */
        public void remove(String name) {
            //根据名字查询数据并删除
            UserDTO userDTO = mongoTemplate.findOne(Query.query(Criteria.where("name").is(name)), UserDTO.class);
            //remove方法不支持级联删除所以要单独删除子数据
            List<AddressDTO> addressList = userDTO.getAddressList();
            for (AddressDTO addressDTO : addressList) {
                mongoTemplate.remove(addressDTO);
            }
            //删除主数据
            mongoTemplate.remove(userDTO);
        }
    
        /**
         * 更新文档
         * @param userDTO
         */
        public void update(UserDTO userDTO) {
            mongoTemplate.updateFirst(Query.query(Criteria.where("name").is(userDTO.getName())), Update.update("age", userDTO.getAge()), UserDTO.class);
        }
    
        /**
         * 查询文档
         * @param name
         */
        public void find(String name) {
            Sort sort = new Sort(Sort.Direction.DESC, "name");
            List<UserDTO> userDTOS = mongoTemplate.find(Query.query(Criteria.where("name").is(name)), UserDTO.class);
            //基于sort排序使用findOne查询最新一条记录
            UserDTO userDTO = mongoTemplate.findOne(Query.query(Criteria.where("name").is(name)).with(sort), UserDTO.class);
            //模糊查询
            List<UserDTO> userDTOList = mongoTemplate.find(Query.query(Criteria.where("name").is(name).regex(name)).with(sort), UserDTO.class);
            //分页查询
            Pageable pageable = PageRequest.of(3, 20, sort);
            List<UserDTO> userDTOPageableList = mongoTemplate.find(Query.query(Criteria.where("name").is(name)).with(pageable), UserDTO.class);
            //总数
            long conut = mongoTemplate.count(Query.query(Criteria.where("name").is(name)), UserDTO.class);
            Page<UserDTO> page = new PageImpl(userDTOPageableList, pageable, conut);
        }
    }
    

    NOTE:
      在开发中,如果从任何MongoDB操作返回的com.mongodb.WriteResult包含错误,则可以方便地记录或引发异常。 通常,在开发过程中很容易忘记执行此操作,然后最终得到一个看似运行成功的App,但实际上该数据库操作发生异常,没执行成功。 可以将MongoTemplateWriteResultChecking属性设置为以下值之一:

    • EXCEPTION:引发Exception
    • NONE:不执行任何操作,默认值

      对于更高级的情况,可以将每个操作设置不同的WriteConcern值(用于删除,更新,插入和保存操作),则可以在MongoTemplate上配置WriteConcernResolver的策略接口。 由于MongoTemplate用于持久化POJO,因此WriteConcernResolver允许您创建一个策略,该策略可以将特定的POJO类映射到WriteConcern值。

    WriteConcernResolver接口:

    public interface WriteConcernResolver {
      WriteConcern resolve(MongoAction action);
    }
    

    自定义WriteConcernResolver接口,实现不同WriteConcern策略:

    private class MyAppWriteConcernResolver implements WriteConcernResolver {
    
      public WriteConcern resolve(MongoAction action) {
        if (action.getEntityClass().getSimpleName().contains("UserDTO")) {
          return WriteConcern.NONE;
        } else if (action.getEntityClass().getSimpleName().contains("Metadata")) {
          return WriteConcern.JOURNAL_SAFE;
        }
        return action.getDefaultWriteConcern();
      }
    }
    
    

     常用的类以及方法解析

    5.1 MongoClient、ServerAddress、MongoCredential以及MongoClientOptions

      基于ServerAddress单机或者Replica Set在使用MongoClient连接mongodb数据库注册mongo实例,在注册示例中可能要使得MongoCredential账号密码验证以及使用MongoClientOptions配置mongodb其他的参数。

    MongoClient常用的构造器方法:

    public MongoClient(String host){}
    public MongoClient(MongoClientURI uri){}
    public MongoClient(String host, MongoClientOptions options) {}
    public MongoClient(ServerAddress addr, MongoCredential credential, MongoClientOptions options){}
    public MongoClient(List<ServerAddress> seeds, MongoCredential credential, MongoClientOptions options){}
    

    5.2 MongoTemplate

    使用MongoTemplate结合SortCriteriaQueryUpdate以及分页Pageable类灵活地进行对mongodb数据库进行增删改查。

    query方法:

    //根据查询条件查询
     public <T> List<T> find(Query query, Class<T> entityClass){}
     //根据查询条件查询返回一条记录
     public <T> <T>findOne(Query query, Class<T> entityClass){}
     //查询该collection所有记录
     public <T> List<T> findAll(Class<T> entityClass){}
    

    insert方法:

    //新增一条记录
     public <T> T insert(T objectToSave){}
     //在collectionName中新增一条记录
     public <T> T insert(T objectToSave, String collectionName) {}
     //
     public <T> T save(T objectToSave){}
    

    remove方法:

    //根据Object删除
     public DeleteResult remove(Object object) {}
     //根据查询条件进行删除
     public DeleteResult remove(Query query, Class<?> entityClass){}

    update方法:

    
     //
     public UpdateResult upsert(Query query, Update update, Class<?> entityClass) {}
     //更新查询出来的第一条记录
     public UpdateResult updateFirst(Query query, Update update, String collectionName) {}
    
    

    5.3 Sort

    Sort查询排序类。Sort类常用方法:

    //构造方法创建一个排序。direction为排序方向的枚举类型,properties为排序字段数组
    Sort(Sort.Direction direction, String... properties)
    //多个排序条件链接
    and(Sort sort)
    //返回升序排列对象
    ascending()    
    //返回降序排列对象
    descending()    

    5.4 Criteria

    Criteria查询条件类,类似于SQL的where,常用方法:

    //声明定义查询条件,且为静态方法
    where(String key)
    //与操作
    and(String key)
    //正则表达式,即可为模糊查询
    regex(String re)
    //包含
    in(Object... o)    
    //大于
    gt(Object o)
    //大于等于
    gte(Object o)
    //等于
    is(Object o)
    //小于
    lt(Object o)
    //小于等于
    lte(Object o) 
    //非
    not()
    //创建与操作
    andOperator(Criteria... criteria)    

    5.5 Query

    Query查询对象,具有查询的全部信息,其中包括筛选条件、排序、返回数量等。常用的方法:

    //定义查询对象,静态方法
    query(CriteriaDefinition criteriaDefinition)
    //在本次查询添加一个CriteriaDefinition查询条件
    addCriteria(CriteriaDefinition criteriaDefinition)
    //添加一个Sort排序对象
    with(Sort sort)
    //添加一个Pageable分页对象、通常情况下,分页和排序一起使用。
    with(Pageable pageable)
    

    详细接口信息可查看【MogoDB API官方文档】

    常用注解

    注解解析
    @Id 用于标记id字段,没有标记此字段的实体也会自动生成id字段,但是我们无法通过实体来获取id。id建议使用ObjectId类型来创建
    @Document 用于标记此实体类是mongodb集合映射类
    @DBRef 用于指定与其他集合的级联关系,但是需要注意的是并不会自动创建级联集合
    @Indexed 用于标记为某一字段创建索引
    @CompoundIndex 用于创建复合索引
    @TextIndexed: 用于标记为某一字段创建全文索引
    @Language 指定documen语言
    @Transient: 被该注解标注的,将不会被录入到数据库中。只作为普通的javaBean属性
    @Field: 用于指定某一个字段映射到数据库中的名称

  • 相关阅读:
    keepalvied虚拟ip安装设置
    mysql 主从,主主,主主复制时的主键冲突解决
    mysql备份,知识点
    mysql自定义函数语法
    sql之left join、right join、inner join的区别
    mysql 日志文件mysql-bin文件清除方法,和mysql-bin相关文件的配置
    mysql日志总结
    并查集 专题总结
    最短路径 专题总结
    Dancing Links 专题总结
  • 原文地址:https://www.cnblogs.com/21-Gram/p/12014944.html
Copyright © 2011-2022 走看看