Как Spring Boot Application, использующий Hibernate, может взаимодействовать с несколькими таблицами, структурированными одинаково? - PullRequest
1 голос
/ 28 марта 2019

У меня есть база данных MySQL под названием «валюта», с более чем сотней таблиц, каждая для одной валюты, и все в идентичной структуре (2 столбца, дата-время для метки времени и число с плавающей точкой для курса).

Как Spring Boot Application может взаимодействовать с этой структурой?

Я хотел бы просто иметь один класс CurrencyRate с полями и методами получения / установки.Если я отмечу этот класс @Entity, @Table, то я могу получить доступ только к одной таблице.Я исследовал отметку @SecondaryTable, но, похоже, это только для ситуаций, в которых мы хотели бы взаимодействовать с несколькими таблицами одновременно, а не с одной.

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Id;
import javax.validation.constraints.NotBlank;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.databind.ser.std.NumberSerializers.FloatSerializer;

public abstract class CurrencyRate implements Serializable {

    @Id
    @JsonSerialize(using=DateSerializer.class)
    private Date datetime;

    @NotBlank
    @JsonSerialize(using=FloatSerializer.class)
    private float rate;

    Date getDate () { return this.datetime; }
    void setDate (Date timestamp) { this.datetime = timestamp; }
    float getRate () { return this.rate; }
    void setRate (float rate) { this.rate = rate; } 
}

У меня была идея, что ямог бы сделать CurrencyRate абстрактным классом (как на рисунке), а затем создать класс для каждой валюты, которая наследуется от этого класса.Это было бы очень утомительно, но по крайней мере это могло бы работать.Однако кажется, что мне нужно было бы создать не только класс для каждой модели валюты, но и класс для каждого репозитория.

Разве есть способ обслуживать эту структуру без всего этого?Есть идеи?В настоящее время просматривает документацию и ищет других людей с этой проблемой, но не похоже, что эта структура очень распространена.

Редактировать:

Я хочу добавитьконтроллер, потому что я считаю, что это место, в котором возникает логическая проблема различения дочерних элементов абстрактного класса.

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/rates")
class CurrencyRateController {

    @Autowired
    private CurrencyRateService service;

    @GetMapping("/allEUR")
    public List<CurrencyRate> getAllEUR() {
        return service.findAll();
    }

    @GetMapping("/allCAD")
    public List<CurrencyRate> getAllCAD() {
        return service.findAll();
    }
}

Приведенный выше контроллер возвращает значения CAD для обоих / allCAD и / allEUR, я полагаюпотому что CurrencyRateService использует CurrencyRateRepository.Где-то Hibernate пытается провести различие между подклассом EUR и подклассом CAD, но они идентичны.Поэтому значения CAD приведены для всех запросов.

Ответы [ 2 ]

0 голосов
/ 28 марта 2019

В вашем сценарии, я думаю, следует использовать стратегию Single Table, поскольку она создаст одну таблицу для каждой иерархии классов.Это также стратегия по умолчанию, выбранная JPA, если мы не укажем ее явно.Вы можете определить стратегию, которую хотите использовать, добавив аннотацию @Inheritance к суперклассу: Родительский объект: -

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class CurrencyRate  {
    @Id
    @JsonSerialize(using=DateSerializer.class)
    private Date datetime;

    @NotBlank
    @JsonSerialize(using=FloatSerializer.class)
    private float rate;

    // constructor, getters, setters
}

Подклассы без поля: -

@Entity
public class Rupee extends CurrencyRate {

}

@Entity
public class Dollar extends CurrencyRate {

}

Сзаписи для всех сущностей будут находиться в одной и той же таблице, Hibernate предоставляет возможность различать эти строки таблицы.В этом случае добавляется столбец дискриминатора, называемый DTYPE, в котором в качестве значения указывается имя объекта.

Вы можете создать репозиторий для CurrencyRate и затем запросить таблицу CurrencyRate на основе столбца DType.

0 голосов
/ 28 марта 2019

Вероятно, вы должны использовать правильную стратегию наследования.Например:

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class CurrencyRate {
  (... omitted for brevity ...)
}

Подклассы:

@Entity
@Table(name="USDOLLAR")
public class UnitedStatesDollar extends CurrencyRate {
}

@Entity
@Table(name="EURO")
public class Euro extends CurrencyRate {
}

И то же самое для других валют.Вы должны иметь возможность выполнять запросы к классу CurrencyRate, получая все результаты из всех таблиц, и вам придется использовать instanceof для различения валют.Также вы сможете выполнить запрос к единой валюте.

Если вы хотите узнать больше о наследовании, взгляните здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...