2010-11-23 15 views
0

Um ein Uni-Projekt zu beenden, muss ich ein generisches DAO erstellen.Generic DAO and Wrapper

Ich folgte dem generischen DAO-Design, wie es im Manning-Buch Java-Persistenz mit Hibernate zu finden ist. en endete mit den folgenden Methoden.

Das Problem ist, dass diese Methode nicht genug für mein Projekt ist, das aus dem Suchen von Entitäten, dem Bestellen von ihnen und dem Paging besteht. Ich verstehe, dass ich kann das tun, indem ein Verfahren wie

List<T> find(DetachedCriteria dc) 

Schaffung Das Problem ist, das würde bedeuten, dass ich eine Hibernate-Schnittstelle zur Business-Schicht zu, und ich will das nicht.

Ich möchte eine Schnittstelle sagen sagen MyCriteria und eine Klasse sagen MyCriteriaImpl, die das gleiche wie die DetachedCriteria tun würde, aber würde ich den Persistenzanbieter ändern, indem Sie nur die Implementierung ändern. Ich denke, es ist möglich.

Das Problem ist, dass ich keine Zeit habe, solchen Code zu schreiben.

Was ich wissen möchte, ist, wenn es ein Muster gibt, mit dem ich die MyCriteria-Schnittstelle erstellen könnte, und in der MyCriteriaImpl nur Methoden der Hibernate-Kriterien API aufrufen.

Like:

MyCriteriaImpl mci = new MyCriteriaImpl(); 
mci.addRestrictionLike(property, String value); 

und das würde bedeuten, nur einen Anruf an:

DetachedCriteria dc = new DetachedCriteria(); 
dc.add(Restrictions.like(property, value) 

Dank

Antwort

0

Hades bietet alles, was Sie in einer allgemeinen DAO-Schnittstelle erfordern. Wenn Sie Ihre selbstgewachsenen Sachen durch diese ersetzen können, oder Sie können durch den Code browsen, wenn Sie nur als Referenz suchen. Es hat Unterstützung für Paging usw.

+1

Hallo, Es ist nicht wirklich über einen generischen Dao (Ich habe bereits Hibernate-Generic-Dao gefunden, die alle die Pfiffe haben, die ich haben wollte). Es geht mehr darum, das richtige Muster zu verwenden, wenn Sie eine Lösung für ein definiertes Problem benötigen. Deshalb wollte ich ein Muster, mit dem ich die DetachedCriteria-Klasse verwenden kann, aber ein Objekt, das nicht aus dem Hibernate-Api stammt. – Tadili

+0

+1 für die Angabe Hibernate-Generic-Dao –

1

Verwenden Sie diese. Es hat Seitennummerierung sowie Lucene-Integration. Ich habe dieses für eines meiner Projekte erstellt. Stellen Sie sicher, dass sich jedes DAO davon erstreckt. Nimm heraus, was du nicht brauchst.

package com.isavera.hibernate; 

import java.io.Serializable; 
import java.lang.reflect.Method; 
import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Collections; 
import java.util.HashMap; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 
import java.util.Map.Entry; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

import org.apache.commons.lang.StringUtils; 
import org.apache.lucene.analysis.standard.StandardAnalyzer; 
import org.apache.lucene.queryParser.MultiFieldQueryParser; 
import org.apache.lucene.queryParser.ParseException; 
import org.hibernate.Criteria; 
import org.hibernate.LockMode; 
import org.hibernate.Query; 
import org.hibernate.annotations.Cache; 
import org.hibernate.annotations.CacheConcurrencyStrategy; 
import org.hibernate.criterion.Criterion; 
import org.hibernate.search.FullTextSession; 
import org.hibernate.search.Search; 
import org.springframework.beans.BeansException; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.ApplicationContextAware; 
import org.springframework.dao.ConcurrencyFailureException; 
import org.springframework.orm.hibernate3.support.HibernateDaoSupport; 
import org.springframework.transaction.annotation.Transactional; 
import org.springframework.transaction.interceptor.TransactionAspectSupport; 

import com.isavera.actions.utils.Application; 

@SuppressWarnings("serial") 
@Transactional 
public abstract class AbstractDAOImpl<E> extends HibernateDaoSupport implements AbstractDAO<E>, ApplicationContextAware { 


private static final String CLASS_NAME = AbstractDAOImpl.class.getName(); 

private static final Logger LOG = Logger.getLogger(CLASS_NAME); 

private static ApplicationContext _applicationContext; 

private final Class<? extends E> _entityClass; 

/** 
* @param entityClass 
*/ 
public AbstractDAOImpl(Class<? extends E> entityClass) { 
    super(); 

    _entityClass = entityClass; 
} 


public void delete(E entity) { 
    LOG.entering(CLASS_NAME, "delete", entity); 

    getHibernateTemplate().delete(entity); 

    LOG.exiting(CLASS_NAME, "delete"); 
} 

public void evict(E entity) { 
    LOG.entering(CLASS_NAME, "evict", entity); 

    getHibernateTemplate().evict(entity); 

    LOG.exiting(CLASS_NAME, "evict"); 
} 

public void deleteAll(Collection<E> entities) { 
    getHibernateTemplate().deleteAll(entities); 
} 

@SuppressWarnings("unchecked") 
public List<E> findByNamedQuery(String queryName) { 
    return getHibernateTemplate().findByNamedQuery(queryName); 
} 

@SuppressWarnings("unchecked") 
public List<E> findByNamedQueryAndNamedParam(String queryName, String paramName, Object value) { 
    return getHibernateTemplate().findByNamedQueryAndNamedParam(queryName, paramName, value); 
} 

@SuppressWarnings("unchecked") 
public List<E> findByNamedQueryAndNamedParam(String queryName, String[] paramNames, Object[] values) { 
    return getHibernateTemplate().findByNamedQueryAndNamedParam(queryName, paramNames, values); 
} 

public E get(Serializable id) { 
    LOG.entering(CLASS_NAME, "get", id); 

    @SuppressWarnings("unchecked") 
    E entity = (E) getHibernateTemplate().get(_entityClass, id); 

    LOG.exiting(CLASS_NAME, "get", entity); 

    return entity; 
} 

public List<E> get(Criterion... criterion) { 
    LOG.entering(CLASS_NAME, "get", criterion); 

    Criteria criteria = getSession().createCriteria(_entityClass); 

    for (Criterion c : criterion) { 
     criteria.add(c); 
    } 

    @SuppressWarnings("unchecked") 
    List<E> list = new ArrayList<E>(criteria.list()); 

    LOG.exiting(CLASS_NAME, "get", list); 

    return list; 
} 

public boolean isEntityAttached(E entity) { 
    return getHibernateTemplate().getSessionFactory().getCurrentSession().contains(entity); 
} 

public E load(Serializable id) { 
    LOG.entering(CLASS_NAME, "load", id); 

    @SuppressWarnings("unchecked") 
    E entity = (E) getHibernateTemplate().load(_entityClass, id); 

    LOG.exiting(CLASS_NAME, "load", entity); 

    return entity; 
} 

public E load(Serializable id, LockMode lockMode) { 
    LOG.entering(CLASS_NAME, "load", new Object[] { id, lockMode }); 

    @SuppressWarnings("unchecked") 
    E entity = (E) getHibernateTemplate().load(_entityClass, id, lockMode); 

    LOG.exiting(CLASS_NAME, "load", entity); 

    return entity; 
} 

public void load(E entity, Serializable id) { 
    LOG.entering(CLASS_NAME, "load", new Object[] { entity, id }); 

    getHibernateTemplate().load(entity, id); 

    LOG.exiting(CLASS_NAME, "load"); 
} 

public void lock(E entity, LockMode lockMode) { 
    LOG.entering(CLASS_NAME, "lock", new Object[] { entity, lockMode }); 

    getHibernateTemplate().lock(entity, lockMode); 

    LOG.exiting(CLASS_NAME, "lock"); 
} 



public void saveOrUpdateAll(Collection<E> entities) { 
    getHibernateTemplate().saveOrUpdateAll(entities); 
} 

@SuppressWarnings("unchecked") 
public E merge(E entity) { 
    LOG.entering(CLASS_NAME, "merge", entity); 

    E persistentEntity = (E) getHibernateTemplate().merge(entity); 

    LOG.exiting(CLASS_NAME, "merge", persistentEntity); 

    return persistentEntity; 
} 

public void refresh(E entity) { 
    LOG.entering(CLASS_NAME, "refresh", entity); 

    getHibernateTemplate().refresh(entity); 

    LOG.exiting(CLASS_NAME, "refresh"); 
} 

public Long save(E entity) { 
    LOG.entering(CLASS_NAME, "save", entity); 

    LOG.exiting(CLASS_NAME, "save"); 

    return (Long) getHibernateTemplate().save(entity); 
} 

public void saveOrUpdate(E entity) { 
    LOG.entering(CLASS_NAME, "saveOrUpdate", entity); 

    getHibernateTemplate().saveOrUpdate(entity); 

    LOG.exiting(CLASS_NAME, "saveOrUpdate"); 
} 

public void update(E entity) { 
    LOG.entering(CLASS_NAME, "update", entity); 

    getHibernateTemplate().update(entity); 

    LOG.exiting(CLASS_NAME, "update"); 
} 

/** 
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) 
*/ 
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
    setStaticApplicationContext(applicationContext); 
} 

private static void setStaticApplicationContext(ApplicationContext applicationContext) { 
    _applicationContext = applicationContext; 
} 

/** 
* @param queryName 
* @return count 
*/ 
protected int getCounter(String queryName) { 
    @SuppressWarnings("unchecked") 
    List<Number> counterList = getHibernateTemplate().findByNamedQuery(queryName); 

    return counterList == null || counterList.isEmpty() ? 0 : counterList.iterator().next().intValue(); 
} 

/** 
* @param queryName 
* @param paramName 
* @param value 
* @return count 
*/ 
protected int getCounter(String queryName, String paramName, Object value) { 
    @SuppressWarnings("unchecked") 
    List<Number> counterList = getHibernateTemplate().findByNamedQueryAndNamedParam(queryName, paramName, value); 

    return counterList == null || counterList.isEmpty() ? 0 : counterList.iterator().next().intValue(); 
} 

/** 
* @param queryName 
* @param paramNames 
* @param values 
* @return count 
*/ 
protected int getCounter(String queryName, String[] paramNames, Object[] values) { 
    @SuppressWarnings("unchecked") 
    List<Number> counterList = getHibernateTemplate().findByNamedQueryAndNamedParam(queryName, paramNames, values); 

    return counterList == null || counterList.isEmpty() ? 0 : counterList.iterator().next().intValue(); 
} 

public List<E> narrowSearch(String keyword) { 
    List<E> result = Collections.EMPTY_LIST; 
    if (StringUtils.isBlank(keyword)) { 
     return result; 
    } 
    try { 
     Method method = _entityClass.getMethod("SEARCHABLE_FIELDS"); 
     if (method == null) { 
      throw new RuntimeException(_entityClass + " should respond to static method call - SEARCHABLE_FIELDS"); 
     } 
     result = narrowSearch(keyword, (String[]) method.invoke(null, null), _entityClass); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
    return result; 
} 

public List<E> search(String keyword) { 
    List<E> result = Collections.EMPTY_LIST; 
    if (StringUtils.isBlank(keyword)) { 
     return result; 
    } 
    try { 
     Method method = _entityClass.getMethod("SEARCHABLE_FIELDS"); 
     if (method == null) { 
      throw new RuntimeException(_entityClass + " should respond to static method call - SEARCHABLE_FIELDS"); 
     } 
     result = search(keyword, (String[]) method.invoke(null, null), _entityClass); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
    return result; 
} 

private List<E> search(String keyword, String[] fields, Class clazz) { 
    Map<String, Integer> paginationOptions = Application.getPaginationOptions(); 
    Integer pageNumber = Integer.valueOf(1); 
    Integer perPage = Integer.valueOf(5); 

    if (paginationOptions.containsKey("perPage")) { 
     pageNumber = paginationOptions.get("pageNumber"); 
     perPage = paginationOptions.get("perPage"); 
    } 

    FullTextSession fullTextSession = Search.getFullTextSession(getHibernateTemplate().getSessionFactory().getCurrentSession()); 

    // create native Lucene query 
    MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, new StandardAnalyzer()); 
    org.apache.lucene.search.Query query; 
    try { 
     query = parser.parse(keyword); 
     // wrap Lucene query in a org.hibernate.Query 
     org.hibernate.search.FullTextQuery hibQuery = fullTextSession.createFullTextQuery(query, clazz); 
     hibQuery.setFirstResult((pageNumber - 1) * perPage); 
     hibQuery.setMaxResults(perPage); 
     Application.setResultSize(hibQuery.getResultSize()); 
     // execute search 
     return hibQuery.list(); 
    } catch (ParseException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    return null; 
} 

private List<E> narrowSearch(String keyword, String[] fields, Class clazz) { 
    /** 
    * Need to identify better way of doing this for performance reasons. 
    */ 
    List<E> results = new ArrayList<E>(); 
    for (String word : keyword.split(" ")) { 
     if (results.isEmpty()) { 
      results.addAll(search(word, fields, clazz)); 
     } else { 
      results.retainAll(search(word, fields, clazz)); 
     } 
    } 
    return results; 
} 

protected static <T extends AbstractDAO<?>> T getDAO(String beanName, Class<T> clazz) { 
    return clazz.cast(_applicationContext.getBean(beanName, clazz)); 
} 


protected int getCount(List<Number> counterList) { 
    return counterList == null || counterList.isEmpty() ? 0 : counterList.iterator().next().intValue(); 
} 

@SuppressWarnings("unchecked") 
protected List paginateByNamedQueryAndNamedParam(String hqlName, Map<String, Object> params) { 
    Query namedQuery = getHibernateTemplate().getSessionFactory().getCurrentSession().getNamedQuery(hqlName); 
    configurePagination(namedQuery); 

    for (Entry<String, Object> parameter : params.entrySet()) { 
     if (parameter.getValue() instanceof Collection) { 
      namedQuery.setParameterList(parameter.getKey(), (Collection) parameter.getValue()); 
     } else if (parameter.getValue() instanceof Object[]) { 
      namedQuery.setParameterList(parameter.getKey(), (Object[]) parameter.getValue()); 
     } else { 
      namedQuery.setParameter(parameter.getKey(), parameter.getValue()); 
     } 

    } 
    return namedQuery.list(); 
} 

@SuppressWarnings("unchecked") 
protected List paginateByNamedQuery(String hqlName) { 
    Query namedQuery = getHibernateTemplate().getSessionFactory().getCurrentSession().getNamedQuery(hqlName); 
    configurePagination(namedQuery); 

    List result = namedQuery.list(); 

    resetPagination(namedQuery); 

    return result; 
} 

private void resetPagination(Query namedQuery) { 
    getHibernateTemplate().setMaxResults(0); 
} 

private void configurePagination(Query namedQuery) { 
    Integer pageNumber = Application.getPaginationOptions().get("pageNumber"); 
    Integer perPage = Application.getPaginationOptions().get("perPage"); 

    if (pageNumber != null && pageNumber > 1) { 
     namedQuery.setFirstResult((pageNumber - 1) * perPage); 
    } 
    namedQuery.setMaxResults(perPage == null ? 5 : perPage); 
} 



} 
+1

Hallo, in dieser Klasse Sie diese Methode öffentliche Liste bekommen (Kriterium ... Kriterium), die die Hibernate-API dem Client ausgesetzt sind, das ist das Problem, das ich versucht habe lösen. Auch bevorzuge ich die Kriterien-API über die HQL (nie wirklich gemocht). – Tadili

+0

Kriterien API ist langsamer als HQL glaube ich. Also probiere das aus. –