基于spring data操作mongoDB数据库数据持久层(dao层)设计感悟

13 篇文章 1 订阅
4 篇文章 0 订阅

spring data项目旨在对不同数据源提供一组相似的、较一致的具有spring style的交互方法。目的方便用户对不同数据源(关系数据库、非关系性数据等)的api操作,并简化系统持久层的代码逻辑结构。spring data项目包含多个子项目,不同数据源有不同的子项目对应。详见spring data官方文档

项目中的问题以及本文目的

在项目开发过程中由于前期没有很好规划,mongoDB操作逻辑代码编码冗余重复;存在大量collection和属性名硬编码;mongoDB操作逻辑同业务逻辑混在一起,阅读困难;业务逻辑中存在大量复杂指标计算,业务逻辑复杂;这些导致系统后期需求开发缓慢,新人难以上手,维护难度大。基于此,本文想基于spring data的理念,浅谈一下面向mongoDB的数据持久层(dao层)设计,并给出设计示例以及spring data mongoDB的操作方法和使用步骤。

设计理念
  • 借助Spring data封装的mongoDB操作方法,以及Spring data基于方法名称的操作范式简化原来基于MongoTemplate和MongoOperations实现的具体代码逻辑。
  • 持久层与业务逻辑层分离。
  • 以扩展的方式实现对不同collection的特殊业务逻辑。作为对Spring data公共方法的补充。

spring data mongoDB操作方法和使用步骤

创建spring boot项目

创建一个spring boot项目并实现对mongoDB的连接,具体可参见博文:Spring boot连接和操作mongoDB
本文基于yml配置。
1.在pom中引入相关包:

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

2.基于application.yml的连接配置

spring:
  data:
    mongodb:
      database: 数据库名称
      authentication-database: admin
      uri: mongodb://用户名:密码@ip:端口号
Spring data mongoDB部分源码概览

在正确配置完yml后,spring容器启动后将自动实例化对mongoDB的连接,在service类中通过简单的@Autowire MongoTemplate即可编写操作mongoDB代码逻辑。本文希望通过Spring data的封装的公共方法,简化操作逻辑。org.springframework.data.repository.Repository接口及派生接口提供对部分mongoDB操作的封装。
在这里插入图片描述

  • Repository接口是根接口,@Indexed注解修饰,容器在编译时会自动快速实例化实现或继承了该接口的子孙代的接口或类(非@NoRepositoryBean修饰),起到“入口”作用。
  • CrudRepository封装基础的增删改查操作
  • PagingAndSortingRepository在CrudRepository基础上扩展了分页和排序功能
  • MongoRepository在上述基础上扩展了insert方法,但是官方仍然推荐使用save方法。
  • BaseMongoDao为本文自定义接口,作为mongoDB业务操作的base接口。
  • SimpleMongoRepository是官方提供的MongoRepository接口的具体实现。

@NoRepositoryBean注解避免了容器在启动时被作为一个bean实例创建。可以通过自定义接口继承MongoRepository使用这些方法。
如下截图展示了MongoRepository,PagingAndSortingRepository,CrudRepository封装的mongoDB公共操作方法,基本覆盖了mongoDB的常规操作。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

Spring Data统一数据库操作范式

Spring Data提供基于方法名称的统一操作范式,只需在接口层定义相应方法即可完成具体操作逻辑,** 这一点非常有利于面向Nosql的操作,可极大简化冗余代码操作逻辑。**我们知道在面向关系型数据库的持久层设计中,大名鼎鼎的mybatis框架以xml文件的方式避免了sql脚本对业务逻辑代码的侵入性,提供统一操作接口供sevice层调用。对于mongoDB需要掌握大量json操作命令的数据库交互方式来说。Spring Data基于接口方法名称的统一操作范式极大的降低了mongoDB的查询难度。
基于接口方法名称的统一操作典型范式如下:

  • find…By, read…By, query…By
  • count…By
  • get…By
    更多范式请参见官方文档
interface PersonRepository extends Repository<User, Long> {

  List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);

  // 通过lastname或firstname属性从Person表(@Document声明的对应mongoDB collection)查询记录并去重
  List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
  List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);

  // 通过lastname从Person表(@Document声明的对应mongoDB collection)查询记录忽略lastname大小写
  List<Person> findByLastnameIgnoreCase(String lastname);
  // 通过lastname和firstname属性从Person表(@Document声明的对应mongoDB collection)查询记录忽略全部大小写
  List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);

  // 查询书结果并排序
  List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
  List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
}

也可在范式的基础上指定一些额外的规则

//查询结果后根据age倒序排序
 @Query(sort = "{ age : -1 }")
  List<Person> findByFirstname(String firstname);              

  @Query(sort = "{ age : -1 }")
  List<Person> findByLastname(String lastname, Sort sort);

更多关于范式的查询请参见:Spring data官方文档

基于Spring Data封装的方法以及基于方法名称的范式,基本可覆盖80%的mongoDB常规操作。同学们可以根据需求进行定义接口。如果还有其他复杂查询,例如aggregaet,可以定义详细实现类作为扩展。

基于spring data mongoDB的数据持久层设计实例

持久层(dao)结构如下:
在这里插入图片描述

  • BaseMongoDao继承MongoRepository作为项目的根接口,并预留相应扩展空间。
  • BaseMongoDaoExtend作为mongoDB复杂操作的基类并提供相应公共方法。
  • LatestDeviceInfoDao接口继承BaseMongoDao,继承所有MongoRespostory方法,并提供基于方法名称的范式方法声明,根据需求对mongoDB的 LatestDeviceInfo表进行操作。
  • LatestDeviceInfoDaoExtend继承BaseMongoDaoExtend扩展了操作方法,编写具体逻辑完成对mongoDB的 LatestDeviceInfo表的复杂操作。

代码示例如下:
在这里插入图片描述T为实体类泛型,ID为实体类对应表的主键类型泛型。
在这里插入图片描述BaseMongoDaoExtend提供复杂操作的封装,并对传参进行重载:
在这里插入图片描述LatestDeviceInfoDaoExtend继承BaseMongoDaoExtend,完成一些具体操作实现,供service层调用。
在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值