要想使写的代码具有可复用、可维护、易扩展,我们就要面向接口编程。
添删改查,每增加一个模块都要做添删改查,重复代码之多可想而知,不便于维护,虽然我们使用了持久层框架JPA,但也避免不了重复的代码。
如何才能使重复的代码更少些呢?
采用泛型+反射技术。
首先我们定义一个接口
public interface DAO<T> {
/**
* 保存实体
* @param entity 实体对象
*/
public void save(T entity);
/**
* 更新实体
* @param entity 实体对象
*/
public void update(T entity);
/**
* 删除实体
* @param entityId 实体标识
*/
public void delete(Serializable entityId);//JPA 规定实体的id属性必须实现序列化接口
/**
* 获得实体
* @param entityId 实体标识
* @return 实体对象
*/
public T find(Serializable entityId);
/**
* 获取实体的总记录数
* @return 总记录数
*/
public long getCount();
}
实现类:
public class BaseDao<T> implements DAO<T> {
@PersistenceContext
protected EntityManager em;
/* 实体类*/
@SuppressWarnings("unchecked")
protected Class<T> entityClass = GenericsUtils.getSuperClassGenricType(getClass());
@Override
public void save(T entity) {
em.persist(entity);
}
@Override
public void update(T entity) {
em.merge(entity);
}
@Override
public void delete(Serializable entityId) {
em.remove(em.getReference(entityClass, entityId));
}
@Transactional(propagation=Propagation.NOT_SUPPORTED)
public T find(Serializable entityId) {
return em.find(entityClass, entityId);
}
@Transactional(propagation=Propagation.NOT_SUPPORTED)
public long getCount() {
return (Long) em.createQuery("select count(o) from " + getEntityName(this.entityClass) + " o").getSingleResult();
}
/**
* 获取实体名称
* 在方法上使用泛型
* @param entityClass
* @return
*/
protected static <E>String getEntityName(Class<E> entityClass) {
String entityName = entityClass.getSimpleName();
//获得注解的实体类
Entity entity = entityClass.getAnnotation(Entity.class);
// 注解时是否有name属性,如果有,则使用注解时指定的name属性,否则使用类的简单名称
if(entity.name() != null && !"".equals(entity.name())) {
entityName = entity.name();
}
return entityName;
}
}
如何使用:
只需让你开发的模块的接口继承DAO<T>接口,实现类继承BaseDao
例如:
/**
* 用户业务处理接口
* 一定要继承DAO接口,因为是通过接口操作的
* @author zjq
*
*/
public interface BuyerService extends DAO<Buyer>{
}
/**
* 业务处理类
* 交给spring管理
* 并且支持事务,(spring只会对定义在本类的方法应用事务通知,所以把事务放在父类里面)
* @author zjq
*
*/
@Service("buyerService")//spring只会对定义在本类的方法应用事务通知(Advice)
public class BuyerServiceBean extends BaseDao<Buyer> implements BuyerService {
}