gpt4 book ai didi

java - 按父字段查询但返回子类

转载 作者:行者123 更新时间:2023-11-30 09:06:07 30 4
gpt4 key购买 nike

是否可以编写一个服务来提供一种方法,该方法通过父字段选择实体,但返回一个被传递的子类通过参数(或方法上的泛型)输入?

假设 Parent 有一个名为 flag 的字符串字段和两个子字段 Child1Child2ParentService 应该像这样使用:

Child1 child1 = parentService.findFlag(Child1.class, "de");
Child2 child2 = parentService.findFlag(Child2.class, "de");

Child1 child1 = parentService.findFlag<Child1>("de");
Child2 child2 = parentService.findFlag<Child2>("de");

详细示例:

因为很难解释,这段代码应该解释上面的场景:

Java 类:

  • Parameter - 抽象父类具有所有子类的公共(public)字段
    • UiParameter 扩展参数
    • BatchParameter extends Parameter
  • ParameterService - 提供了一个save(Parameter)方法,可以用于UiParameterBatchParameter这个方法被其他服务用于拯救各种 child

现在可以方便地向 ParameterService< 添加一个 find(UiParameter.class, commonFieldSelector)find(BatchParameter.class, commonFieldSelector) 方法.

目前有 4 个样板类(UiParameterService、UiParameterRepository、BatchParameterService、BatchParameterRepository),只有 1 个看起来几乎相似的方法。

@Data
@EqualsAndHashCode(callSuper = true)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("PARAMETER")
public abstract class Parameter extends AbstractEntity
{
// all children will share that
@ManyToOne
private Application commonField;
}

@Data
@Entity
@EqualsAndHashCode(callSuper = true)
public class UiParameter extends Parameter
{
private String foo;
}

@Data
@Entity
@EqualsAndHashCode(callSuper = true)
public class BatchParameter extends Parameter
{
private int size;
}

public interface ParameterRepository extends JpaRepository<Parameter, Long>
{
// That works great, but it returns all kind of children...
List<Parameter> findByCommonField(final Application commonField);
}

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ParameterService
{
private final ParameterRepository parameterRepository;

public ... findByCommonField...(...)
{
return ... magic ...;
}
}

在我们的案例中,所有 Childs 方法的常用服务/存储库导致样板类只有一个 findFlag 方法,该方法从 Child1 复制到 ChildN。

更改域(继承策略)将是一个问题。

Spring-Solution based on Maciejs answer:

public interface ParameterRepository extends JpaRepository<Parameter, Long>
{
@Query("SELECT e FROM Parameter e WHERE TYPE(e) = ?1 AND e.commonField = ?2")
<E extends Parameter> List<E> findByTopic(final Class<E> e, final Application commonField);
}

最佳答案

JPQL 中有TYPE 运算符,可以按如下方式使用:

SELECT e
FROM EntityClass
WHERE TYPE(e) = EntityClassSubclass

您可以使用此查询,然后编写将结果转换为所需类型的通用方法。

private static <T extends SuperClass> List<T> queryForClass(Class<T> myClass) {

Query q = em.createQuery("SELECT p FROM SuperClass p WHERE TYPE(p) = :myClass");
q.setParameter("myClass", myClass);
List<? extends SuperClass> resultList = q.getResultList();

return (List<T>) resultList;
}

关于java - 按父字段查询但返回子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24562576/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com