gpt4 book ai didi

java - Java中按实体类型检索存储库

转载 作者:行者123 更新时间:2023-12-02 11:41:46 26 4
gpt4 key购买 nike

我正在编写Java程序,它通过Hibernate与Db交互。

我所有的持久类都从公共(public)抽象类 Entity 扩展而来。它实现接口(interface)IEntity 。例如:

public interface IEntity {
long getId();
void setId(long id);
}

public abstract class Entity implements IEntity {
private long id;
//get + set id
}

public class User extends Entity {
private string name;
//get + set name
}

public class Item extends Entity {
private string description;
//get + set description
}

对于 Db 的操作,我创建了从 Repository<T extends IEntity> 扩展的存储库类。对所有实体使用标准 CRUD 方法,并且此类实现接口(interface) IRepository<T extends IEntity> :

public interface IRepository<T extends IEntity> {
void create(T object) throws JDBCException;
//other CRUD operations
}

public abstract class Repository<T extends IEntity> implements IRepository<T> {
private final Class<T> entityClass;
protected final EntityManager entityManager;

public Repository(Class<T> entityClass, EntityManager entityManager) {
this.entityClass = entityClass;
this.entityManager = entityManager;
}

@Override
public void create(T object) throws JDBCException {
entityManager.getTransaction().begin();
entityManager.persist(object);
entityManager.getTransaction().commit();
}
//other CRUD operations implementation
}

public class UserRepository extends Repository<User> {
public UserRepository (EntityManager entityManager) {
super(AmountUnit.class, entityManager);
}
}

public class ItemRepository extends Repository<Item> {
public ItemRepository (EntityManager entityManager) {
super(AmountUnit.class, entityManager);
}
}

这种结构运行良好,直到我决定创建方法来通过其实体类获取特定存储库。我认为这个方法是这样的:

public <T extends IEntity, U extends IRepository<T>> U getByType(T object) {
// code here
}

比方说,那个类 User extends Entity并具有存储库类 UserRepository extends Repository<User>我期望这个方法应该返回 Repository for用户对象`。

从我的角度来看,这可以通过两种方式实现:

  1. 优雅。为 IRepository 创建方法-Class<T> getEntityClass然后比较 getEntityClass 的输入类和结果类
  2. 愚蠢。赚很多if/else该方法内的语句并返回存储库。 if(object instanceof A) return ARepository

    public class Storage {
    private IRepository<? extends IEntity>[] repositories;

    public <T extends IEntity, U extends IRepository<T>> U getByTypeVar1(T object) {
    for (IRepository<?> repo : repositories) {
    if (object instanceof repo.getEntityClass ()) // cannot resolve getEntityClass
    return repo;
    }
    }

    public <T extends IEntity, U extends IRepository<T>> U getByTypeVar2(T object) {

    if (object instanceof UserRepository.getEntityClass ())
    return UserRepository; //incompatible type
    //more if else here

    }
    }

但是这两个实现都无法编译。也许您有任何想法如何正确编写此方法

最佳答案

您可以像这样实现getByType方法(我更改了参数类型):

private List<IRepository<? extends IEntity>> repositories;

@SuppressWarnings("unchecked")
public <E extends IEntity> IRepository<E> getByType(Class<E> entityClass) {
for (IRepository<?> repository : repositories) {
if (repository.getEntityClass().equals(entityClass)) {
return (IRepository<E>) repository;
}
}
throw new IllegalArgumentException(
"No repository for entity class " + entityClass.getName());
}

当您发布无法编译的代码时,我们可以找出问题所在。

更新(代码注释)

您应该将 getEntityClass() 方法添加到 IRepository。为了使代码不那么复杂,您可以替换:

<T extends IEntity, U extends IRepository<T>> U getByType()

<T extends IEntity> IRepository<T> getByType getByType()

中使用 instanceof
object instanceof repo.getEntityClass ()

可能会出现问题,因为您可能拥有实体层次结构,并且可能会获得错误的对象(子类)存储库。如果你不知道该对象的类,可以通过以下方式获取(该对象可以是 Hibernate 代理):

org.hibernate.Hibernate.unproxy(object).getClass()

然后通过repository.getEntityClass().equals(entityClass)比较类。

关于java - Java中按实体类型检索存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48490123/

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