Как обработать мягкое удаление в Spring Data JDBC? - PullRequest
0 голосов
/ 30 декабря 2018

Есть ли хороший способ обработки мягкого удаления в Spring Data JDBC?

В Spring Data JPA мы можем либо добавить @Where(clause="is_active=1") аннотацию, либо расширить CrudRepository или PagingAndSortingRepository.

Поскольку Spring Data JDBC не поддерживает SPEL в запросах, мы не можем написать их в общем виде следующим образом:

@NoRepositoryBean
public interface SoftDeleteCrudRepository<T extends BasicEntity, ID extends 
Long> extends CrudRepository<T, ID> {
//Override CrudRepository or PagingAndSortingRepository's query method:
@Override
@Transactional(readOnly = true)
@Query("select e from #{#entityName} e where e.deleteFlag=false")
public List<T> findAll();

//Look up deleted entities
@Query("select e from #{#entityName} e where e.deleteFlag=true")
@Transactional(readOnly = true)
public List<T> findAllDeleted(); 

//Soft delete.
@Query("update #{#entityName} e set e.deleteFlag=true where e.id=?1")
@Transactional
@Modifying
public void softDelete(String id);
...
}

Таким образом, расширение CrudRepository или PagingAndSortingRepository означает написание одинаковых запросов для каждогохранилище для каждой сущности / таблицы?Как

Repository1
@Override
@Transactional(readOnly = true)
@Query("select id, name, value, deleteFlag from table1 e where e.deleteFlag=false")
public List<T> findAll();
....

Repository2
@Override
@Transactional(readOnly = true)
@Query("select id, name, value, deleteFlag from table2 e where e.deleteFlag=false")
public List<T> findAll();
....

Спасибо за ответ заранее!

Ответы [ 2 ]

0 голосов
/ 15 января 2019

@ Декстер, мы используем тип INT в db, чтобы пометить активное состояние записи. Если вы используете логическое значение, вы можете изменить перечисление StateTag (может быть, интерфейс лучше), а затем вызвать changeState, чтобы изменить состояние.удаление или отключение рассматривается на уровне бизнес-сервисов, например:

public class RoleServiceImpl extends SoftDeleteRepositoryServiceImpl<Role, Long>
    implements RoleService {
    private static final Logger LOGGER = LoggerFactory.getLogger(RoleServiceImpl.class);

.......

@Override
public Role deleteRole(Long roleId) {
    return softDelete(roleId);
}

}

и

 public class SoftDeleteRepositoryServiceImpl<T, ID extends Serializable> extends BasicRepositoryServiceImpl<T, ID>
    implements SoftDeleteRepositoryService<T, ID> {


@Override
public T enable(ID id) {
    return updateState(id, ENABLED);
}

  ........

@Override
public T softDelete(ID id) {
    return updateState(id, DELETED);
}
}
0 голосов
/ 31 декабря 2018

В настоящее время я вижу три варианта, как можно этого достичь.

  1. Использовать представления.Для каждого совокупного корня создайте представление базы данных, которое отфильтровывает мягко удаленные строки.Сопоставьте свои сущности с этими представлениями.

  2. напишите свое собственное SqlGenerator.И введите его в DefaultDataAccessStrategy через SqlGeneratorSource.Поскольку SqlGenerator является видимым только для пакета, вам придется создать свой собственный DefaultDataAccessStrategy для этого, в основном, для дублирования существующего.Это, конечно, будет сопряжено с долгосрочными затратами на его обслуживание.

  3. Поскольку все, что вам кажется необходимым для вашего сценария, - это особая поддержка SpEL для имени объекта, открывающеговопрос для этого и отправка запроса может быть жизнеспособным вариантом.Если вы заинтересованы в таком подходе и вам нужна дополнительная помощь, укажите это в описании проблемы.

...