Connecting to a NoSQL Database with Spring Boot – 用Spring Boot连接到NoSQL数据库

最后修改: 2022年 2月 20日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’re going to learn how to connect to a NoSQL database using Sprint Boot. For the focus of our article, we’ll be using DataStax Astra DB, a DBaaS powered by Apache Cassandra that allows us to develop and deploy data-driven applications using a cloud-native service.

在本教程中,我们将学习如何使用 Sprint Boot 连接到 NoSQL 数据库。对于我们文章的重点,我们将使用DataStax Astra DB,这是一个由Apache Cassandra提供的DBaaS,允许我们使用云原生服务来开发和部署数据驱动的应用程序。

First, we’ll start by looking at how to get our application set up and configured with Astra DB. Then we’ll learn how to build a simple application using Spring Boot.

首先,我们将首先了解如何使用Astra DB设置和配置我们的应用程序。然后我们将学习如何使用Spring Boot构建一个简单的应用程序

2. Dependencies

2.依赖性

Let’s start by adding the dependencies to our pom.xml. Of course, we’re going to need the spring-boot-starter-data-cassandra dependency:

让我们先把依赖项添加到我们的pom.xml中。当然,我们将需要spring-boot-starter-data-cassandra依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-cassandra</artifactId>
    <version>2.6.3</version>
</dependency>

Next, we’ll add the spring-boot-starter-web dependency:

接下来,我们将添加spring-boot-starter-web依赖性。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
     <version>2.6.3</version>
</dependency>

Finally, we’ll be using the Datastax astra-spring-boot-starter:

最后,我们将使用Datastax的astra-spring-boot-starter

<dependency>
    <groupId>com.datastax.astra</groupId>
    <artifactId>astra-spring-boot-starter</artifactId>
    <version>0.3.0</version>
</dependency>

Now that we have all the necessary dependencies configured, we can start writing our Spring Boot application.

现在,我们已经配置了所有必要的依赖,我们可以开始编写我们的Spring Boot应用程序。

3. Database Setup

3.数据库的设置

Before we start defining our application, it’s important to quickly reiterate that DataStax Astra is a cloud-based database offering that is powered by Apache Cassandra. This gives us a fully hosted, fully managed Cassandra database that we can use to store our data. However, as we’re going to see, the way we set up and connect to our database has some specificities.

在我们开始定义我们的应用程序之前,必须快速重申,DataStax Astra是一个基于云的数据库产品,由Apache Cassandra驱动。这为我们提供了一个完全托管、完全管理的 Cassandra 数据库,我们可以用它来存储我们的数据。然而,正如我们将要看到的,我们设置和连接到数据库的方式有一些特殊性。

In order for us to interact with our database, we need to setup our Astra Database on the host platform. Then, we need to download our Secure Connect Bundle, which contains details of SSL certificates and connection details for this exact database, allowing us to connect securely.

为了使我们能够与我们的数据库进行交互,我们需要在主机平台上设置我们的Astra数据库。然后,我们需要下载我们的安全连接包,其中包含SSL证书的详细信息和该确切数据库的连接细节,使我们能够安全地进行连接。

For the purposes of this tutorial, we’ve assumed we’ve done both of these tasks.

在本教程中,我们假设我们已经完成了这两项任务。

4. Application Configuration

4.应用配置

Next, we’ll configure a simple main class for our application:

接下来,我们将为我们的应用程序配置一个简单的main类。

@SpringBootApplication
public class AstraDbSpringApplication {

    public static void main(String[] args) {
        SpringApplication.run(AstraDbSpringApplication.class, args);
    }
}

As we can see, this is a run-of-the-mill Spring Boot application. Now let’s begin to populate our application.properties file:

我们可以看到,这是一个普通的Spring Boot应用程序。现在让我们开始填充我们的application.properties文件。

astra.api.application-token=<token>
astra.api.database-id=<your_db_id>
astra.api.database-region=europe-west1

These are our Cassandra credentials and can be taken directly from the Astra dashboard.

这些是我们的 Cassandra 凭证,可以直接从 Astra 仪表板上获取。

In order to use CQL via a standard CqlSession, we’ll add another couple of properties, including the location of our downloaded secure connect bundle:

为了通过标准的CqlSession使用CQL,我们将再添加几个属性,包括我们下载的安全连接包的位置。

astra.cql.enabled=true
astra.cql.downloadScb.path=~/.astra/secure-connect-shopping-list.zip

Finally, we’ll add a couple of standard Spring Data properties for working with Cassandra:

最后,我们将添加几个标准的Spring Data属性,以便与Cassandra一起工作。

spring.data.cassandra.keyspace=shopping_list
spring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS

Here, we’re specifying our database keyspace and telling Spring Data to create our tables if they do not exist.

在这里,我们指定了我们的数据库关键空间,并告诉Spring Data在我们的表不存在的情况下创建它们。

5. Testing Our Connection

5 测试我们的联系

Now we have all the parts in place to test our database connection. So let’s go ahead and define a simple REST Controller:

现在我们已经有了所有的部分来测试我们的数据库连接。因此,让我们继续前进,定义一个简单的REST控制器

@RestController
public class AstraDbApiController {

    @Autowired
    private AstraClient astraClient;

    @GetMapping("/ping")
    public String ping() {
        return astraClient.apiDevopsOrganizations()
          .organizationId();
    }

}

As we can see, we’ve created a simple ping endpoint using the AstraClient class that will return the organization id of our database. This is a wrapper class that comes as part of the Astra SDK that we can use to interact with various Astra APIs.

我们可以看到,我们使用AstraClient类创建了一个简单的ping端点,它将返回我们数据库的组织ID。这是一个包装类,作为Astra SDK的一部分,我们可以用它来与各种Astra API进行交互

Above all, this is just a simple test to make sure we can establish connectivity. So let’s go ahead and run our application using Maven:

最重要的是,这只是一个简单的测试,确保我们能够建立连接。因此,让我们继续使用Maven运行我们的应用程序。

mvn clean install spring-boot:run

We should see on our console the connection established with our Astra database:

我们应该在控制台看到与我们的Astra数据库建立的连接。

...
13:08:00.656 [main] INFO  c.d.stargate.sdk.StargateClient - + CqlSession   :[ENABLED]
13:08:00.656 [main] INFO  c.d.stargate.sdk.StargateClient - + API Cql      :[ENABLED]
13:08:00.657 [main] INFO  c.d.stargate.sdk.rest.ApiDataClient - + API Data     :[ENABLED]
13:08:00.657 [main] INFO  c.d.s.sdk.doc.ApiDocumentClient - + API Document :[ENABLED]
13:08:00.658 [main] INFO  c.d.s.sdk.gql.ApiGraphQLClient - + API GraphQL  :[ENABLED]
13:08:00.658 [main] INFO  com.datastax.astra.sdk.AstraClient
  - [AstraClient] has been initialized.
13:08:01.515 [main] INFO  o.b.s.a.AstraDbSpringApplication
  - Started AstraDbSpringApplication in 7.653 seconds (JVM running for 8.097)

Likewise, if we go to our endpoint in a browser or hit it using curl, we should get a valid response:

同样地,如果我们在浏览器中访问我们的端点,或者用curl点击它,我们应该得到一个有效的响应。

$ curl http://localhost:8080/ping; echo
d23bf54d-1bc2-4ab7-9bd9-2c628aa54e85

Great! Now that we have our database connection established and a simple application using Spring Boot implemented, let’s see how we can store and retrieve data.

很好!现在我们已经建立了数据库连接,并使用Spring Boot实现了一个简单的应用程序,让我们看看我们如何存储和检索数据。

6. Working with Spring Data

6.使用Spring Data

We have several flavors to choose from as a basis for our Cassandra database access. In this tutorial, we’ve opted to use Spring Data which has support for Cassandra.

我们有几种风格可供选择,作为我们访问Cassandra数据库的基础。在本教程中,我们选择使用Spring Data,它具有对Cassandra的支持

The main goal of Spring Data’s repository abstraction is to significantly reduce the amount of boilerplate code required to implement our data access layer, which will help to keep our example really simple.

Spring Data的存储库抽象的主要目标是大大减少实现我们的数据访问层所需的模板代码量,这将有助于保持我们的例子真正简单。

For our data model, we’ll define one entity representing a simple shopping list:

对于我们的数据模型,我们将定义一个代表简单购物清单的实体

@Table
public class ShoppingList {

    @PrimaryKey
    @CassandraType(type = Name.UUID)
    private UUID uid = UUID.randomUUID();

    private String title;
    private boolean completed = false;

    @Column
    private List<String> items = new ArrayList<>();

    // Standard Getters and Setters
}

In this example, we’re using a couple of standard annotations in our bean to map our entity to a Cassandra data table and define a primary key column named uid.

在这个例子中,我们在Bean中使用了几个标准注解,将我们的实体映射到Cassandra的数据表中,并定义了一个名为uid的主键列。

Let’s now create the ShoppingListRepository to be used in our application:

现在让我们创建ShoppingListRepository,在我们的应用程序中使用。

@Repository
public interface ShoppingListRepository extends CassandraRepository<ShoppingList, String> {

    ShoppingList findByTitleAllIgnoreCase(String title);

}

This follows the standard Spring Data repository abstraction. Apart from the inherited methods contained in the CassandraRepository interface, such as findAll, we’ve added an additional method findByTitleAllIgnoreCase that we can use to find a shopping list using the title.

这遵循了标准的Spring Data存储库抽象。除了CassandraRepository接口中包含的继承方法(如findAll)外,我们还添加了一个额外的方法findByTitleAllIgnoreCase,我们可以用它来使用标题查找购物清单。

Indeed one of the real benefits of using the Astra Spring Boot Starter is that it creates the CqlSession bean for us using the properties previously defined.

事实上,使用Astra Spring Boot Starter的真正好处之一是,它使用之前定义的属性为我们创建了CqlSession Bean。

7. Putting It All Together

7.把一切都放在一起

Now we have our data access repository in place, let’s define a simple service and controller:

现在我们有了数据访问库,让我们来定义一个简单的服务和控制器。

@Service
public class ShoppingListService {

    @Autowired
    private ShoppingListRepository shoppingListRepository;

    public List<ShoppingList> findAll() {
        return shoppingListRepository.findAll(CassandraPageRequest.first(10)).toList();
    }

    public ShoppingList findByTitle(String title) {
        return shoppingListRepository.findByTitleAllIgnoreCase(title);
    }
    
    @PostConstruct
    public void insert() {
        ShoppingList groceries = new ShoppingList("Groceries");
        groceries.setItems(Arrays.asList("Bread", "Milk, Apples"));

        ShoppingList pharmacy = new ShoppingList("Pharmacy");
        pharmacy.setCompleted(true);
        pharmacy.setItems(Arrays.asList("Nappies", "Suncream, Aspirin"));

        shoppingListRepository.save(groceries);
        shoppingListRepository.save(pharmacy);
    }
    
}

For the purposes of our test application, we’ve added a @PostContruct annotation to insert some test data into our database.

为了我们的测试应用程序,我们添加了一个@PostContruct注解,以便将一些测试数据插入我们的数据库中。

For the final part of the puzzle, we’ll add a simple controller with one endpoint to retrieve our shopping lists:

对于难题的最后一部分,我们将添加一个简单的控制器,用一个端点来检索我们的购物清单。

@RestController
@RequestMapping(value = "/shopping")
public class ShoppingListController {

    @Autowired
    private ShoppingListService shoppingListService;

    @GetMapping("/list")
    public List<ShoppingList> findAll() {
        return shoppingListService.findAll();
    }
}

Now when we run our application and access http://localhost:8080/shopping/list – we’ll see a JSON response containing our different shopping list objects:

现在,当我们运行我们的应用程序并访问http://localhost:8080/shopping/list – 我们将看到一个包含不同购物清单对象的JSON响应。

[
  {
    "uid": "363dba2e-17f3-4d01-a44f-a805f74fc43d",
    "title": "Groceries",
    "completed": false,
    "items": [
      "Bread",
      "Milk, Apples"
    ]
  },
  {
    "uid": "9c0f407e-5fc1-41ad-8e46-b3c115de9474",
    "title": "Pharmacy",
    "completed": true,
    "items": [
      "Nappies",
      "Suncream, Aspirin"
    ]
  }
]

This confirms that our application is working properly. Awesome!

这证实了我们的应用程序正在正常工作。真棒!

8. Working With Cassandra Template

8.使用Cassandra模板工作

On the other hand, it’s also possible to work directly with the Cassandra Template, the classic Spring CQL approach, and probably still the most popular.

另一方面,也可以直接使用Cassandra模板,这是经典的Spring CQL方法,而且可能仍然是最流行的方法。

Simply put, we can extend our AstraDbApiController quite easily to retrieve our data center:

简单地说,我们可以很容易地扩展我们的AstraDbApiController来检索我们的数据中心。

@Autowired
private CassandraTemplate cassandraTemplate;

@GetMapping("/datacenter")
public String datacenter() {
    return cassandraTemplate
        .getCqlOperations()
        .queryForObject("SELECT data_center FROM system.local", String.class);
}

This will still leverage all the configuration properties we have defined. So as we can see, switching between the two access methods is entirely transparent.

这仍将利用我们所定义的所有配置属性。因此我们可以看到,在两种访问方法之间的切换是完全透明的。

9. Conclusion

9.结论

In this article, we learned how to set up and connect to a hosted Cassandra Astra Database. Next, we built a simple shopping list application to store and retrieve data using Spring Data. Finally, we also discussed how we could work with the lower level access method Cassandra Template.

在这篇文章中,我们学习了如何设置并连接到一个托管的Cassandra Astra数据库。接下来,我们建立了一个简单的购物清单应用程序,使用Spring Data存储和检索数据。最后,我们还讨论了如何与低级别的访问方法Cassandra模板合作。

As always, the full source code of the article is available over on GitHub.

一如既往,文章的完整源代码可在GitHub上获得