Hibernate Dao辅助类,提供Dao的基本操作

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.assess.lang.Paging;
import com.assess.lang.util.Misc;
@Resource
public class DaoHelper {
    @Resource
    private SessionFactory sessionFactory;

    private StatementBuilder statementBuilder;

    /**
     * 统计总数
     * 
     * @param c
     * @return
     */
    public int count(Criteria c) {
        return ((Number) c.uniqueResult()).intValue();
    }

    /**
     * 统计总数
     * 
     * @param q
     * @return
     */
    public int count(Query q) {
        return ((Number) q.uniqueResult()).intValue();
    }

    /**
     * 获取当前Session
     * 
     * @return
     */
    public final Session session() {
        return sessionFactory.getCurrentSession();
    }

    /**
     * 根据主键获取持久化的实体对象
     * 
     * @param clazz 持久化实体的类型
     * @param id 数据的主键
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> T get(Class<T> clazz, Serializable id) {
        return (T) session().get(clazz, id);
    }

    /**
     * 保存数据对象
     * 
     * @param obj
     */
    public void save(Object obj) {
        Session ses = session();
        if (obj instanceof Collection<?>) {
            Collection<?> cs = (Collection<?>) obj;
            if (cs != null && cs.size() > 0) {
                for (Object o : cs) {
                    ses.saveOrUpdate(o);
                }
            }
        } else {
            ses.saveOrUpdate(obj);
        }
    }

    /**
     * 删除对象
     * 
     * @param obj
     */
    public void delete(Object obj) {
        session().delete(obj);
    }

    /**
     * 使用主键删除持久化对象
     * 
     * @param clazz 持久化对象类
     * @param id 主键
     */
    public <T> void delete(Class<T> clazz, Serializable id) {
        Session s = session();
        Object o = s.get(clazz, id);
        if (o != null) {
            s.delete(o);
        }
    }

    /**
     * 更新数据
     * 
     * @param obj
     */
    public void update(Object obj) {
        session().update(obj);
    }

    /**
     * 保存或更新数据。主键为null时保存,否则更新
     * 
     * @param obj
     */
    public void saveOrUpdate(Object obj) {
        session().saveOrUpdate(obj);
    }

    /**
     * 使用HQL创建Query对象
     * 
     * @param hql HQL语句
     * @return
     */
    public Query query(String hql) {
        return session().createQuery(hql);
    }

    @SuppressWarnings("unchecked")
    public <T> List<T> query(String hql, String countHql, Paging paging, Map<String, Object> params) {
        List<T> results = Collections.EMPTY_LIST;
        if (paging.isCountable()) {
            Query countQuery = session().createQuery(countHql);
            setParameter(countQuery, params);

            // 统计数据总数
            int total = ((Number) countQuery.uniqueResult()).intValue();
            paging.setTotal(total);

            // 总数比偏移量小,不需要执行查询
            if (total > paging.getOffset()) {
                Query query = session().createQuery(hql);
                setParameter(query, params);
                results = query.setFirstResult(paging.getOffset()).setMaxResults(paging.getPageSize()).list();
            }
        } else {
            Query countQuery = session().createQuery(hql);
            setParameter(countQuery, params);
            results =
                    countQuery.setFirstResult(paging.getOffset()).setMaxResults(paging.getPageSize())
                            .list();
        }

        return results;
    }

    @SuppressWarnings("unchecked")
    public <T> List<T> nativeQuery(String sql, String countSql, Paging paging, Map<String, Object> params) {
        List<T> results = Collections.EMPTY_LIST;
        if (paging.isCountable()) {
            Query countQuery = session().createSQLQuery(countSql);
            setParameter(countQuery, params);

            // 统计数据总数
            int total = ((Number) countQuery.uniqueResult()).intValue();
            paging.setTotal(total);

            // 总数比偏移量小,不需要执行查询
            if (total > paging.getOffset()) {
                Query query = session().createSQLQuery(sql);
                setParameter(query, params);
                results = query.setFirstResult(paging.getOffset()).setMaxResults(paging.getPageSize()).list();
            }
        } else {
            results =
                    session().createSQLQuery(sql).setFirstResult(paging.getOffset())
                            .setMaxResults(paging.getPageSize()).list();
        }

        return results;
    }

    /**
     * 使用SQL创建SQLQuery对象
     * 
     * @param sql SQL语句
     * @return
     */
    public SQLQuery sqlQuery(String sql) {
        return session().createSQLQuery(sql);
    }

    /**
     * 获取命名查询
     * 
     * @param name
     * @return
     */
    public Query namedQuery(String name) {
        return session().getNamedQuery(name);
    }

    /**
     * 获得动态命名HQL查询对象
     * 
     * @param namedQuery 命名HQL的名称
     * @param params 查询参数
     * @return
     */
    public Query dynamicQuery(String namedQuery, Map<String, Object> params) {
        return session().createQuery(statementBuilder.namedHQLQuery(namedQuery, params)).setProperties(params);
    }

    /**
     * 获得动态命名SQL查询对象
     * 
     * @param namedQuery 命名SQL的名称
     * @param params 查询参数
     * @return
     */
    public SQLQuery nativeDynamicQuery(String namedQuery, Map<String, Object> params) {
        SQLQuery query = session().createSQLQuery(statementBuilder.namedSQLQuery(namedQuery, params));
        query.setProperties(params);
        return query;
    }

    /**
     * 创建指定持久化类的Criteria对象
     * 
     * @param clazz 数据实体类
     * @return
     */
    public Criteria criteria(Class<?> clazz) {
        return session().createCriteria(clazz);
    }

    /**
     * 查询所有持久化数据
     * 
     * @param clazz 数据实体类
     * @return 数据列表
     */
    public <T> List<T> select(Class<T> clazz) {
        return selector(clazz, 0).list();
    }

    /**
     * 查询指定数量的持久化数据
     * 
     * @param clazz 数据实体类
     * @param size 查询数量,返回列表中对象数量不超过size
     * @return 数据列表
     */
    public <T> List<T> select(Class<T> clazz, int size) {
        return selector(clazz, size).list();
    }

    /**
     * 创建查询器
     * 
     * @param clazz 要查询的数据实体类
     * @return
     */
    public <T> Selector<T> selector(Class<T> clazz) {
        return new Selector<T>(criteria(clazz), 0, 0);
    }

    /**
     * 创建查询器
     * 
     * @param clazz 要查询的数据实体类
     * @param size 要查询的最大数据条数
     * @return
     */
    public <T> Selector<T> selector(Class<T> clazz, int size) {
        return new Selector<T>(criteria(clazz), 0, size);
    }

    /**
     * 创建分页查询器
     * 
     * @param clazz 要查询的数据实体类
     * @param paging 分页对象
     * @return
     */
    public <T> Selector<T> selector(Class<T> clazz, Paging paging) {
        Criteria finder = criteria(clazz);
        if ((paging.getPageSize() != 0) && paging.isCountable()) {
            return new PagingSelector<T>(criteria(clazz).setProjection(Projections.rowCount()), finder, paging);
        }

        return new Selector<T>(finder, paging.getOffset(), paging.getPageSize());
    }

    /**
     * 获取动态SQL的分页查询对象
     * 
     * @param counterName 统计数量的SQL名称,为null时不统计数量
     * @param finderName 查询数据的SQL名称
     * @param paging 分页对象
     * @param params 查询参数
     * @return
     */
    public NativeDynamicSelector nativeDynamicSelector(String counterName, String finderName, Paging paging,
            Map<String, Object> params) {
        SQLQuery counter = null;
        if (counterName != null) {
            counter = nativeDynamicQuery(counterName, params);
        }

        SQLQuery finder = nativeDynamicQuery(finderName, params);

        return new NativeDynamicSelector(counter, finder, paging);
    }

    /**
     * 获取动态HQL的分页查询对象
     * 
     * @param counterName 统计数量的HQL名称,为null时不统计数量
     * @param finderName 查询数据的HQL名称
     * @param paging 分页对象
     * @param params 查询参数
     * @return
     */
    public DynamicSelector dynamicSelector(String counterName, String finderName, Paging paging,
            Map<String, Object> params) {
        Query counter = null;
        if (counterName != null) {
            counter = dynamicQuery(counterName, params);
        }

        Query finder = dynamicQuery(finderName, params);

        return new DynamicSelector(counter, finder, paging);
    }

    /**
     * 执行单一In查询,多用于查询多个主键对应的数据
     * 
     * @param clazz
     * @param property
     * @param values
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> in(Class<T> clazz, String property, Set<? extends Serializable> values) {
        if (Misc.isEmpty(values)) {
            return Collections.EMPTY_LIST;
        }

        return criteria(clazz).add(Restrictions.in(property, values)).list();
    }

    /**
     * 执行单一In查询和条件查询
     * 
     * @param clazz
     * @param property
     * @param values
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> in(Class<T> clazz, String property, Set<? extends Serializable> values, String otherProperty,
            Object propertyValue) {
        if (Misc.isEmpty(values)) {
            return Collections.EMPTY_LIST;
        }

        return criteria(clazz).add(Restrictions.in(property, values))
                .add(Restrictions.eq(otherProperty, propertyValue)).list();
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @SuppressWarnings("rawtypes")
    private void setParameter(Query query, Map<String, Object> params) {
        if (params != null) {
            Iterator<String> it = params.keySet().iterator();
            while (it.hasNext()) {
                String key = it.next();
                if (params.get(key) instanceof Collection) {
                    query.setParameterList(key, (Collection) params.get(key));
                } else {
                    query.setParameter(key, params.get(key));
                }
            }
        }
    }

    /**
     * 同步数据
     * 
     * @param flush
     */
    public void flush() {
        session().flush();
    }

    public void setStatementBuilder(StatementBuilder statementBuilder) {
        this.statementBuilder = statementBuilder;
    }

}
import httl.Engine;
import httl.Template;

import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.dom4j.Element;
import org.hibernate.internal.util.xml.MappingReader;
import org.hibernate.internal.util.xml.OriginImpl;
import org.hibernate.internal.util.xml.XmlDocument;
import org.springframework.core.io.Resource;
import org.xml.sax.InputSource;

import com.assess.lang.AppException;
import com.assess.lang.util.TextUtil;

public class StatementBuilder {
    private Resource[] locations;
    private Engine engine;
    private ConcurrentHashMap<String, Template> hqlCache = new ConcurrentHashMap<>(32);
    private ConcurrentHashMap<String, Template> sqlCache = new ConcurrentHashMap<>(32);

    public void setLocations(Resource...locations) {
        this.locations = locations;
    }

    public void init() throws Exception {
        engine = Engine.getEngine("httl-hibernate.properties");
        if (locations != null) {
            for (Resource r : locations) {
                parse(r);
            }
        }
    }

    public String namedSQLQuery(String name, Map<String, Object> params) {
        Template tpl = sqlCache.get(name);

        if (tpl == null) {
            throw new IllegalArgumentException("Not found named query: " + name);
        }

        return render(tpl, params);
    }

    public String namedHQLQuery(String name, Map<String, Object> params) {
        Template tpl = hqlCache.get(name);

        if (tpl == null) {
            throw new IllegalArgumentException("Not found named query: " + name);
        }

        return render(tpl, params);
    }

    private String render(Template tpl, Map<String, Object> params) {
        try {
            Writer out = new StringBuilderWriter(128);
            tpl.render(params, out);
            return out.toString();
        } catch (Exception e) {
            throw new AppException(e);
        }
    }

    @SuppressWarnings("unchecked")
    private void parse(Resource resource) throws Exception {
        try (InputStream is = resource.getInputStream()) {
            InputSource source = new InputSource(is);
            OriginImpl o = new OriginImpl("file", resource.getFilename());
            XmlDocument xml = MappingReader.INSTANCE.readMappingDocument(source, o);

            Element statement = xml.getDocumentTree().getRootElement();
            for (Element e : (List<Element>) statement.elements()) {
                final String name = e.getName();

                if ("sql-query".equals(name)) {
                    cacheStatement(resource, e, sqlCache);
                } else if ("query".equals(name)) {
                    cacheStatement(resource, e, hqlCache);
                }
            }
        }
    }

    private void cacheStatement(Resource res, final Element element, Map<String, Template> cache) throws Exception {
        String name = element.attribute("name").getText();
        if (TextUtil.isBlank(name)) {
            throw new Exception("query name is lacked in " + res.getURI());
        }

        String text = element.getText();
        if (TextUtil.isBlank(text)) {
            throw new Exception("query text is lacked in " + res.getURI());
        }

        if (cache.containsKey(name)) {
            throw new Exception("query name " + name + " is duplicated in " + res.getURI());
        }

        Template tpl = engine.parseTemplate(text);
        if (tpl == null) {
            throw new Exception("Cann't parse namedQuery: " + name);
        }

        cache.put(name, tpl);
    }

    private static class StringBuilderWriter extends Writer {
        private final StringBuilder buf;

        public StringBuilderWriter(int capacity) {
            buf = new StringBuilder(capacity);
        }

        @Override
        public void write(String value) {
            if (value != null) {
                buf.append(value);
            }
        }

        @Override
        public void write(char[] value, int offset, int length) throws IOException {
            if (value != null) {
                buf.append(value, offset, length);
            }
        }

        @Override
        public void flush() throws IOException {
        }

        @Override
        public void close() throws IOException {
        }

        @Override
        public Writer append(char value) {
            buf.append(value);
            return this;
        }

        @Override
        public Writer append(CharSequence value) {
            buf.append(value);
            return this;
        }

        @Override
        public Writer append(CharSequence value, int start, int end) {
            buf.append(value, start, end);
            return this;
        }

        @Override
        public String toString() {
            return buf.toString();
        }
    }
}
compiler=httl.spi.compilers.JavassistCompiler
loader=httl.spi.loaders.ClasspathLoader
logger=httl.spi.loggers.Slf4jLogger
logger.level=INFO

codecs=
before.listener=
after.listener=
formatter=httl.spi.formatters.DateFormatter
formatter.switcher=
template.filter=
expression.filter=httl.spi.filters.UnescapeXmlFilter
value.filter=httl.spi.filters.MultiValueFilter
text.filter=httl.spi.filters.MultiTextFilter
script.value.filter=
script.text.filter=
style.value.filter=
style.text.filter=
具体的使用:
<sql-query name="Survey.findCodeByActor">
        <![CDATA[
         SELECT DISTINCT(s.code) as code
         FROM t_survey s, t_actor a, t_user u
         WHERE s.category=2 AND a.user_id=:userId AND s.locale=:locale AND a.state=1
             AND a.assessed_actor_id=u.person_id AND s.code=a.survey_code
             AND (s.state=3 OR s.state=4)
         #if(relationship != -1) AND a.relationship=:relationship #end
         #if(assessedActor != null) AND a.assessed_actor_id=:assessedActor #end
         #if(name != null) AND s.name LIKE :name #end
         #if(state == 2)
             GROUP BY s.code HAVING min(a.answer_status)=2 AND max(a.answer_status)=2 ORDER BY s.end_time ASC
         #else(state != -1)
             GROUP BY s.code HAVING min(a.answer_status)=:state ORDER BY s.end_time ASC
         #else
             GROUP BY s.code ORDER BY min(a.answer_status) ASC, s.end_time ASC
         #end
         ]]>
	</sql-query>

	<query name="Survey.reject">
        <![CDATA[
         SELECT a FROM Actor a, Survey s
         WHERE a.surveyCode=:surveyCode AND a.userId=:userId AND s.locale=:locale AND a.assessedActorId=:peer
             AND a.surveyCode=s.code AND a.relationship=4 AND s.category=2
             AND s.state=3 AND a.state=1 AND a.answerStatus=1
         ]]>
	</query>
public void reject(Map<String, Object> params) {
        Actor actor = (Actor) daoHelper.namedQuery("Survey.reject").setProperties(params).uniqueResult();
        if (actor == null) {
            throw new AppException("survey.reject.notFound");
        }

        // 拒绝答题
        actor.setAnswerStatus(Constants.ANSWER_STATUS_REFUSED);
    }

public List<Object[]> findByActor(Paging paging, Map<String, Object> params) {
        List<Long> codes =
                daoHelper.nativeDynamicQuery("Survey.findCodeByActor", params)
                        .addScalar("code", StandardBasicTypes.LONG).list();

        paging.setTotal(codes.size());

        int offset = paging.getOffset();
        if (codes.size() <= offset) {
            return Collections.EMPTY_LIST;
        }

        int end = Math.min(codes.size(), offset + paging.getPageSize());
        params.put("codes", codes.subList(offset, end));

        return daoHelper.namedQuery("Actor.findForSurvey").setProperties(params).list();
    }
	<bean id="statementBuilder" class="com.assess.lang.hibernate.StatementBuilder" init-method="init">
        <property name="locations" value="classpath:hibernate/dynamic-queries-*.xml" />
    </bean>

    <bean id="daoHelper" class="com.assess.lang.hibernate.DaoHelper">
        <property name="sessionFactory" ref="sessionFactory" />
        <property name="statementBuilder" ref="statementBuilder" />
    </bean>

猜你喜欢

转载自mxdxm.iteye.com/blog/2248019