不幸的是,我感到主流开发人员仍然对此感到恐惧。
但是,比喻海格的蜘蛛,我会说泛型是被严重误解的生物……:-)
我希望以下示例可以证明它们的实用性。
问题 – DAO(数据访问对象)类具有通用的方法,例如保存,更新,删除,loadAll ..,这在每个DAO类中都是必需的。
用这些通用方法编写基类并使每个DAO对象对其进行扩展是远远不够的,因为每个DAO类都代表一个不同的域类,因此通用方法签名中使用的类型是不同的(尽管实现是相似的),例:
class OrderDAO {
//save method receive an Order
public void save(Order order){....}
//getAll method return Orders List
public List<Order> getAll(){...}
}
class UserDAO{
//save method receive an User
public void save(User user){....}
//getAll method return Users List
public List<User> getAll(){...}
}
泛型如何帮助我们创建具有通用实现的基类,同时又保持方法签名的类型安全?
首先,我们需要使用通用方法定义一个接口 :
/**
* Base interface for CRUD operations and common queries
*/
public interface IDaoBase<T> {
public List<T> loadAll();
public void save(T domain);
public void update(T domain);
public void delete(T domain);
public T get(Serializable id);
/**
* Get list by criteria
* @param detachedCriteria the domain query criteria, include condition and the orders.
* @return
*
*/
public List<T> getListByCriteria(DetachedCriteria detachedCriteria);
public List<T> getListByCriteria(DetachedCriteria detachedCriteria, int offset, int size);
}
请注意,我们利用泛型,因此每个方法签名都有一个类型T,在已实现的DAO类中,每个域将是一个具体类型。
第二步是创建一个实现通用功能的抽象类:
public abstract class DaoBase<T> extends HibernateDaoSupport implements IDaoBase<T> {
private Class<T> entityClass;
@Autowired
public void setSession(SessionFactory sessionFactory){
this.setSessionFactory(sessionFactory);
}
public DaoBase() {
entityClass = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
public List<T> loadAll(){
return getHibernateTemplate().loadAll(entityClass);
}
public void delete(T domain) {
getHibernateTemplate().delete(domain);
}
public void save(T domain) {
getHibernateTemplate().saveOrUpdate(domain);
}
public void update(T domain) {
getHibernateTemplate().merge(domain);
}
public T get(Serializable id) {
T o = (T) getHibernateTemplate().get(entityClass, id);
return o;
}
public List<T> getListByCriteria(DetachedCriteria detachedCriteria,
int offset, int size) {
return getHibernateTemplate().findByCriteria(detachedCriteria, offset, size);
}
public List<T> getListByCriteria(DetachedCriteria detachedCriteria) {
return getHibernateTemplate().findByCriteria(detachedCriteria);
}
}
就是这样!
花一两分钟的时间检查基础对象如何以类型安全的方式实现通用功能。
实施新的DAO时,我们要做的就是:
1.接口,以扩展具体类型的IDaoBase
public interface DaoUser extends IDaoBase<User> {//<=Notice the User typing
//Add any additional custom methods..
public User getbyUsername(String username);
public User getbyEmail(String email);
}
2.实现以具体类型扩展DaoBase
//This class has all the common methods, which are type safe for the User class
@Repository("daoUser")
public class DaoUserImpl extends DaoBase<User> implements DaoUser { //<=Notice the User typing
public User getbyUsername(String username) {
// concrete implmentation ...
}
因此,现在您知道使用泛型有多么强大。 希望它现在不再那么令人恐惧,更容易理解了……
参考: DAO层–在Gal Levinsky博客博客中,我们的JCG合作伙伴 Gal Levinsky进行救援的通用名 。
翻译自: https://www.javacodegeeks.com/2012/08/dao-layer-generics-to-rescue.html