Spring整合MongoDB(十二)----MongoDB Repositories

【Spring连载】使用Spring Data访问 MongoDB(十二)----MongoDB Repositories

一、核心概念

核心概念

二、定义存储库接口

定义存储库接口

三、用法

要访问存储在MongoDB中的域实体,你可以使用我们复杂的存储库支持,这大大简化了实现。要执行此操作,请为存储库创建一个interface,如以下示例所示:
例1:Person 实体示例

public class Person {

  @Id
  private String id;
  private String firstname;
  private String lastname;
  private Address address;

  // … getters and setters omitted
}

请注意,上例中显示的域类型有一个String类型的id属性。MongoTemplate(支持存储库操作)中使用的默认序列化机制将id属性视为document ID。目前,框架支持String、ObjectId和BigInteger作为ID类型。有关如何在映射层中处理ID字段的更多信息,请参阅ID映射
现在我们有了一个域对象,我们可以定义一个使用它的接口,如下所示:
用于持久化Person实体的基本存储库接口

public interface PersonRepository extends PagingAndSortingRepository<Person, String> {

    // additional custom query methods go here
}

要开始使用存储库,请使用@EnableMongoRepositories注解。该注释与namespace元素具有相同的属性。如果没有配置基本包,则基础结构将扫描带注解的配置类的包。以下示例显示了如何将应用程序配置为使用MongoDB存储库:

@Configuration
@EnableMongoRepositories("com.acme..repositories")
class ApplicationConfig extends AbstractMongoClientConfiguration {

  @Override
  protected String getDatabaseName() {
    return "e-store";
  }

  @Override
  protected String getMappingBasePackage() {
    return "com.acme..repositories";
  }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:mongo="http://www.springframework.org/schema/data/mongo"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/data/mongo
    https://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd">

  <mongo:mongo-client id="mongoClient" />

  <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg ref="mongoClient" />
    <constructor-arg value="databaseName" />
  </bean>

  <mongo:repositories base-package="com.acme.*.repositories" />

</beans>

这个namespace元素导致扫描基本包,寻找继承MongoRepository的接口,并为找到的每个接口创建Spring beans。默认情况下,存储库会注入一个名为mongoTemplate的MongoTemplate Spring bean,因此如果偏离(deviate)此约定,只需要显式配置mongo-template-ref。
因为我们的域存储库继承了PagingAndSortingRepository,所以它为你提供了对实体进行分页和排序访问的方法。在反应式(reactive)存储库的情况下,只有ReactiveSortingRepository可用,因为页面的概念不适用。但是finder方法仍然接受Sort和Limit参数。
reactive space提供了各种反应合成库。最常见的库是RxJava和Project Reactor。
Spring Data MongoDB构建在MongoDB Reactive Streams driver之上,通过依赖Reactive Streams倡议提供最大的互操作性。静态API,如ReactiveMongoOperations,是通过使用Project Reactor的Flux和Mono类型提供的。ProjectReactor提供了各种适配器来转换反应包装类型(Flux到Observable,反之亦然),但转换很容易使代码混乱。
Spring Data的Reactive Repository抽象是一个动态的API,主要由你的需求在声明查询方法时定义。Reactive MongoDB存储库可以通过使用RxJava或Project Reactor包装器类型来实现,方法是从以下特定于library的存储库接口之一进行扩展:

  • ReactiveCrudRepository
  • ReactiveSortingRepository
  • RxJava3CrudRepository
  • RxJava3SortingRepository

Spring Data在底层转换reactive包装器类型,以便你可以坚持使用你喜欢的组合库。
如果你想获得基本CRUD操作的方法,还可以添加CrudRepository接口。使用存储库实例只是将其注入客户端的依赖关系。因此,访问页面大小为10的Person对象的第一页将类似于以下代码:
对Person实体的分页访问

@ExtendWith(SpringExtension.class)
@ContextConfiguration
class PersonRepositoryTests {

    @Autowired PersonRepository repository;

    @Test
    void readsFirstPageCorrectly() {

      Page<Person> persons = repository.findAll(PageRequest.of(0, 10));
      assertThat(persons.isFirstPage()).isTrue();
    }
}

前面的示例使用Spring的单元测试支持创建了一个应用程序上下文,它在测试用例中执行基于注解的依赖项注入。在测试方法中,我们使用存储库来查询数据存储。我们向存储库提供一个PageRequest实例,该实例请求页面大小为10的Person对象的第一页。

四、类型安全的查询方法

MongoDB存储库及其反应式(reactive)实现与Querydsl项目集成,该项目提供了一种执行类型安全查询的方法。

它们不是将查询编写为内联字符串或将其外部化为XML文件,而是通过fluent API构建的。
————Querydsl团队

它提供了以下功能:

  • IDE中的代码完成(所有属性、方法和操作都可以在你喜欢的Java IDE中展开)。
  • 几乎不允许语法无效的查询(在所有级别上都是类型安全的)。
  • 可以安全地引用域类型和属性 — 不涉及任何strings!
  • 更好地适应域类型中的重构更改。
  • 增量查询定义更容易。

请参阅QueryDSL文档,了解如何使用Maven或Ant引导环境以生成基于APT的代码。
QueryDSL允许你编写以下查询:

QPerson person = new QPerson("person");
List<Person> result = repository.findAll(person.address.zipCode.eq("C0123"));

Page<Person> page = repository.findAll(person.lastname.contains("a"),
                                       PageRequest.of(0, 2, Direction.ASC, "lastname"));

QPerson是一个由Java注解后处理工具生成的类。它是一个谓词(Predicate),允许你编写类型安全的查询。请注意,查询中除了C0123值之外没有其他字符串。
你可以通过使用QuerydslPredicateExecutor/ReactiveQuerydslPredicateExecutor接口来使用生成的Predicate类,如下所示:

public interface QuerydslPredicateExecutor<T> {

    T findOne(Predicate predicate);

    List<T> findAll(Predicate predicate);

    List<T> findAll(Predicate predicate, Sort sort);

    List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders);

    Page<T> findAll(Predicate predicate, Pageable pageable);

    List<T> findAll(OrderSpecifier<?>... orders);

    Long count(Predicate predicate);

    Boolean exists(Predicate predicate);
}

要在你的存储库实现中使用它,请将其添加到你的接口继承的存储库接口列表中,如下面的示例所示:

interface PersonRepository extends MongoRepository<Person, String>, QuerydslPredicateExecutor<Person> {

   // additional query methods go here
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值