【问题标题】:Generic class for CRUD operations for domain models用于域模型的 CRUD 操作的通用类
【发布时间】:2020-07-03 18:28:03
【问题描述】:

我的目标是为 CRUD 操作使用一个通用类,这样我就不需要为我的应用程序中的每个域模型实现一个单独的类。

这一层还在我的 DTO 和域模型之间进行转换。

get 和 delete 方法工作正常。但是,我该如何实现 save 方法。如果是新实体,我需要创建一个新的泛型实例并在其上映射 DTO。

/**
 * This class can be extended to use default CRUD features
 *
 * @param <T> domain model
 * @param <V> DTO represenation of domain model
 */
@RequiredArgsConstructor
public abstract class AbstractCrudService<T extends CoreDomain, V extends CoreDTO> implements CrudStrategy<T, V>{
    
    private final JpaRepository<T, Long> repository;
    private final ModelMapper modelMapper;
    private final Class<V> dtoClass;    
    
    @Override
    public List<V> getAll() {
        List<V> list = new ArrayList<>();
        for (T item : repository.findAll()) {
            list.add(modelMapper.map(item, dtoClass));
        };      
        return list;
    }

    @Override
    public V getById(Long id) {
        T entity = getEntity(id);
        return modelMapper.map(entity, dtoClass);
    }

    @Override
    public void delete(Long id) {
        repository.deleteById(id);      
    }


    @Override
    @Transactional
    public void save(V dto) {
        T entity = new T(); /// DOESNT WORK!!!!
        
        // for edit operation, load existing entity from the DB
        if (dto.getId() != null) {
            entity = getEntity(dto.getId());
        }
        
        modelMapper.map(dto, entity);   
    }
    
    @Override
    public T getEntity(Long id) {
        Optional<T> entity = Optional.ofNullable(repository.findById(id)    
                .orElseThrow(() -> new NoSuchElementException(String.format("Entity with id %s not found", id))));
        return entity.get();
    }   
    
}

我的服务类如下所示:

@Service
public class Test extends AbstractCrudService<Project, ProjectDTO>{
    
    private final ProjectRepository projectRepository;
    private final ModelMapper modelMapper;
    
    public Test(ProjectRepository projectRepository, ModelMapper modelMapper) {
        super(projectRepository, modelMapper, ProjectDTO.class);
        this.projectRepository = projectRepository;
        this.modelMapper = modelMapper;
    }   
        
}

【问题讨论】:

标签: java spring-boot generics persistence crud


【解决方案1】:

我通过以下实现解决了它:

    @Override
    @Transactional
    @SuppressWarnings("unchecked")
    public void save(V dto) {

        ParameterizedType paramType = (ParameterizedType) entityClass.getGenericSuperclass();
        T entity = (T) paramType.getActualTypeArguments()[0];

        // for edit operation, load existing entity from the DB
        if (dto.getId() != null) {
            entity = getEntity(dto.getId());
        }

        modelMapper.map(dto, entity);
    }

【讨论】:

  • 这里的entityClass 变量是什么?你不能用entityClass.newInstance()吗?
  • @Iłya Bursov 是的,但它说“Class 类型的方法 newInstance() 自版本 9 起已弃用” - 我使用的是 Java 11
  • 因为java 9 newInstance 可以替换为entityClass.getDeclaredConstructor().newInstance()
猜你喜欢
  • 1970-01-01
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-19
  • 1970-01-01
  • 2014-06-14
  • 2014-04-07
相关资源
最近更新 更多