`

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>

 

分享到:
评论

相关推荐

    Hibernate实战(第2版 中文高清版)

    第一部分 从Hibernate和EJB 3.0开始  第1章 理解对象/关系持久化   1.1 什么是持久化   1.1.1 关系数据库   1.1.2 理解SQL   1.1.3 在Java中使用SQL   1.1.4 面向对象应用程序中的持久化   1.2 范式不...

    howsun-javaee-framework:这是一款特别适用于中小企业应用的JavaEE快速开发框架。它是居于Spring容器之上,封装了DAO(含Hibernate和MongoDB)操作、多模块统一管理、统一配置管理、统一日志管理等优雅的工程管理开发模型,并提供大量工具包、Json操作、分页辅助工具

    howsun-javaee-framework Java应用层框架 版本:1.0.8   1、项目介绍 这是一款居于Spring容器之上特别适用于中小企业应用的...7、提供了分页、工具类封装的JSP标签库 8、大量工具包:如安全、Web、断言、编码等40多

    spring jar 包详解

    (2) spring-beans.jar 这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI支持,...

    最新最全的spring开发包

    这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI支持,引入spring-core.jar及...

    基本于J2EE的Ajax宝典.rar

    18.3.2 使用 AjaxXmlBuilder 辅助类 62 18.3.3 使用 BaseAjaxAction 生成响应 66 18.3.4 使用 BaseAjaxServlet 生成响应 68 18.3.5 使用非 Java响应 70 18.4 AjaxTags 常用标签的使用 71 18.4.1 使用自动完成...

    JAVA程序开发大全---上半部分

    13.4.2 反向工程生成JPA 实体类和Spring DAO类 242 13.4.3 创建测试类 243 13.5 本章小结 243 第14章 Web Service的开发及应用 244 14.1 Web Service概述 244 14.2 使用MyEclipse创建Web Service项目 245 14.2.1 ...

    Spring 2.5 jar 所有开发包及完整文档及项目开发实例

    这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI支持,引入spring-core.jar及...

    spring4.3.9相关jar包

    spring-web.jar(必须) :这个jar 文件包含Web 应用开发时,用到Spring 框架时所需的核心类,包括自动载入Web Application Context 特性的类、Struts 与JSF 集成类、文件上传的支持类、Filter 类和大量工具辅助类。...

    Spring面试题

    5.容器提供了众多的辅助类,能加快应用的开发 6.spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等 7.spring属于低侵入式设计,代码的污染极低 8.独立于各种应用服务器 9.spring的DI机制降低...

    j2ee 架构设计 (SSH典型结构解析)

    j2ee 架构设计 第一部份:介绍实例架构 结合实例讲解Web项目总体结构 ...第五部分:介绍数据持久层利器(HIbernate) 快速入门 介绍辅助工具 表与表之间关联操作 多数据库操作 事务管理 DAO模式 与Spring结合使用

    J2EE架构设计PPT

    第五部分:介绍数据持久层利器(HIbernate) 快速入门 介绍辅助工具 表与表之间关联操作 多数据库操作 事务管理 DAO模式 与Spring结合使用 第六部分:介绍软件测试与部署 借助Junit的单元测试 借助Ant的自动部署

    java代码自动生成器(根据数据库生成数据库操作代码)

    是一个以spring为核心的项目脚手架(或者称为胶水框架),框架将各个零散的框架(struts,strust2,springmvc,hibernate,ibatis,spring_jdbc,flex)搭建好,并内置一个代码生成器,辅助项目开发,可以生成java的hibernat ...

    Spring中文帮助文档

    11.2. 利用JDBC核心类控制JDBC的基本操作和错误处理 11.2.1. JdbcTemplate类 11.2.2. NamedParameterJdbcTemplate类 11.2.3. SimpleJdbcTemplate类 11.2.4. DataSource接口 11.2.5. SQLExceptionTranslator接口...

    Spring API

    11.2. 利用JDBC核心类控制JDBC的基本操作和错误处理 11.2.1. JdbcTemplate类 11.2.2. NamedParameterJdbcTemplate类 11.2.3. SimpleJdbcTemplate类 11.2.4. DataSource接口 11.2.5. SQLExceptionTranslator接口...

    Spring 2.0 开发参考手册

    18.3. 使用Spring提供的辅助类实现EJB组件 19. JMS 19.1. 简介 19.2. 使用Spring JMS 19.2.1. JmsTemplate 19.2.2. 连接工厂 19.2.3. (消息)目的地管理 19.2.4. 消息侦听容器 19.2.5. 事务管理 19.3. 发送...

    jdbc封装(实现对实体的增删改查[分页]).zip

    jdbc封装(实现对实体的增删改查[分页]),辅助学习Hibernate 包含三个文件夹,分别是: code-access实现 是用access实现的,本意是access方便,就一个文件,方便部署。但access有好多不支持,就写成这样.主要是可参考Dao...

    spring chm文档

    Spring Framework 开发参考手册 Rod Johnson Juergen Hoeller Alef Arendsen Colin Sampaleanu Rob Harrop ...18.3. 使用Spring提供的辅助类实现EJB组件 19. JMS 19.1. 简介 19.2. 使用Spring JMS ...

    这是一款特别适用于中小企业应用的JavaEE快速开发框架.zip

    它是居于Spring容器之上,封装了DAO(含Hibernate和MongoDB)操作、多模块统一管理、统一配置管理、统一日志管理等优雅的工程管理开发模型,并提供大量工具包、Json操作、分页辅助工具。 开发工具在软件开发生命...

    Spring-Reference_zh_CN(Spring中文参考手册)

    11.2. 利用JDBC核心类实现JDBC的基本操作和错误处理 11.2.1. JdbcTemplate类 11.2.2. NamedParameterJdbcTemplate类 11.2.3. SimpleJdbcTemplate类 11.2.4. DataSource接口 11.2.5. SQLExceptionTranslator接口 ...

    dexcoder-assistant:dexcoder 快速开发工具包

    如果你不喜欢用Hibernate、Mybaits这类ORM框架,喜欢Spring JdbcTemplate或DbUtils,那么可以试试这个封装的通用dal,这可能是目前封装的最方便易用的通用dal层了。 最近更新: 版本 2.3.5 更新时间:2016-06-08 重构...

Global site tag (gtag.js) - Google Analytics