栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

ParameterizedType并创建通用dao

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ParameterizedType并创建通用dao

不幸的是,没有任何方法可以使其完全按照您的要求工作。

第1部分。为什么它不起作用

需要注意的确切声明

GenericDaoJpaImpl
-
GenericDaoJpaImpl<T, PK extends Serializable> implements GenericDao<T, PK>

ClassCastException
之所以抛出,是因为
getClass().getGenericSuperclass()
返回的实例(
Class<java.lang.Object>
Type
java.lang.Class
实现
java.lang.reflect.Type
),但是不是)
ParameterizedType
。实际上,对于每个直接超类为的类,
Class<java.lang.Object>
将由的实例返回。因此,像
getClass().getGenericSuperclass()``java.lang.Object

public GenericDaoJpaImpl() {    ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();    this.entityClass = (Class<T>) genericSuperclass.getActualTypeArguments()[0];}

适用于声明为的类

alerteAcheteurGenericDaoJpaImpl extendsGenericDaoJpaImpl<alerteAcheteur, Integer>
。但这正是您不希望声明DAO的方式。

摘录1(如果是从您运行的

GenericDaoJpaImpl
)将打印
T
PK
(它们都是的实例
sun.reflect.generics.reflectiveObjects.TypeVariableImpl
)。

片段1

Type[] genericInterfaces = getClass().getGenericInterfaces();ParameterizedType genericInterface = (ParameterizedType) genericInterfaces[0];System.out.println(genericInterface.getActualTypeArguments()[0]);System.out.println(genericInterface.getActualTypeArguments()[1]);

片段2

@Bean(name = "alerteVendeurDao")public GenericDao<alerteVendeur, Long> alerteVendeurDao() {    return new GenericDaoJpaImpl<alerteVendeur, Long>();}

即使存在Snippet
2中带

@Configuration
注释的类之类的内容,在运行时也无法知道
GenericDaoJpaImpl
由于类型Erase导致参数化了。但是,如果代码片段1是从类似的代码执行的
alerteAcheuteurDaoimplements GenericDao<alerteAcheuteur, Long>
classsomepackage.entity.alerteAcheteur
并且
classjava.lang.Long
将被打印(因为这些参数是明确的,并且在编译时是已知的)。

最后,组件扫描甚至在逻辑上都不适用于

GenericDaoJpaImpl
。带
@Component
注释类的Bean 是“
Singleton”作用域的。除了将只创建一个实例这一事实之外,我们如何知道该单例DAO应该在哪个实体上运行?尽管如此,容器仍然能够实例化
GenericDaoJpaImpl
,因为在运行时类型信息已经被擦除(类型擦除!)。

此外,在相关情况下,建议使用更具体的注释DAO

@Repository
,而不是
@Component

第2部分。什么是最好的选择?

在您的特定情况下,最好的选择是将实体类声明为构造函数参数。这样,可以

GenericDaoJpaImpl
通过将适当的构造函数参数传递给每个实例来在Spring配置中创建大量特定于实体的实例。

通用DaoJpaImpl.java

public class GenericDaoJpaImpl<T, PK extends Serializable> implements GenericDao<T, PK> {    private final Class<T> entityClass;    @PersistenceContext    protected EntityManager entityManager;    public GenericDaoJpaImpl(Class<T> entityClass) {        this.entityClass = entityClass;    }    @Override    public T create(T t) {        this.entityManager.persist(t);        return t;    }    @Override    public T read(PK id) {        return this.entityManager.find(entityClass, id);    }    @Override    public T update(T t) {        return this.entityManager.merge(t);    }    @Override    public void delete(T t) {        t = this.entityManager.merge(t);        this.entityManager.remove(t);    }    @Override    public void delete(Set<T> ts) {        for( T t : ts){ t = this.entityManager.merge(t); this.entityManager.remove(t);        }    }}

AnnotationContextConfiguration.java

请注意,也可以通过基于构造函数的依赖注入在XML中执行相同的操作。

@Configuration@ComponentScan("somepackage.service")// scan for services, but not for DAOs!public class Config {    @Bean(autowire = Autowire.BY_NAME)    public GenericDaoJpaImpl<alerteAcheteur, Long> alerteAcheteurDao() {        return new GenericDaoJpaImpl<alerteAcheteur, Long>(alerteAcheteur.class);    }    @Bean(autowire = Autowire.BY_NAME)    public GenericDao<alerteVendeur, Long> alerteVendeurDao() {          return new GenericDaoJpaImpl<alerteVendeur, Long>(alerteVendeur.class);    }   // other DAOs   ...}

alerteServiceImpl.java (看起来如何)

请注意,字段名称很重要,因为DAO通过名称自动连接。如果你不希望类似名称的字段

alerteAcheteurDao
,你可以使用
@Qualifier
@Autowired

@Servicepublic class alerteServiceImpl implements alerteService {    @Autowired    private GenericDao<alerteAcheteur, Long> alerteAcheteurDao;    @Autowired    private GenericDao<alerteVendeur, Long> alerteVendeurDao;    ...}

这是一个非常优雅的解决方案。您不必发送垃圾邮件之类的消息

alerteAcheteurGenericDaoJpaImpl extendsGenericDaoJpaImpl<alerteAcheteur,Integer>
。添加新实体后,您只需
GenericDaoJpaImpl
向Spring配置添加新实例。

我希望这会有所帮助。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/377460.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号