Реголит
Эта система позволит хранить ваши данные в БД.
Создайте описание ваших таблиц:
java
package ru.slie.luna.template.db;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import ru.slie.luna.regolith.ActiveDocEntity;
import ru.slie.luna.template.card.CardState;
import java.time.LocalDateTime;
@Entity
@Table(name = "cards")
public class CardEntity extends ActiveDocEntity {
private String value;
private String state;
private LocalDateTime created;
// empty constructor required for morphia
public CardEntity() {}
public CardEntity(String value) {
this.value = value;
this.state = CardState.Open.getState();
this.created = LocalDateTime.now();
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public LocalDateTime getCreated() {
return created;
}
public void setCreated(LocalDateTime created) {
this.created = created;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}Обязательно укажите это в дескрипторе
yaml
activeDocs:
- ru.slie.luna.template.db.CardEntityТеперь вы можете создавать/искать/редактировать и удалять данные с помощью ActiveDocManager.
Пример из демо-проекта:
java
@Component
@Transactional
public class CardManager {
private final ActiveDocManager activeDocManager;
private final I18nResolver i18n;
public CardManager(ActiveDocManager activeDocManager,
I18nResolver i18n) {
this.activeDocManager = activeDocManager;
this.i18n = i18n;
}
private void validate(CardEntity entity) throws ValidateException {
ValidateException validateException = new ValidateException();
if (entity.getValue() == null || entity.getValue().trim().isEmpty()) {
validateException.addError("value", i18n.getText("demo.field.value.required"));
}
if (entity.getState() == null || entity.getState().trim().isEmpty()) {
validateException.addError("value", i18n.getText("demo.field.value.required"));
}
validateException.raise();
}
public Optional<Card> getCardById(Long cardId) {
Optional<CardEntity> entity = activeDocManager.getById(CardEntity.class, cardId);
return entity.map(Card::new);
}
public List<Card> getCards() {
List<CardEntity> cards = activeDocManager.query(CardEntity.class).list();
return cards.stream().map(Card::new).toList();
}
public Card createCard(String value) {
CardEntity entity = new CardEntity(value);
activeDocManager.save(entity);
return new Card(entity);
}
public void saveCard(Card card) throws ValidateException {
CardEntity entity = card.getEntity();
validate(entity);
activeDocManager.save(entity);
}
public DeleteResult delete(Long cardId) {
Optional<CardEntity> entity = activeDocManager.getById(CardEntity.class, cardId);
if (entity.isPresent()) {
activeDocManager.delete(entity.get());
return new DeleteResult(1);
}
return new DeleteResult(0);
}
}Инфо
Используйте Transactional из состава spring-tx, чтобы оптимизировать read-only методы
Сложный запрос
Пример создания сложного запроса c CriteriaBuilder:
java
List<MetricPointDto> points = activeDocManager.getCriteriaBuilder(ScriptRunResultEntity.class)
.from(ScriptRunResultEntity.class, "s")
.selectNew(MetricPointDto.class)
.with("FUNCTION('date_trunc', :timeStep, s.startAt)", "bucket")
.with("COUNT(s.id)", "totalCount")
.with("AVG(s.executionTimeMs)", "avgExecutionTime")
.with("MAX(s.executionTimeMs)", "maxExecutionTime")
.with("AVG(s.cpuTimeMs)", "avgCpuTime")
.with("MAX(s.cpuTimeMs)", "maxCpuTime")
.end()
.where("s.scriptId").eq(scriptId)
.where("s.startAt").between(from).and(to)
.groupBy("FUNCTION('date_trunc', :timeStep, s.startAt)")
.orderByAsc("FUNCTION('date_trunc', :timeStep, s.startAt)")
.setParameter("timeStep", bucketStep)
.getResultList();