-1
最近我創建了一個通用基礎資源庫收集在它所有需要的數據訪問層的方法(的findall,保存,存在,計數....等)應我用組合物或繼承了一般存儲庫
接口如下所示
/**
* Interface for generic CRUD operations on a repository.
*
* @author Farouk_Elabady
*/
public interface BaseRepository<T> {
/**
* Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
* entity instance completely.
*
* @param entity
* @return the saved entity
*/
<E> E save(E entity);
/**
* Saves all given entities.
*
* @param entities of type {@link Iterable}
* @return {@link List} of saved entities
* @throws IllegalArgumentException in case the given entity is {@literal null}.
*/
<E> List<E> save(Iterable<E> entities);
/**
* Saves an entity and flushes changes instantly.
*
* @param entity
* @return the saved entity
*/
<E> E saveAndFlush(E entity);
/**
* Saves all given entities.
*
* @param entities of type {@link Iterable}
* @return {@link List} of saved entities
* @throws IllegalArgumentException in case the given entity is {@literal null}.
*/
<E> List<E> saveAndFlush(Iterable<E> entities);
/**
* Updates a given entity. Use the returned instance for further operations
* as the update operation might have changed the
* entity instance completely.
*
* @param entity
* @return the saved entity
*/
<E> E update(E entity);
/**
* Updates all given entities.
*
* @param entities of type {@link Iterable}
* @return {@link List} of saved entities
* @throws IllegalArgumentException in case the given entity is {@literal null}.
*/
<E> List<E> update(Iterable<E> entities);
/**
* Check whether an entity with the given id exists.
*
* @param entityClass must not be {@literal null}.
* @param id must not be {@literal null}.
* @return true if an entity with the given id exists, {@literal false} otherwise
* @throws IllegalArgumentException if {@code id} is {@literal null}
*/
<E,ID> boolean exists(Class<E> entityClass, ID id);
/**
* Returns an entity by its id.
*
* @param entityClass must not be {@literal null}.
* @param id must not be {@literal null}.
* @return the entity with the given id or {@literal null} if none found
* @throws IllegalArgumentException if {@code id} is {@literal null}
*/
<E,ID> E find(Class<E> entityClass, ID id);
/**
* Returns an entity by its id.
*
* @param id must not be {@literal null}.
* @return the entity with the given id or {@literal null} if none found
* @throws IllegalArgumentException if {@code id} is {@literal null}
*/
<ID> T find(ID id);
/**
* Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
* if {@code Pageable} is null there will be no paging restriction
*
* @param entityClass must not be {@literal null}.
* @param pageable can be {@literal null}
* @return a page of entities
*/
<E> Page<E> findAll(Class<E> entityClass, Pageable pageable);
/**
* Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
* if {@code Pageable} is null there will be no paging restriction
*
* @param pageable can be {@literal null}
* @return a page of entities
*/
Page<T> findAll(Pageable pageable);
/**
* Returns a {@link Page} of entities meeting single parameter and paging restriction provided in the {@code Pageable} object.
* if {@code Pageable} is null there will be no paging restriction
*
* @param entityClass {@link Class} must not be {@literal null}.
* @param pageable {@link Pageable} can be {@literal null}
* @param parameter string to determine the parameter type
* @param value of the parameter
* @return a page of entities
*/
<E> Page<E> findAllByParameter(Class<E> entityClass, Pageable pageable, String parameter, Object value);
/**
* Returns a {@link Page} of entities meeting single parameter and paging restriction provided in the {@code Pageable} object.
* if {@code Pageable} is null there will be no paging restriction
*
* @param pageable {@link Pageable} can be {@literal null}
* @param parameter string to determine the parameter type
* @param value of the parameter
* @return a page of entities
*/
Page<T> findAllByParameter(Pageable pageable, String parameter, Object value);
/**
* Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object with the given IDs.
* if {@code Pageable} is null there will be no paging restriction
*
* @param entityClass must not be {@literal null}.
* @param pageable can be {@literal null}
* @return a page of entities
*/
<E,ID> Page<E> findAllByIds(Class<E> entityClass, Pageable pageable , Iterable<ID> ids);
/**
* Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object with the given IDs.
* if {@code Pageable} is null there will be no paging restriction
*
* @param pageable can be {@literal null}
* @return a page of entities
*/
<ID> Page<T> findAllByIds(Pageable pageable , Iterable<ID> ids);
/**
* Returns the number of entities available.
*
* @param entityClass {@link Class} must not be {@literal null}.
* @return the number of entities
*/
<E> long count(Class<E> entityClass);
/**
* Refreshes the cached entity with recent one from the database
*
* @param entity object to refresh
*/
<E> void refresh(E entity);
/**
* Initialize lazy mapping entity associations
*
* @param entity object to initialize
*/
void initializeCollection(Object entity);
/**
* lock entity object row in db on given LockMode this action depends on database engine capabilities.
*
* @param entity
* @param lockMode
*/
void lock(final Object entity, LockModeType lockModeType);}
和實施,
public abstract class JpaBaseRepository<T> implements BaseRepository<T> { .... }
目前
,如果我想使用這個泛型DAO我下面
public interface AuditRepository extends BaseRepository<AuditableClass>{
//@Transactional
//@Query("SELECT ac FROM AuditableClass ac WHERE LOWER(ac.className) = LOWER(:className)")
AuditableClass getAuditableClassByClassName(@Param("className") String className);
Page<AuditingRecord> getAuditingRecordByUsername(String username);
}
和倉儲類
@Repository
public class JpaAuditRepository extends JpaAuditBaseRepository<AuditableClass>
implements AuditRepository {
@Override
public AuditableClass getAuditableClassByClassName(String className) {
Specifications<AuditableClass> spec = where(
(root, query, cb) -> {
Path<String> p = root.get(getEntityManager().getMetamodel().entity(AuditableClass.class).getSingularAttribute("className" , String.class));
return cb.equal(cb.lower(p), className.toLowerCase());
});
return find(AuditableClass.class, spec);//query.getSingleResult();
}
/* (non-Javadoc)
* @see net.onecard.common.dataaccess.repository.audit.AuditRepository#getAuditingRecordByUsername(java.lang.String)
*/
@Override
public Page<AuditingRecord> getAuditingRecordByUsername(String username) {
return findAll(AuditingRecord.class, new PageRequest(0, 10), " where username = :username", username);
}
}
在這種情況下使用繼承是正確的方式還是應該使用成分?每種方法有哪些優缺點?
我認爲作爲繼承的優點是我可以在注入auditRepository時直接使用這些方法,但是如果我使用組合,我需要在審計存儲庫中編寫更多代碼以公開通用存儲庫方法。
在此先感謝