spring-boot2.x集成mongodb

  • spring-boot 2.x
  • mongogb-3.6

配置信息

依赖信息

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-mongodb</artifactId>
 </dependency>

配置信息

spring:
  data:
    mongodb:
      host: 192.168.129.44
      port: 27017
      database: cmdb
	  # 自动将字段转换为驼峰标识存储到mongo中.
	  # 如 notifyNo 存储到mongodb中自动转换为: notify_no
      field-naming-strategy:  org.springframework.data.mapping.model.SnakeCaseFieldNamingStrategy

java-beans

类图
在这里插入图片描述

BasicPojo
定义通用的基础字段:如创建人/时间,修改人/时间,删除标识等。

public class BasicPojo<T> implements Serializable {
    private static final long serialVersionUID = -8985545025018238754L;
	
	//删除标识: 0:有效, 1:无效
	//已设置了驼峰自动标识,无需使用@Field指定;
	//    @Field("del_flag")
	@Getter @Setter
    int delFlag;

    @Getter @Setter
    String createStaff;

    @Getter @Setter
    Date createTime;

    @Getter @Setter
    String updateStaff;
    
    @Getter @Setter
    Date updateTime;
}

NotifyMsg
测试实体NotifyMsg,继承自BasicPojo

@Document(collection = "notify_msg")//集合名
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class NotifyMsg extends BasicPojo<String> {

    @Id
    String id;

    /**
     * 消息类型
     */
    @Indexed
    String notifyType;

    /**
     * 消息单号
     */
    @Indexed(unique = true)
    String notifyNo;

    /**
     * 消息通知日期
     */
    String notifyDate;

    /**
     * 消息体
     * 可指定存储时的字段名
     */
    String notifyMsg;

}

索引
通过在属性上使用注解@Index来创建索引;

  • @Index :索引
  • @Indexed(unique = true)创建唯一索引

联合索引
通过在类上添加注解,来创建索引:

@Document(collection = XXX集合)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
//复合索引: type 升序, code升序;
@CompoundIndexes({
        @CompoundIndex(name = "type_code_unique_inx", def = "{'type': 1, 'code': 1}",unique = true)
})
public class XXXimplements Serializable {


    String type;

    String code;
}

SpringDataPageable
mongodb请求分页参数bean:

public class SpringDataPageable implements Serializable, Pageable {
    private static final long serialVersionUID = 1;
    // 当前页
    private Integer pagenumber = 1;
    // 当前页面条数
    private Integer pagesize = 10;
    // 排序条件
    private Sort sort;

    // 当前页面
    @Override
    public int getPageNumber() {
        return getPagenumber();
    }

    // 每一页显示的条数
    @Override
    public int getPageSize() {
        return getPagesize();
    }

    // 第二页所需要增加的数量
    @Override
    public long getOffset() {
        return (getPagenumber() - 1) * getPagesize();
    }

  //略....
}

SimplePageInfo(非必须)
由于springt框架返回的分页信息太多,自定义分页response-bean,只传递简要的分页信息即可(非必须)。

public class SimplePageInfo<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    //总记录数
    protected long    total;
    //结果集
    protected List<T> list;

    public SimplePageInfo() {
    }

    public SimplePageInfo(List<T> list) {
        this.list = list;
        if(list instanceof Page){
            this.total = ((Page)list).getTotal();
        }
    }
    public SimplePageInfo(List<T> list, long total) {
        this.list = list;
        this.total = total;
    }
	
	//略....

}

MongoTemplate

NotifyMsgServiceImpl 方法总览

@Service
public class NotifyMsgServiceImpl implements NotifyMsgService {

    @Autowired
    MongoTemplate mongoTemplate;
	
	//增删改查method
}

新增-saveNotifyMsg()

  @Override
 public NotifyMsg saveNotifyMsg(NotifyMsg entity) {
   //设置创建人信息,删除标识
   entity.setCreateStaff("TEST");
   entity.setCreateTime(new Date());
   entity.setDelFlag( 0);

   mongoTemplate.save(entity);
   return entity;
}

使用 save和insert都可以进行插入,区别:当存在"_id"时

  • insert 插入已经存在的id时 会异常
  • save 则会进行更新 ("不存在的_id"就是insert操作, 存在就是update操作)

更新–updateNotifyMsg()

public NotifyMsg updateNotifyMsg(NotifyMsg entity) {
	//业务要求,只允许修改 notifyMsg和notifyType两个字段的信息
   if (entity.getNotifyMsg() != null || entity.getNotifyType() != null) {
        Update update = new Update();
        Optional.ofNullable(entity.getNotifyMsg()).ifPresent(msg -> {
            update.set("notify_msg", msg);
        });

        Optional.ofNullable(entity.getNotifyType()).ifPresent(type -> {
            update.set("notify_type", type);
        });
		
		//设置修改人信息
        update.set("update_time", new Date());
        update.set("update_staff", getCurrentStaff());
	
		//设置查询条件: 主键为id 且删除位有效的数据
        Query query = new Query(Criteria.where("id").is(new ObjectId(entity.getId())).and("del_flag").is(0));
		
		//修改满足指定查询条件的第一条记录.
        mongoTemplate.updateFirst(query, update, NotifyMsg.class);
    }
    return entity;
}

mongoTemplate.updateXXX众多更新方法:

  • mongoTemplate.updateFirst 修改符合条件第一条记录
  • mongoTemplate.updateMulti : 修改符合条件的所有
  • mongoTemplate.Upsert: 修改符合条件时如果不存在则添加

逻辑删除-delNotifyMsgById()

@Override
public long delNotifyMsgById(String id) {
    Query where = new Query(Criteria.where("id").is(new ObjectId(id)).and("del_flag").is(0));

	//设置修改人信息
    Update update = new Update();
    update.set("update_time", new Date());
    update.set("update_staff", getCurrentStaff());
    update.set("del_flag", 1);

    return mongoTemplate.updateFirst(where, update, NotifyMsg.class).getModifiedCount();
}

单个获取-findNotifyMsgByNo()

  public NotifyMsg findNotifyMsgByNo(String notifyNo) {
      //根据Criteria 改造查询条件
      Query query = new Query(Criteria.where("notify_no").is(notifyNo).and("del_flag").is(0));
      return mongoTemplate.findOne(query, NotifyMsg.class);
  }

分页查询-qry()

 public SimplePageInfo<NotifyMsg> qry(NotifyMsg param, int pageNum, int pageSize) {
  SpringDataPageable pageable = new SpringDataPageable();
     //排序
     List<Sort.Order> orders = new ArrayList<>();
     orders.add(new Sort.Order(Sort.Direction.DESC, "notify_no"));
     Sort sort = Sort.by(orders);

     // 开始页
     pageable.setPagenumber(pageNum);
     // 每页条数
     pageable.setPagesize(pageSize);
     // 排序
     pageable.setSort(sort);

     //查询条件...
     Query query = new Query(Criteria.where("del_flag").is(0));
     Field fields = query.fields();
//        fields.exclude("_id"); //-- 排除_id字段

     Optional.ofNullable(param).ifPresent(entity -> {
         Criteria criteria = new Criteria();
         Optional.ofNullable(entity.getId()).ifPresent(id -> {
             criteria.and("id").is(new ObjectId(id));
         });

         Optional.ofNullable(entity.getNotifyNo()).ifPresent(notifyNo -> {
             criteria.and("notify_no").is(notifyNo);
         });

         Optional.ofNullable(entity.getNotifyMsg()).ifPresent(notifyMsg -> {
             //等价于: {"notifyMsg": /apple/}
             //类似于sql:  notifyMsg like '%apple%'
             criteria.and("notify_msg").regex(notifyMsg);
         });

         Optional.ofNullable(entity.getNotifyType()).ifPresent(notifyType -> {
             criteria.and("notify_type").in(notifyType);
         });
         query.addCriteria(criteria);
     });


     // 查询出一共的条数
     Long count = mongoTemplate.count(query, NotifyMsg.class);
     // 查询
     List<NotifyMsg> list = mongoTemplate.find(query.with(pageable), NotifyMsg.class);
     // 将集合与分页结果封装
     SimplePageInfo<NotifyMsg> pagelist = new SimplePageInfo<NotifyMsg>(list, count);
     return pagelist;
 }

MongoTemplate特点

  • 所有的更新操作都要指定创建人,修改人等信息–比较繁琐
  • 最为常用的的查询方法,也需要通过手写实现。

JPA — MongoRepository

@CreatedBy,@CreatedDate,@LastModifiedBy,@LastModifiedDate
通过如上的注解,来实现在创建或修改时自动设置创建人/时间,修改人/时间等信息。
修改BasicPojo,为其添加注解:

public class BasicPojo<T> implements Serializable {
    private static final long serialVersionUID = -8985545025018238754L;
	
	//已设置了驼峰自动标识,无需使用@Field指定;
	//    @Field("del_flag")
	@Getter @Setter
    int delFlag;

	@CreatedBy
    @Getter @Setter
    String createStaff;

    @CreatedDate
    @Getter @Setter
    Date createTime;
    
 	@LastModifiedBy
    @Getter @Setter
    String updateStaff;
    
    @LastModifiedDate
    @Getter @Setter
    Date updateTime;
}

审计人信息自动注入类—AuditorAware
上文中的@CreatedDate,@LastModifiedDate我们可以通过系统时间来自动注入。
但是@CreatedBy,@LastModifiedBy人信息该如何设置呢,答案就是AuditorAware.

@Configuration
public class UserAcctAuditorBean implements AuditorAware<String> {
    private static final String ANONYMOUS = "Anonymous";
    @Override
    public Optional<String> getCurrentAuditor() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated() && !(authentication instanceof AnonymousAuthenticationToken)) {
            OauthUserDetails oauthUserDetails = (OauthUserDetails) authentication.getPrincipal();
            return Optional.of(oauthUserDetails.getLoginAcct());
        } else {
            return Optional.of(ANONYMOUS+ LocalDateTime.now().getSecond());
        }
    }
}

NotifyMsgRepository

public interface NotifyMsgRepository extends MongoRepository<NotifyMsg, String> {
     /**
     * @description 根据模块id + del_flag 获取bean, 并指定输出字段
     * - ?0 是函数的参数。
     * - fields 指定需要输出的字段
     * @author trump
     * @param id 主键
     * @return
     * @throws
     */
    @Query(value = "{'id':?0, 'del_flag':0}" /*,fields="{ 'id' : 1, 'notify_type' : 1, 'notify_no' : 1, 'notify_msg' : 1}"*/)
    Optional<NotifyMsg> getById2(String id);

    /**
     * 使用jpa方法: notifyNo + delFlag删除
     * @param notifyNo 编码
     * @param delFlag 删除位
     * @return
     */
    Optional<NotifyMsg> getNotifyMsgByNotifyNoAndDelFlag(String notifyNo,int delFlag);

    default Optional<NotifyMsg> getNotifyMsgByNotify2(String notifyNo){
        return getNotifyMsgByNotifyNoAndDelFlag(notifyNo, Constant.DEL_FLAG_EFFECTIVE);
    }
}

NotifyMsgServiceImpl

public class NotifyMsgServiceImpl2 implements NotifyMsgService {
    private Logger logger = LoggerFactory.getLogger(NotifyMsgServiceImpl2.class);

    @Autowired
    NotifyMsgRepository repository;

    @Override
    public NotifyMsg saveNotifyMsg(NotifyMsg entity) {
        //使用 save和insert都可以进行插入
        //区别:当存在"_id"时
        //insert 插入已经存在的id时 会异常
        //save 则会进行更新
        //简单来说 save 就是不存在插入 存在更新
//        mongoTemplate.insert(msg);
        return repository.save(entity);
    }

    @Override
    public NotifyMsg updateNotifyMsg(NotifyMsg param) {
        repository.getById2(param.getId()).ifPresent(dbEntity -> {
            if (dbEntity.getDelFlag() == Constant.DEL_FLAG_EFFECTIVE) {
                //只允许修改notifyMsg 和 notifyType
                Optional.ofNullable(param.getNotifyMsg()).ifPresent(newNotifyMsg -> {
                    dbEntity.setNotifyMsg(newNotifyMsg);
                });

                Optional.ofNullable(param.getNotifyType()).ifPresent(newNotifyType -> {
                    dbEntity.setNotifyType(newNotifyType);
                });

                dbEntity.setNotifyMsg(param.getNotifyMsg());
                
				//save更新会将未传入的属性全部设置为null,所以需要将db中历史数据取出,然后更新指定字段
       		    // db.xx.update({title:"xx"},{rank:99}) 及不带有$set形式的更新
               // db.xx.update({title:"xx"},{$set:{rank: 10}})
                repository.save(dbEntity);
            }
        });

        return null;
    }

    @Override
    public NotifyMsg findNotifyMsgByNo(String notifyNo) {
        return repository.getNotifyMsgByNotify2(notifyNo).get();
    }


    @Override
    public long delNotifyMsgById(String id) {
        repository.getById2(id).ifPresent(dbEntity -> {
            dbEntity.setDelFlag(Constant.DEL_FLAG_INVALID);
            
            repository.save(dbEntity);
        });

       return 1;
    }

    @Override
    public SimplePageInfo<NotifyMsg> qry(NotifyMsg param, int pageNum, int pageSize) {
        SpringDataPageable pageable = new SpringDataPageable();
        //排序
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(new Sort.Order(Sort.Direction.DESC, "notify_no"));
        Sort sort = Sort.by(orders);
        // 开始页
        pageable.setPagenumber(pageNum);
        // 每页条数
        pageable.setPagesize(pageSize);
        // 排序
        pageable.setSort(sort);

        Page<NotifyMsg> page = repository.findAll(Example.of(param), pageable);
        return new SimplePageInfo<>(page.getContent(), page.getTotalElements());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值