You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Boot整合ES应用:Oracle数据库数据索引与多字段检索实现

Great to hear you've got the basics of your Spring Boot + Elasticsearch app up and running! Let's walk through how to connect it to Oracle, sync your database records to Elasticsearch, and build the search capabilities you need.


Step 1: Add Required Dependencies

First, add Oracle JDBC and Spring Data JPA (to interact with Oracle) to your pom.xml (if using Maven):

<!-- Oracle JDBC Driver -->
<dependency>
    <groupId>com.oracle.database.jdbc</groupId>
    <artifactId>ojdbc8</artifactId>
    <version>19.3.0.0</version>
</dependency>

<!-- Spring Data JPA for Oracle interaction -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- Keep your existing Elasticsearch dependency -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

Step 2: Configure Oracle & Elasticsearch Connections

Update your application.properties with database and Elasticsearch credentials:

# Oracle Database Configuration
spring.datasource.url=jdbc:oracle:thin:@//your-oracle-host:1521/your-service-name
spring.datasource.username=your-oracle-username
spring.datasource.password=your-oracle-password
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver

# JPA Settings (disable auto-table creation since your Oracle table exists)
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle12cDialect

# Elasticsearch Configuration
spring.elasticsearch.uris=http://your-es-host:9200
# Add credentials below if your ES cluster uses authentication
# spring.elasticsearch.username=your-es-username
# spring.elasticsearch.password=your-es-password

Step 3: Update Your Book Entity

Modify your Book class to support both Oracle (JPA) and Elasticsearch mappings:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Entity
@Table(name = "BOOKS") // Match your Oracle table name
@Document(indexName = "books") // Elasticsearch index name
public class Book {
    @Id
    @Column(name = "ID") // Match Oracle column name
    @Field(type = FieldType.Keyword) // Use Keyword for exact ID matches
    private String id;

    @Column(name = "TITLE")
    @Field(type = FieldType.Text, analyzer = "standard") // Text for full-text search
    private String title;

    @Column(name = "AUTHOR")
    @Field(type = FieldType.Text)
    private String author;

    // Add other fields (e.g., publish_date) with matching @Column and @Field annotations

    // Getters and Setters
}

Step 4: Create Repositories for Oracle & Elasticsearch

Build two repositories to handle data operations for each system:

Oracle JPA Repository

import org.springframework.data.jpa.repository.JpaRepository;

public interface BookRepository extends JpaRepository<Book, String> {
    // Add custom Oracle queries if needed (e.g., findByAuthor)
}

Elasticsearch Repository

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;

public interface BookEsRepository extends ElasticsearchRepository<Book, String> {
    // Search books by title (partial match)
    List<Book> findByTitleContaining(String title);

    // Search books by exact author name
    List<Book> findByAuthor(String author);

    // Add more custom search methods as needed
}

Step 5: Sync Oracle Data to Elasticsearch

You'll need to sync existing Oracle records to ES, plus keep future updates in sync. Here are two common approaches:

Option 1: Full Initial Sync (On App Startup)

Create a component to sync all Oracle books to ES when your app starts:

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.List;

@Component
public class InitialDataSync implements ApplicationRunner {

    private final BookRepository bookRepository;
    private final BookEsRepository bookEsRepository;

    // Constructor injection (no need for @Autowired in Spring 4.3+)
    public InitialDataSync(BookRepository bookRepository, BookEsRepository bookEsRepository) {
        this.bookRepository = bookRepository;
        this.bookEsRepository = bookEsRepository;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        List<Book> allBooks = bookRepository.findAll();
        bookEsRepository.saveAll(allBooks);
        System.out.println("Synced " + allBooks.size() + " books from Oracle to Elasticsearch");
    }
}

Option 2: Incremental Sync (For Updates)

Add an event listener to sync Oracle changes to ES in real-time:

import org.springframework.data.rest.core.event.AfterSaveEvent;
import org.springframework.transaction.event.TransactionalEventListener;
import org.springframework.stereotype.Component;

@Component
public class BookSyncListener {

    private final BookEsRepository bookEsRepository;

    public BookSyncListener(BookEsRepository bookEsRepository) {
        this.bookEsRepository = bookEsRepository;
    }

    @TransactionalEventListener
    public void handleBookSave(AfterSaveEvent<Book> event) {
        Book updatedBook = event.getEntity();
        bookEsRepository.save(updatedBook);
        System.out.println("Synced updated book (ID: " + updatedBook.getId() + ") to Elasticsearch");
    }
}

Step 6: Build Search Endpoints

Update your controller to support ID and field-based searches:

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/api/books")
public class BookController {

    private final BookEsRepository bookEsRepository;

    public BookController(BookEsRepository bookEsRepository) {
        this.bookEsRepository = bookEsRepository;
    }

    // Search by ID (exact match)
    @GetMapping("/{id}")
    public ResponseEntity<Book> getBookById(@PathVariable String id) {
        return bookEsRepository.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    // Search by title (partial match)
    @GetMapping("/search/title")
    public List<Book> searchByTitle(@RequestParam String title) {
        return bookEsRepository.findByTitleContaining(title);
    }

    // Search by exact author name
    @GetMapping("/search/author")
    public List<Book> searchByAuthor(@RequestParam String author) {
        return bookEsRepository.findByAuthor(author);
    }
}

Key Notes to Keep in Mind

  • Index Creation: Set spring.data.elasticsearch.repositories.create-index=true in application.properties to let Spring auto-create the ES index, or create it manually with custom mappings for better control.
  • Field Types: Use Keyword for fields you want exact matches (like ID, ISBN) and Text for full-text search (like title, author).
  • Performance: For large Oracle datasets, split the initial sync into batches to avoid memory issues (e.g., use bookRepository.findAll(PageRequest.of(page, 1000))).
  • Error Handling: Add try-catch blocks to sync components to handle failures gracefully.

内容的提问来源于stack exchange,提问作者Karthikeyan

火山引擎 最新活动