在抽象的JPA DAO中抽象命名查询

yoa*_*str 10 java hibernate jpa jpa-2.0

我有一个抽象的DAO类,它使用参数化类型E(实体)和K(主键).在每个实体我都有@NamedQuery.我想在不知道其确切名称和参数名称的情况下动态调用此命名查询.

例如,想象下面的实体 City

@Entity(name="CITY")
@NamedQuery(
    name="findCityByname",
    query="FROM CITY c WHERE name = :CityName"
)
public class City { 
    // ...
}
Run Code Online (Sandbox Code Playgroud)

还有这个 CityDao

public class CityDao extends AbstractDao<City, Long> {
    public CityDao() {
        super(City.class);
    }   
}
Run Code Online (Sandbox Code Playgroud)

我应该如何实现该findByName()方法,AbstractDao以便我不需要知道确切的名称和参数名称?

public abstract class AbstractDao<E, K> implements Dao<E, K> {

    @PersistenceContext
    protected EntityManager entityManager;
    protected Class<E> entityClass;

    protected AbstractDao(Class<E> entityClass) {
        this.entityClass = entityClass; 
    }

    @Override
    public E findByName(String name) {
        try {
            return (E) entityManager
                .createNamedQuery("findCityByName")
                .setParameter("CityName", name)
                .getSingleResult();
        } catch(Exception e) {
            return null;
        }
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

Jör*_*ann 12

命名查询的命名约定通常是<Entity Name>.findBy<PropertyAndAnotherProperty>示例中的"City.findByName",因此我将尝试更改命名查询以遵循此模式.此查询的参数也应该具有相同的名称,或者您可以使用位置参数.然后你的find方法会变成

@Override
public E findByName(String name) {
    E entity = null;
    try {
        return (E)entityManager.createNamedQuery(myClass.getSimpleName() + ".findByName")
                               .setParameter("name", name)
                               .getSingleResult();
    } catch (Exception ex) {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)