`

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>

 

分享到:
评论

相关推荐

    JPA(hibernate) Dao 和 DaoSupport

    继承自`DaoSupport`的DAO类可以利用其提供的便利方法,如`getJdbcTemplate()`或`getHibernateTemplate()`,来简化数据库操作。不过,现在更推荐使用Spring Data JPA,它提供了更高级别的抽象,减少了手动编写DAO层...

    Hibernate泛型Dao

    【内容】在使用Hibernate泛型Dao时,首先需要定义一个基类,比如`AbstractGenericDao&lt;T&gt;`,其中T代表泛型类型,对应你要操作的实体类。这个基类会包含一些通用的CRUD(Create, Read, Update, Delete)方法,如`save...

    hibernate4 通用dao,service

    通用DAO通常包含对增删改查(CRUD)操作的抽象方法,如save()、delete()、update()和getById()等,可以适用于多个不同的数据实体类。而Service层则在此基础上进行业务逻辑处理,调用DAO方法来执行数据库操作,并可能...

    使用模式设计及java5新特性在HibernateDAO中的应用

    标题 "使用模式设计及java5新特性在HibernateDAO中的应用" 涉及到的是软件开发中的几个关键概念,包括模式设计、Java 5的新特性以及它们如何在Hibernate DAO层中得到应用。在这个主题中,我们将深入探讨这些知识点,...

    hibernate eclipse插件生成dao样例

    5. 生成DAO:在配置好实体类和映射文件后,插件可以生成基础的DAO接口和实现类,这些类包含了基本的CRUD(创建、读取、更新、删除)方法。 6. 调试和优化:最后,开发者可以使用生成的DAO样例进行实际操作,根据需要...

    hibernate不是泛型的通用DAo1

    例如,`DynamicDao`可能是一个非泛型接口,它包含了一些基本的CRUD操作,可以直接被任何类实现,而不需要指定特定的实体类型。`DynamicDaoImpl`可能是实现了`DynamicDao`接口的具体类,它包含了与Hibernate集成的...

    Hibernate泛型DAO接口,大部分通用都已包括

    再来看`DaoUtil.java`,这通常是一个工具类,用来辅助生成`SessionFactory`,并提供其他DAO操作的静态方法。例如: ```java public class DaoUtil { private static SessionFactory sessionFactory; static { ...

    DAO设计模式辅助资料

    DAO设计模式的基本思想是为数据库操作创建一个独立的接口,这个接口称为DAO接口。通过这个接口,业务层可以调用各种数据访问方法,而无需直接与数据库交互。这样做的好处在于,一旦数据库发生变化,如表结构、查询...

    Hibernate SQLQuery 本地查询

    在许多企业级应用中,为了提高代码的复用性和可维护性,通常会创建一个基础DAO(Data Access Object)类,提供通用的CRUD操作。BaseDaoSupport可能是这样的一个类,它包含了基本的增删改查方法,并且可能会集成对SQL...

    JAVA Dao 数据库操作

    Java DAO(Data Access Object)模式是Java编程中用于数据库操作的一种设计模式,它提供了一种在业务逻辑和数据库之间解耦的方式。DAO类是专门用来与数据库进行交互的,负责执行SQL语句,处理结果集,以及进行事务...

    springboot2.0多数据源集成hibernate配置hibernateDaoSupport示例

    `HibernateDaoSupport`是Spring提供的一类辅助类,它提供了与Hibernate SessionFactory的连接,简化了Hibernate的使用。首先,我们需要创建一个基础的DAO接口,然后创建其实现类并继承`HibernateDaoSupport`。例如:...

    hibernate的第一个例子

    3. **辅助类(Helper Classes)**:这可能是配置类,如HibernateUtil,负责创建SessionFactory,或者工具类,如DAO(Data Access Object),封装了对数据库的基本操作。这些类通常包含初始化Hibernate配置、打开/...

    生成hibernate配置文件和xml的辅助类generate

    《使用Hibernate配置文件和XML辅助类Generate的深度解析》 在Java开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。然而,手动配置Hibernate的相关文件,如实体类、映射文件(....

    dao包封装包

    而对应的`UserDAOImpl`实现类则会提供这些方法的具体实现,通常使用JDBC(Java Database Connectivity)或者ORM(Object-Relational Mapping)框架如Hibernate、MyBatis来执行SQL语句。例如,使用JDBC实现`...

    HibernateTools-3.2.4

    HibernateTools是Java开发人员在使用Hibernate ORM框架时的有力辅助工具集,主要目的是为了提高开发效率,简化数据库操作。在HibernateTools 3.2.4版本中,它包含了一系列的特性与插件,以支持更便捷地进行对象关系...

    一个的DAO数据访问层的实现

    首先,DAO模式的基本思想是创建一个专门负责与数据库进行交互的接口或类,即DAO接口或DAO实现类。这个接口定义了对数据库进行CRUD(Create、Read、Update、Delete)操作的方法。例如,对于一个用户表,可能会有如下...

    不要重复 DAO !

    首先,我们需要理解DAO的基本概念。DAO是一组接口和实现,用于处理与数据库的交互,包括CRUD(创建、读取、更新和删除)操作。每个DAO通常对应数据库中的一个表或实体。例如,一个`UserDAO`可能包含获取用户、保存...

    Don’t repeat the DAO!

    “工具”可能暗示博主提到了一些辅助工具或者库,用于简化DAO的开发工作,比如Hibernate、MyBatis等。 由于没有具体的博客内容,以下是对DAO模式的一般性解释和相关知识点: 1. **DAO模式概念**:DAO模式是一种...

    java 实体类和Dao层代码生成器

    DAO类通常包含了对数据库的基本操作,如增(insert)、删(delete)、改(update)和查(select)。在Java中,DAO接口和其实现类是常见的做法,接口定义了操作,而实现类则包含了具体的SQL执行逻辑。 3. **代码生成...

    webservice提供数据访问spring+hibernate

    【标题】"Web服务提供数据访问:Spring+Hibernate整合应用" 在现代软件开发中,Web服务已经成为企业级应用间通信的重要手段。通过Web服务,不同的系统可以共享数据和功能,实现松耦合。本主题主要探讨如何利用...

Global site tag (gtag.js) - Google Analytics