封装JPA的数据操作DAO类

对JPA的实体操作进行了简单的封装,降低了数据操作的难度,提高了开发的效率。里面可能会有少许hibernate的元素。

DAO.java

/************************* 版权声明 *********************************
 * 
 * 版权所有:百洋软件
 * Copyright (c) 2009 by Pearl Ocean.
 * 
 ************************* 变更记录 *********************************
 *
 * 创建者:yongtree   创建日期: 2009-4-30
 * 创建记录:创建类结构。
 * 
 * 修改者:宋黎晓       修改日期:2010-1-12
 * 修改记录:修改接口定义中的泛型T ,将其从接口定义挪到每个方法的声明.
 * 
 ************************* 随   笔 *********************************
 *
 * 这里可以写写感想,感慨,疑问什么的。
 * 
 ******************************************************************
 */

package com.posoftframework.dao;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;

import com.posoftframework.entity.base.BaseEO;

/**
 * 底层数据操作的工具类
 * 
 * @author yongtree
 * @date 2009-4-30 上午08:55:32
 * @version 2.0
 * @since 2.0 泛型T挪到方法声明出,声明对象时不需要指定泛型.
 */
public interface DAO {

    /**
     * 清除一级缓存的数据
     */
    public void clear();

    /**
     * 新增实体
     * 
     * @param entity
     *            实体
     */
    public <T extends BaseEO> void create(T entity);

    /**
     * 批量新增实体
     * 
     * @param entitys
     *            实体列表
     */
    public <T extends BaseEO> void createBatch(List<T> entitys);

    /**
     * 更新实体
     * 
     * @param entity
     *            实体
     */
    public <T extends BaseEO> void update(T entity);

    /**
     * 删除实体
     * 
     * @param entityClass
     *            实体类
     * @param entityid
     *            实体id
     */
    public <T extends BaseEO> void delete(Class<T> entityClass, Object entityid);

    /**
     * 删除实体
     * 
     * @param entityClass
     *            实体类
     * @param entityids
     *            实体id数组
     */
    public <T extends BaseEO> void delete(Class<T> entityClass,
            Object[] entityids);

    /**
     * 根据条件删除
     * 
     * @author slx
     * @date 2009-11-24 下午05:52:04
     * @modifyNote
     * @param entityClass
     * @param where
     * @param delParams
     */
    public <T extends BaseEO> void deleteByWhere(Class<T> entityClass,
            String where, Object[] delParams);

    /**
     * 获取实体
     * 
     * @param <T>
     * @param entityClass
     *            实体类
     * @param entityId
     *            实体id
     * @return
     */
    public <T extends BaseEO> T find(Class<T> entityClass, Object entityId);

    /**
     * 根据where条件查询单个对象
     * @author slx
     * @date 2010-7-19 上午10:33:20
     * @modifyNote
     * @param <T>
     * @param entityClass
     *          类型
     * @param where
     *          条件
     * @param params
     *          参数
     * @return
     */
    public <T extends BaseEO> T findByWhere(Class<T> entityClass, String where ,Object[] params);

    /**
     * 获取实体,具有延迟加载的作用(和find相比)
     * 
     * @param <T>
     * @param entityClass
     *            实体类
     * @param entityId
     *            实体id
     * @return
     */
    public <T extends BaseEO> T load(Class<T> entityClass, Object entityId);

    /**
     * 根据条件判断实体是否存在
     * 
     * @author slx
     * @date 2009-7-8 上午11:49:13
     * @modifyNote
     * @param entityClass
     *            实体类
     * @param whereql
     *            查询条件(可空,可为 field1=? and field2=? 形式,也可为field1='value1' and
     *            field2='value2'的形式)
     * @param queryParams
     *            参数(可空,但是当条件使用了field1=? and field2=? 的形式后参数不能为空)
     * @return 是否存在
     */
    public <T extends BaseEO> boolean isExistedByWhere(Class<T> entityClass,
            String whereql, Object[] queryParams);

    /**
     * 获取记录总数
     * 
     * @param entityClass
     *            实体类
     * @return
     */
    public <T extends BaseEO> long getCount(Class<T> entityClass);

    /**
     * 根据条件和参数获取记录总数
     * 
     * @author slx
     * @date 2009-7-8 上午11:34:41
     * @modifyNote
     * @param <T>
     * @param entityClass
     *            实体类
     * @param whereql
     *            查询条件(可空,可为 field1=? and field2=? 形式,也可为field1='value1' and
     *            field2='value2'的形式)
     * @param queryParams
     *            参数(可空,但是当条件使用了field1=? and field2=? 的形式后参数不能为空)
     * @return 记录行数
     */
    public <T extends BaseEO> long getCountByWhere(Class<T> entityClass,
            String whereql, Object[] queryParams);

    /**
     * 获取分页数据
     * 
     * @param <T>
     * @param entityClass
     *            实体类
     * @param firstindex
     *            开始索引
     * @param maxresult
     *            需要获取的记录数
     * @return
     */
    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, int firstindex, int maxresult,
            String wherejpql, Object[] queryParams,
            LinkedHashMap<String, String> orderby);

    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, int firstindex, int maxresult,
            String wherejpql, List<Object> queryParams,
            LinkedHashMap<String, String> orderby);

    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, int firstindex, int maxresult,
            String wherejpql, Map<String, Object> queryParams,
            LinkedHashMap<String, String> orderby);

    /**
     * 查询实体部分字段,获取分页数据
     * 
     * 返回的结果将重新组装到实体属性中,没有查询的字段为NULL<br>
     * 注意:使用该接口时,要确保实体类中有对应的查询字段的有参数构造方法,并且参数的顺序要和此处的queryfields数组的元素一致
     * 
     * @author yongtree
     * @date 2010-4-13 下午12:56:03
     * @modifyNote
     * @param <T>
     * @param entityClass
     * @param queryfields
     * @param firstindex
     * @param maxresult
     * @param wherejpql
     * @param queryParams
     * @param orderby
     * @return
     */
    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, String[] queryfields, int firstindex,
            int maxresult, String wherejpql, Object[] queryParams,
            LinkedHashMap<String, String> orderby);

    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, String[] queryfields, int firstindex,
            int maxresult, String wherejpql, List<Object> queryParams,
            LinkedHashMap<String, String> orderby);

    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, String[] queryfields, int firstindex,
            int maxresult, String wherejpql, Map<String, Object> queryParams,
            LinkedHashMap<String, String> orderby);

    /**
     * 根据条件查询实体中的指定几个字段 <br>
     * 返回结果List<String[]>格式如下: <br>
     * 行1: 字段1value , 字段2value , 字段3value <br>
     * 行2: 字段1value , 字段2value , 字段3value
     * 
     * @author slx
     * @date 2009-5-14 下午01:14:23
     * @modifyNote
     * @param <T>
     * @param entityClass
     * @param queryfields
     * @param wheresql
     * @param queryParams
     * @return
     */
    public <T extends BaseEO> List<Object[]> queryFieldValues(
            Class<T> entityClass, String[] queryfields, String wheresql,
            Object[] queryParams);

    public <T extends BaseEO> List<Object[]> queryFieldValues(
            Class<T> entityClass, String[] queryfields, String wheresql,
            Object[] queryParams, int startRow, int rows);

    /**
     * 根据条件查询实体中的指定几个字段 <br>
     * 返回的结果将重新组装到实体属性中,没有查询的字段为NULL<br>
     * 注意:使用该接口时,要确保实体类中有对应的查询字段的有参数构造方法,并且参数的顺序要和此处的queryfields数组的元素一致
     * 
     * @author yongtree
     * @date 2010-4-13 上午11:45:27
     * @modifyNote
     * @param <T>
     * @param entityClass
     * @param queryfields
     * @param wheresql
     * @param queryParams
     * @return
     */
    public <T extends BaseEO> List<T> queryByWhere(Class<T> entityClass,
            String[] queryfields, String wheresql, Object[] queryParams);

    public <T extends BaseEO> List<T> queryByWhere(Class<T> entityClass,
            String[] queryfields, String wheresql, Object[] queryParams,
            int startRow, int rows);

    /**
     * 根据where条件查询实体bean列表 <br>
     * where和queryParams可空
     * 
     * @author slx
     * @date 2009-5-14 下午01:20:19
     * @modifyNote
     * @param <T>
     * @param entityClass
     * @param wheresql
     * @param queryParams
     * @return
     */
    public <T extends BaseEO> List<T> queryByWhere(Class<T> entityClass,
            String wheresql, Object[] queryParams);

    /**
     * 根据where条件查询实体bean列表,可指定取第几行到第几行 <br>
     * where和queryParams可空
     * 
     * @author slx
     * @date 2009-5-14 下午01:20:19
     * @modifyNote
     * @param <T>
     * @param entityClass
     * @param wheresql
     * @param queryParams
     * @param startRow
     *            开始行
     * @param rows
     *            共多少行
     * @return
     */
    public <T extends BaseEO> List<T> queryByWhere(Class<T> entityClass,
            String wheresql, Object[] queryParams, int startRow, int rows);

    /**
     * 得到EM,不建议经常使用,以免使用过于随意造成系统的维护难度加大和扩展性变差
     * 
     * @author yongtree
     * @date 2009-11-5 上午11:32:49
     * @modifyNote
     * @return
     */
    public EntityManager getEntityManager();
}

BaseJpaDao.java

/************************* 版权声明 *********************************
 * 
 * 版权所有:百洋软件
 * Copyright (c) 2009 by Pearl Ocean.
 * 
 ************************* 变更记录 *********************************
 *
 * 创建者:yongtree   创建日期: 2009-5-31
 * 创建记录:创建类结构。
 * 
 * 修改者:宋黎晓       修改日期:2010-1-12
 * 修改记录:修改了DAO接口,同时修改了此实现类.
 ************************* 随   笔 *********************************
 *
 * 这里可以写写感想,感慨,疑问什么的。
 * 
 ******************************************************************
 */

package com.posoftframework.dao;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.commons.lang.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import com.posoftframework.entity.base.BaseEO;

/**
 * 封装常用增删改查操作
 * 
 * @author yongtree
 * @date 2009-5-31 上午11:09:01
 * @version 2.0
 * @since 2.0 泛型T挪到方法声明出,声明对象时不需要指定泛型.
 */
@SuppressWarnings("unchecked")
public abstract class BaseJpaDao implements DAO {

    private QLBuilder sqlBuilder = new QLBuilder();

    public void clear() {
        getEntityManager().clear();
    }

    @Transactional
    public <T extends BaseEO> void create(T entity) {
        getEntityManager().persist(entity);
    }

    public <T extends BaseEO> void createBatch(List<T> entitys) {
        for (T entity : entitys) {
            create(entity);
        }
    }

    @Transactional
    public <T extends BaseEO> void update(T entity) {
        getEntityManager().merge(entity);
    }

    @Transactional
    public <T extends BaseEO> void saveAll(List<T> entitys) {
        for (int i = 0; i < entitys.size(); i++) {
            T entity = entitys.get(i);
            save(entity);
        }
    }

    @Transactional
    public <T extends BaseEO> void save(T entity) {
        if (entity.getPrimaryKey() == null) {
            this.create(entity);
        } else {
            this.update(entity);
        }
    }

    @Transactional
    public <T extends BaseEO> void delete(Class<T> entityClass, Object entityid) {
        delete(entityClass, new Object[] { entityid });
    }

    @Transactional
    public <T extends BaseEO> void delete(Class<T> entityClass,
            Object[] entityids) {
        // StringBuffer sf_QL = new StringBuffer(" DELETE FROM ").append(
        // sqlBuilder.getEntityName(entityClass)).append(" o WHERE ")
        // .append(sqlBuilder.getPkField(entityClass, "o")).append("=? ");
        // Query query = getEntityManager().createQuery(sf_QL.toString());
        for (Object id : entityids) {
            getEntityManager().remove(getEntityManager().find(entityClass, id));
            // query.setParameter(1, id).executeUpdate();
        }
    }

    @Transactional
    public <T extends BaseEO> void deleteByWhere(Class<T> entityClass,
            String where, Object[] delParams) {
        StringBuffer sf_QL = new StringBuffer("DELETE FROM ").append(
                sqlBuilder.getEntityName(entityClass)).append(" o WHERE 1=1 ");
        if (where != null && where.length() != 0) {
            sf_QL.append(" AND ").append(where);
        }
        Query query = getEntityManager().createQuery(sf_QL.toString());
        this.setQueryParams(query, delParams);

        query.executeUpdate();
    }

    public <T extends BaseEO> T find(Class<T> entityClass, Object entityId) {
        return getEntityManager().find(entityClass, entityId);
    }

    public <T extends BaseEO> long getCount(Class<T> entityClass) {
        return getCountByWhere(entityClass, null, null);
    }

    public <T extends BaseEO> long getCountByWhere(Class<T> entityClass,
            String whereql, Object[] queryParams) {
        StringBuffer sf_QL = new StringBuffer("SELECT COUNT(").append(
                sqlBuilder.getPkField(entityClass, "o")).append(") FROM ")
                .append(sqlBuilder.getEntityName(entityClass)).append(
                        " o WHERE 1=1 ");
        if (whereql != null && whereql.length() != 0) {
            sf_QL.append(" AND ").append(whereql);
        }
        Query query = getEntityManager().createQuery(sf_QL.toString());
        this.setQueryParams(query, queryParams);
        return (Long) query.getSingleResult();
    }

    public <T extends BaseEO> boolean isExistedByWhere(Class<T> entityClass,
            String whereql, Object[] queryParams) {
        long count = getCountByWhere(entityClass, whereql, queryParams);
        return count > 0 ? true : false;
    }

    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, int firstindex, int maxresult,
            String wherejpql, Object[] queryParams,
            LinkedHashMap<String, String> orderby) {
        return scroll(entityClass, firstindex, maxresult, wherejpql,
                queryParams, orderby);
    }

    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, int firstindex, int maxresult,
            String wherejpql, List<Object> queryParams,
            LinkedHashMap<String, String> orderby) {
        Object[] ps = null;
        if (queryParams != null) {
            ps = queryParams.toArray();
        }
        return getScrollData(entityClass, firstindex, maxresult, wherejpql, ps,
                orderby);
    }

    @Override
    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, int firstindex, int maxresult,
            String wherejpql, Map<String, Object> queryParams,
            LinkedHashMap<String, String> orderby) {
        return scroll(entityClass, firstindex, maxresult, wherejpql,
                queryParams, orderby);
    }

    /**
     * 根据条件查询某个实体的列表
     * 
     * @author slx
     * @param <T>
     * @param entityClass
     *            实体类型
     * @param firstindex
     *            开始行
     * @param maxresult
     *            结束行
     * @param wherejpql
     *            where条件
     * @param queryParams
     *            参数
     * @param orderby
     *            排序条件
     * @return
     */
    private <T extends BaseEO> QueryResult<T> scroll(Class<T> entityClass,
            int firstindex, int maxresult, String wherejpql,
            Object queryParams, LinkedHashMap<String, String> orderby) {
        QueryResult<T> qr = new QueryResult<T>();
        String entityname = sqlBuilder.getEntityName(entityClass);
        Query query = getEntityManager()
                .createQuery(
                        "SELECT o FROM "
                                + entityname
                                + " o "
                                + (StringUtils.isEmpty(wherejpql) ? ""
                                        : "WHERE " + wherejpql)
                                + sqlBuilder.buildOrderby(orderby));
        setQueryParams(query, queryParams);
        if (firstindex != -1 && maxresult != -1)
            query.setFirstResult(firstindex).setMaxResults(maxresult).setHint(
                    "org.hibernate.cacheable", true);
        qr.setResultlist(query.getResultList());
        query = getEntityManager().createQuery(
                "SELECT COUNT("
                        + sqlBuilder.getPkField(entityClass, "o")
                        + ") FROM "
                        + entityname
                        + " o "
                        + (StringUtils.isEmpty(wherejpql) ? "" : "WHERE "
                                + wherejpql));
        setQueryParams(query, queryParams);
        qr.setTotalrecord((Long) query.getSingleResult());
        return qr;
    }

    /**
     * 根据条件查询实体指定字段的值并回填到实体内. <br/>
     * <b>注意:</b> <br/>
     * 实体必须有包括要查询的字段为参数的构造函数.
     * 
     * @param <T>
     * @param entityClass
     * @param queryfields
     * @param firstindex
     * @param maxresult
     * @param wherejpql
     * @param queryParams
     * @param orderby
     * @return
     */
    private <T extends BaseEO> QueryResult<T> scroll(Class<T> entityClass,
            String[] queryfields, int firstindex, int maxresult,
            String wherejpql, Object queryParams,
            LinkedHashMap<String, String> orderby) {
        QueryResult<T> qr = new QueryResult<T>();
        String entityname = sqlBuilder.getEntityName(entityClass);
        Query query = getEntityManager()
                .createQuery(
                        (sqlBuilder.buildSelect(entityname, queryfields, "o")
                                + "FROM "
                                + entityname
                                + " o "
                                + (StringUtils.isEmpty(wherejpql) ? ""
                                        : "WHERE " + wherejpql) + sqlBuilder
                                .buildOrderby(orderby)));
        setQueryParams(query, queryParams);
        if (firstindex != -1 && maxresult != -1)
            query.setFirstResult(firstindex).setMaxResults(maxresult).setHint(
                    "org.hibernate.cacheable", true);
        qr.setResultlist(query.getResultList());
        query = getEntityManager().createQuery(
                "SELECT COUNT("
                        + sqlBuilder.getPkField(entityClass, "o")
                        + ") FROM "
                        + entityname
                        + " o "
                        + (StringUtils.isEmpty(wherejpql) ? "" : "WHERE "
                                + wherejpql));
        setQueryParams(query, queryParams);
        qr.setTotalrecord((Long) query.getSingleResult());
        return qr;
    }

    @Override
    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, String[] queryfields, int firstindex,
            int maxresult, String wherejpql, List<Object> queryParams,
            LinkedHashMap<String, String> orderby) {
        return this.scroll(entityClass, queryfields, firstindex, maxresult,
                wherejpql, queryParams, orderby);
    }

    @Override
    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, String[] queryfields, int firstindex,
            int maxresult, String wherejpql, Map<String, Object> queryParams,
            LinkedHashMap<String, String> orderby) {
        return this.scroll(entityClass, queryfields, firstindex, maxresult,
                wherejpql, queryParams, orderby);
    }

    @Override
    public <T extends BaseEO> QueryResult<T> getScrollData(
            Class<T> entityClass, String[] queryfields, int firstindex,
            int maxresult, String wherejpql, Object[] queryParams,
            LinkedHashMap<String, String> orderby) {
        return this.scroll(entityClass, queryfields, firstindex, maxresult,
                wherejpql, queryParams, orderby);
    }

    protected void setQueryParams(Query query, Object queryParams) {
        sqlBuilder.setQueryParams(query, queryParams);
    }

    public <T extends BaseEO> List<T> queryByWhere(Class<T> entityClass,
            String wheresql, Object[] queryParams) {
        String entityname = sqlBuilder.getEntityName(entityClass);
        Query query = getEntityManager().createQuery(
                "SELECT o FROM "
                        + entityname
                        + " o "
                        + ((wheresql == null || wheresql.length() == 0) ? ""
                                : "WHERE " + wheresql));
        setQueryParams(query, queryParams);
        query.setHint("org.hibernate.cacheable", true);
        return query.getResultList();
    }

    public <T extends BaseEO> List<T> queryByWhere(Class<T> entityClass,
            String wheresql, Object[] queryParams, int startRow, int rows) {
        String entityname = sqlBuilder.getEntityName(entityClass);
        Query query = getEntityManager().createQuery(
                "SELECT o FROM "
                        + entityname
                        + " o "
                        + ((wheresql == null || wheresql.length() == 0) ? ""
                                : "WHERE " + wheresql));
        setQueryParams(query, queryParams);
        if (startRow >= 0) {
            query.setFirstResult(startRow);
        }
        if (rows > 0) {
            query.setMaxResults(rows);
        }
        query.setHint("org.hibernate.cacheable", true);
        return query.getResultList();
    }

    @Override
    public <T extends BaseEO> List<T> queryByWhere(Class<T> entityClass,
            String[] queryfields, String wheresql, Object[] queryParams) {
        return queryByWhere(entityClass, queryfields, wheresql, queryParams,
                -1, -1);
    }

    @Override
    public <T extends BaseEO> List<T> queryByWhere(Class<T> entityClass,
            String[] queryfields, String wheresql, Object[] queryParams,
            int startRow, int rows) {
        String entityname = sqlBuilder.getEntityName(entityClass);
        Query query = getEntityManager().createQuery(
                sqlBuilder.buildSelect(entityname, queryfields, "o") + " FROM "
                        + entityname + " o "
                        + (wheresql == null ? "" : "WHERE " + wheresql));
        setQueryParams(query, queryParams);
        if (startRow >= 0) {
            query.setFirstResult(startRow);
        }
        if (rows > 0) {
            query.setMaxResults(rows);
        }
        return query.getResultList();
    }

    public <T extends BaseEO> List<Object[]> queryFieldValues(
            Class<T> entityClass, String[] queryfields, String wheresql,
            Object[] queryParams) {
        return queryFieldValues(entityClass, queryfields, wheresql,
                queryParams, -1, -1);
    }

    @Override
    public <T extends BaseEO> List<Object[]> queryFieldValues(
            Class<T> entityClass, String[] queryfields, String wheresql,
            Object[] queryParams, int startRow, int rows) {
        String entityname = sqlBuilder.getEntityName(entityClass);
        Query query = getEntityManager().createQuery(
                sqlBuilder.buildSelect(queryfields, "o") + " FROM "
                        + entityname + " o "
                        + (wheresql == null ? "" : "WHERE " + wheresql));
        setQueryParams(query, queryParams);
        if (startRow >= 0) {
            query.setFirstResult(startRow);
        }
        if (rows > 0) {
            query.setMaxResults(rows);
        }
        return query.getResultList();
    }

    /**
     * 设置查询参数
     * 
     * @author slx
     * @date 2009-7-8 上午10:02:55
     * @modifyNote
     * @param query
     *            查询
     * @param queryParams
     *            查询参数
     */
    protected void setQueryParams(Query query, Object[] queryParams) {
        sqlBuilder.setQueryParams(query, queryParams);
    }

    /**
     * 返回实体管理器
     * 
     * @desc 由slx在2010-6-8下午04:06:55重写父类方法
     */
    public abstract EntityManager getEntityManager();

    @Override
    public <T extends BaseEO> T load(Class<T> entityClass, Object entityId) {
        try {
            return getEntityManager().getReference(entityClass, entityId);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public <T extends BaseEO> T findByWhere(Class<T> entityClass, String where,
            Object[] params) {
         List<T> l = queryByWhere(entityClass, where, params);
         if(l != null && l.size() == 1){
             return l.get(0);
         }else if(l.size() > 1){
             throw new RuntimeException("查寻到的结果不止一个.");
         }else{
             return null;
         }
    }

}

QLBuilder.java

/************************* 版权声明 *********************************
 * 
 * 版权所有:百洋软件
 * Copyright (c) 2009 by Pearl Ocean.
 * 
 ************************* 变更记录 *********************************
 *
 * 创建者:slx   创建日期: 2009-7-8
 * 创建记录:创建类结构。
 * 
 * 修改者:       修改日期:
 * 修改记录:
 ************************* 随   笔 *********************************
 *
 * 这里可以写写感想,感慨,疑问什么的。
 * 
 ******************************************************************
 */    

package com.posoftframework.dao;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Query;

/**
 * SQL语句构建工具类
 * @author slx
 * @date 2009-7-8 上午10:35:28
 * @version 1.0
 */
public class QLBuilder {

    /**
     * 获取实体的名称
     * 
     * @param <T>
     * @param entityClass
     *            实体类
     * @return
     */
    public <T> String getEntityName(Class<T> entityClass) {
        String entityname = entityClass.getName();
        Entity entity = entityClass.getAnnotation(Entity.class);
        if (entity.name() != null && !"".equals(entity.name())) {
            entityname = entity.name();
        }
        return entityname;
    }

    /**
     * 创建Select后所要查询的字段名称字符串
     * @author slx
     * @date 2009-7-8 上午10:01:02
     * @modifyNote
     * @param fields 
     *          需要查询的字段
     * @param alias  
     *          表的别名
     * @return
     *          拼接成的字段名字符串
     */
    public String buildSelect(String[] fields, String alias) {
        StringBuffer sf_select = new StringBuffer("SELECT");
        for (String field : fields) {
            sf_select.append(" ").append(alias).append(".").append(field)
                    .append(",");
        }
        return (sf_select.substring(0, sf_select.length() - 1)).toString();
    }

    /**
     * 创建Select后所要查询的字段名称字符串,并作为实体类的构造函数
     * @author yongtree
     * @date 2010-4-13 上午11:59:04
     * @modifyNote
     * @param fields
     * @param alias
     * @return
     */
    public String buildSelect(String className,String[] fields, String alias) {
        StringBuffer sf_select = new StringBuffer("SELECT new ").append(className).append("(");
        for (String field : fields) {
            sf_select.append(" ").append(alias).append(".").append(field)
                    .append(",");
        }
        return (sf_select.substring(0, sf_select.length() - 1))+")";
    }

    /**
     * 组装order by语句
     * 
     * @param orderby
     *      列名为key ,排序顺序为value的map
     * @return
     *      Order By 子句
     */
    public String buildOrderby(LinkedHashMap<String, String> orderby) {
        StringBuffer orderbyql = new StringBuffer("");
        if (orderby != null && orderby.size() > 0) {
            orderbyql.append(" order by ");
            for (String key : orderby.keySet()) {
                orderbyql.append("o.").append(key).append(" ").append(
                        orderby.get(key)).append(",");
            }
            orderbyql.deleteCharAt(orderbyql.length() - 1);
        }
        return orderbyql.toString();
    }

    /**
     * 得到Count聚合查询的聚合字段,既是主键列
     * @author slx
     * @date 2009-7-8 上午10:26:11
     * @modifyNote
     * @param <T>
     *              实体类型
     * @param clazz     
     *              实体类
     * @param alias
     *              表别名
     * @return
     *              聚合字段名(主键名)
     */
    public <T> String getPkField(Class<T> clazz, String alias) {
        String out = alias;
        try {
            PropertyDescriptor[] propertyDescriptors = Introspector
                    .getBeanInfo(clazz).getPropertyDescriptors();
            for (PropertyDescriptor propertydesc : propertyDescriptors) {
                Method method = propertydesc.getReadMethod();
                if (method != null && method.isAnnotationPresent(Id.class)) {
//                  PropertyDescriptor[] ps = Introspector.getBeanInfo(
//                          propertydesc.getPropertyType())
//                          .getPropertyDescriptors();
                    out = alias
                            + "."
                            + propertydesc.getName();
//                          + "."
//                          + (!ps[1].getName().equals("class") ? ps[1]
//                                  .getName() : ps[0].getName()
//                                  );
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return out;
    }

    /**
     * 设置查询参数
     * @author slx
     * @date 2009-7-8 上午10:02:55
     * @modifyNote
     * @param query 
     *          查询
     * @param queryParams
     *          查询参数
     */
    public Query setQueryParams(Query query, Object queryParams) {
        if (queryParams != null) {
            if (queryParams instanceof Object[]) {
                Object[] params = (Object[]) queryParams;
                if (params.length > 0) {
                    for (int i = 0; i < params.length; i++) {
                        query.setParameter(i + 1, params[i]);
                    }
                }
            } else if (queryParams instanceof Map) {
                Map params = (Map) queryParams;
                Iterator<String> it = params.keySet().iterator();
                while(it.hasNext()){
                    String key = it.next();
                    query.setParameter(key, params.get(key));
                }
            }
        }
        return query;
    }

    /**
     * 将集合中的字符串拼接成为SQL语句中 in的形式 'aaa','bbb','ccc'
     * @author slx
     * @date 2009-5-26 上午10:30:17
     * @modifyNote
     * @param values
     * @return
     */
    public String toSQLIn(Collection<String> values){
        if(values == null || values.isEmpty())
            return null;

        String[] strvalues = new String[0];
        strvalues = (String[]) values.toArray(new String[values.size()]);

        return toSQLIn(strvalues);
    }

    /**
     * 将字符串数组中的字符串拼接成为SQL语句中 in的形式 'aaa','bbb','ccc'
     * @author slx
     * @date 2009-5-26 上午10:30:17
     * @modifyNote
     * @param values
     * @return
     */
    public String toSQLIn(String[] values){
        StringBuffer bf_sqlin = new StringBuffer();
        if(values == null || values.length == 0)
            return null;

        int len = values.length;
        for(int i = 0 ; i < len ; i++){
            bf_sqlin = bf_sqlin.append(", '").append(values[i]).append("' ");
        }
        String str_sqlin = bf_sqlin.substring(1).toString();

        return str_sqlin;
    }
}

QueryResult.java

/************************* 版权声明 *********************************
 * 
 * 版权所有:百洋软件
 * Copyright (c) 2009 by Pearl Ocean.
 * 
 ************************* 变更记录 *********************************
 *
 * 创建者:yongtree   创建日期: 2009-4-30
 * 创建记录:创建类结构。
 * 
 * 修改者:       修改日期:
 * 修改记录:
 ************************* 随   笔 *********************************
 *
 * 这里可以写写感想,感慨,疑问什么的。
 * 
 ******************************************************************
 */

package com.posoftframework.dao;

import java.util.List;

/**
 * 查询结果对象
 * 
 * @author yongtree
 * @date 2009-4-30 上午09:00:12
 * @version 1.0
 */
public class QueryResult<T> {
    private List<T> resultlist;
    private Long totalrecord;

    public List<T> getResultlist() {
        return resultlist;
    }

    public void setResultlist(List<T> resultlist) {
        this.resultlist = resultlist;
    }

    public Long getTotalrecord() {
        return totalrecord;
    }

    public void setTotalrecord(Long totalrecord) {
        this.totalrecord = totalrecord;
    }
}

QueryCondition.java

/************************* 版权声明 *********************************
 * 
 * 版权所有:百洋软件
 * Copyright (c) 2009 by Pearl Ocean.
 * 
 ************************* 变更记录 *********************************
 *
 * 创建者:slx   创建日期: 2009-6-24
 * 创建记录:创建类结构。
 * 
 * 修改者:       修改日期:
 * 修改记录:
 ************************* 随   笔 *********************************
 *
 * 这里可以写写感想,感慨,疑问什么的。
 * 
 ******************************************************************
 */    

package com.posoftframework.dao;

import java.io.Serializable;

/**
 * 条件对象
 * @author slx
 * @date 2009-6-24 上午10:53:46
 * @version 1.0
 */
public class QueryCondition implements Serializable,Cloneable{

    private static final long serialVersionUID = 1L;

    /** 字段名(表名.列名) **/
    private String field ;

    /** 操作符 **/
    private String operator ;

    /** 值 **/
    private Object value ;

    public QueryCondition() {
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public QueryCondition(String field , String operator , Object value) {
        this.field = field ;
        this.operator = operator ;
        this.value = value ;
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public String getOperator() {
        return operator;
    }

    public void setOperator(String operator) {
        this.operator = operator;
    }

    public Object getValue() {
        return value;
    }

    public void setValue(Object value) {
        this.value = value;
    }
}

QueryObject.java

/************************* 版权声明 *********************************
 * 
 * 版权所有:百洋软件
 * Copyright (c) 2009 by Pearl Ocean.
 * 
 ************************* 变更记录 *********************************
 *
 * 创建者:slx   创建日期: 2009-6-24
 * 创建记录:创建类结构。
 * 
 * 修改者:       修改日期:
 * 修改记录:
 ************************* 随   笔 *********************************
 *
 * 这里可以写写感想,感慨,疑问什么的。
 * 
 ******************************************************************
 */    

package com.posoftframework.dao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * 查询对象,用于前后台传输查询条件。
 * 拼接查询语句并返回参数
 * @author slx
 * @date 2009-6-24 上午10:46:05
 * @version 1.0
 */
public class QueryObject implements Serializable{

    private static final long serialVersionUID = 1L;

    /** 条件列表 **/
    private List<QueryCondition> queryConditions ;

    /** 参数列表 **/
    private Object[] queryParams ;

    /** where语句 **/
    private String whereQL ;

    /**
     * 添加查询条件
     * @author slx
     * @date 2009-6-24 上午11:18:16
     * @modifyNote
     * @param field 字段名
     * @param operator  操作符
     * @param value 值
     */
    public void addCondition(String field , String operator , Object value ){
        addCondition(new QueryCondition(field,operator,value));
    }

    /**
     * 添加查询条件
     * @author slx
     * @date 2009-6-24 上午11:19:03
     * @modifyNote
     * @param condition 条件对象
     */
    public void addCondition(QueryCondition condition ){
        getQueryConditions().add(condition);
    }

    /**
     * 设置条件列表
     * @author slx
     * @date 2009-6-24 上午11:19:41
     * @modifyNote
     * @param queryConditions
     */
    public void setQueryConditions(List<QueryCondition> queryConditions){
        this.queryConditions = queryConditions;
    }

    public List<QueryCondition> getQueryConditions() {
        if(queryConditions == null){
            queryConditions = new ArrayList<QueryCondition>();
        }
        return queryConditions;
    }

    /**
     * 得到where语句
     * <br> table.field1 = ? AND table.field2 = ?
     * @author slx
     * @date 2009-6-24 上午11:20:17
     * @modifyNote
     * @return
     */
    public String getWhereQL(){
        buildQuery();
        return whereQL ;
    }

    /**
     * 得到参数列表
     * @author slx
     * @date 2009-6-24 上午11:03:54
     * @modifyNote
     * @return
     */
    public Object[] getQueryParams(){
        buildQuery();
        return queryParams ;
    }

    /**
     * 构造查询,初始化where和params
     * @author slx
     * @date 2009-6-24 上午11:31:08
     * @modifyNote
     */
    protected void buildQuery(){
        StringBuffer sf_where = new StringBuffer("");
        int size = getQueryConditions().size();
        queryParams = new Object[size];

        for(int i = 0 ; i < size ; i++){
            QueryCondition condition = getQueryConditions().get(i);
            if(condition.getValue() == null || condition.getValue().toString().trim().equals("")){
                continue;
            }
            sf_where.append(" AND ").append(condition.getField()).append(" ")
                .append(condition.getOperator()).append(" ? ");
            queryParams[i] = condition.getValue();
        }
        whereQL = sf_where.toString();
        whereQL = whereQL. replaceFirst("AND", "");
    }

    public QueryCondition findQueryCondition(String field , String operator){

        for (QueryCondition queryCondition : queryConditions) {
            if (field.equals(queryCondition.getField())
                    && operator.equals(queryCondition.getOperator())) {
                return queryCondition ;
            }
        }
        return null;
    }
}

BaseEO.java

/************************* 版权声明 *********************************
 * 
 * 版权所有:百洋软件
 * Copyright (c) 2009 by Pearl Ocean.
 * 
 ************************* 变更记录 *********************************
 *
 * 创建者:yongtree   创建日期: 2009-4-29
 * 创建记录:创建类结构。
 * 
 * 修改者:       修改日期:
 * 修改记录:
 ************************* 随   笔 *********************************
 *
 * 这里可以写写感想,感慨,疑问什么的。
 * 
 ******************************************************************
 */

package com.posoftframework.entity.base;

import java.io.Serializable;
import java.util.List;

import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;

/**
 * 基础实体Bean,包含系统表中公共的字段 <br>
 * 重写 toString() clone() equals() hashCode()
 * 
 * @author yongtree
 * @date 2009-4-29 下午01:43:42
 * @version 1.0
 */
@MappedSuperclass
public abstract class BaseEO implements Serializable {

    private static final long serialVersionUID = 1962905939086138888L;

    private transient EOUtility eoutil ;

    protected boolean selected;

    @Transient
    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    @Transient
    protected EOUtility getBeanUtility() {
        if (eoutil == null) {
            eoutil = new EOUtility(this);
        }
        return eoutil;
    }

    @Override
    public String toString() {
        return getBeanUtility().beanToString();
    }

    @Override
    public boolean equals(Object obj) {
        return getBeanUtility().equalsBean(obj);
    }

    @Override
    public int hashCode() {
        return getBeanUtility().hashCodeBean();
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Object obj = null;
        try {
            obj = getBeanUtility().cloneBean();
        } catch (Exception e) {
            throw new CloneNotSupportedException(e.getMessage());
        }

        return obj;
    }

    /**
     * 得到所有可持久化字段的名称
     * @author slx
     * @date 2009-7-17 上午08:59:34
     * @modifyNote
     * @return
     *      名称列表
     */
    @Transient
    public String[] getAttributeNames(){
        return getBeanUtility().getAttributeNames();
    }

    /**
     * 得到某个字段的值
     * @author slx
     * @date 2009-7-17 上午08:59:58
     * @modifyNote
     * @param attributeName
     *      字段名
     * @return
     *      值
     */
    @Transient
    public Object getAttributeValue(String attributeName) {
        return getBeanUtility().getAttributeValue(attributeName);
    }

    /**
     * 设置某个字段的值
     * @author slx
     * @date 2009-7-17 上午09:00:26
     * @modifyNote
     * @param attributeName
     *      字段名
     * @param value
     *      值
     */
    @Transient
    public void setAttributeValue(String attributeName , Object value){
        getBeanUtility().setAttributeValue(attributeName,value);
    }

    @SuppressWarnings("static-access")
    @Transient
    public String getEnumDescription(String enumAttributeName){
        Object value = getAttributeValue(enumAttributeName);

        return getBeanUtility().getEnumDescription(value);
    }

    /**
     * 获得实体对应的表名
     * 
     * @author slx
     * @date 2009-7-17 上午09:00:57
     * @modifyNote
     * @return
     */
    @Transient
    public String getTableName() {
        return getBeanUtility().getTableName();
    }

    /**
     * 比较此对象与另一个对象的差别,并返回值不同的字段的名称。
     * 
     * @author slx
     * @date 2009-7-17 上午09:34:39
     * @modifyNote
     * @param antherBean
     *            将要比较的对象
     * @return 值不同的字段名
     */
    @Transient
    public List<String> getDifferentField(BaseEO anotherBean) {
        return getBeanUtility().getDifferentField(anotherBean);
    }

    /**
     * 获取主键值
     * 
     * @author slx
     * @date 2009-6-12 上午09:15:11
     * @modifyNote
     * @return 主键值
     */
    @Transient
    public abstract Object getPrimaryKey();

    /**
     * 比较主键值是否相同
     * 
     * @author yongtree
     * @date 2009-9-15 下午04:09:21
     * @modifyNote
     * @param obj
     * @return
     */
    @Transient
    public boolean equalsPK(Object obj) {
        if (obj == null)// 对象为空不比较
            return false;
        // 类型不同不必进行比较
        if (!this.getClass().equals(obj.getClass())) {
            return false;
        }

        // 不是BaseEO,不必比较
        if (!(obj instanceof BaseEO)) {
            return false;
        }

        BaseEO eo = (BaseEO) obj;

        if (getPrimaryKey()!=null
                && eo.getPrimaryKey()!=null) {
            if (getPrimaryKey().equals(eo.getPrimaryKey()))
                return true;
            return false;
        } else {
            return false;
        }

    }

    /**
     * 拷贝另一个eo对象中的字段值到当前对象中
     * @author slx
     * @date 2009-12-6 上午11:04:49
     * @modifyNote
     * @param fromEO            从哪里拷贝
     * @param copyAttributes    拷贝哪些字段
     */
    public void copyAttributeValue(BaseEO fromEO , String[] copyAttributes){
        if(copyAttributes == null)
            return ;

        for (String attr : copyAttributes) {
            this.setAttributeValue(attr, fromEO.getAttributeValue(attr));
        }
    }

    /**
     * 加载所有延迟加载字段
     * @author slx
     * @date 2010年4月1日17:22:29
     * @modifyNote
     */
    public void loadLazyAttributes(){
        getBeanUtility().loadLazyField();
    }

}

DateUtil.java

package com.posoftframework.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 字符串公共工具类
 * <br>提供关于字符串处理的公用方法
 * <li> 按照指定格式格式化日期并作为字符串返回
 * <li> 将字符串数组或者容器转换为sql语句中in子句的形式。
 * 
 * @author slx
 * @date 2009-5-14 下午05:21:42
 * @version 1.0
 */
public class DateUtil {

    private static DateFormat datefmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 按照指定格式返回日期字符串
     * 
     * @author slx
     * @date 2009-5-14 下午05:20:06
     * @modifyNote
     * @param date
     *          需要格式化的日期
     * @param format
     *          格式化字符串,为空则采用默认  yyyy-MM-dd hh:mm:ss。如果格式化字符串不合法会抛出异常
     * @return
     *          格式化后的日期字符串。
     */
    public static String formatDate(Date date , String format){
        if(date == null)
            return null;
        String str_date = null;
        if(format != null){
            DateFormat formater = new SimpleDateFormat(format);
            str_date = formater.format(date);
        }else{
            str_date =datefmt.format(date);
        }

        return str_date;
    }

    public static Date parseToDate(String date , String format) throws ParseException{
        if(date == null)
            return null;
        Date dDate = null;
        if(format != null){
            DateFormat formater = new SimpleDateFormat(format);
            dDate = formater.parse(date);
        }else{
            DateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
            dDate =formater.parse(date);
        }

        return dDate;
    }

    /**
     * 比较两个时间是否相等。
     * @author slx
     * @date 2009-7-13 上午10:08:52
     * @modifyNote
     * @param d1  
     *          时间1
     * @param d2
     *          时间2 
     * @return
     *          相等则true。因为数据库中读出的数据为Timestamp类型(Date的子类),
     * 当它与Date类型进行比较时,总是为false,即使是同一个时间.因此写了这个方法,用于兼容这两种类型的时间比较.
     */
    public static boolean equalsDate(Date d1 , Date d2){
        if(d1 !=null && d2!= null){
            return d1.getTime() == d2.getTime();
        }
        return false;
    }

    /**
     * 判断后面的一天是否是前面一天的下一天
     * @author slx
     * @date 2009-7-8 下午04:46:38
     * @modifyNote
     * @param day   
     *          基准日期
     * @param nextDay
     *          比较日期
     * @return
     *          如果比较日期是基准日期的下一天则返回true,否则为false
     */
    public static boolean isNextDay(Date day,Date nextDay){
        return ( getBetweenDays(day ,nextDay) == -1 );
    }

    /**
     * 判断两个日期是否是同一天
     * @author slx
     * @date 2009-11-10 下午04:32:07
     * @modifyNote
     * @param day
     * @param otherDay
     * @return
     */
    public static boolean isSameDay(Date day,Date otherDay){
        return ( getBetweenDays(day ,otherDay) == 0 );
    }

    /**
     * 计算两个日期相差的天数.不满24小时不算做一天
     * @author slx
     * @date 2009-7-10 下午03:15:54
     * @modifyNote
     * @param fDate     日期1
     * @param oDate     日期2
     * @return
     *      日期1 - 日期2 的差
     */
    public static int getBetweenDays(Date fDate, Date sDate) {
        int day=(int)((fDate.getTime()-sDate.getTime())/86400000L);//(24小时 * 60分 * 60秒 * 1000毫秒 = 1天毫秒数) 
        return day;
    }

    /**
     * 日期相加指定年
     * @author slx
     * @date 2009-9-10 上午10:26:22
     * @modifyNote
     * @param date
     *      日期
     * @param addYears
     *      要添加的年数
     * @return
     *      相加后的日期
     */
    public static Date addYears(Date date , int addYears){
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.add(Calendar.YEAR, addYears);
        return calender.getTime();
    }
    /**
     * 加指定月
     * @author slx
     * @date 2009-9-10 上午10:26:57
     * @modifyNote
     * @param date
     *      日期
     * @param addMonths
     *      月数
     * @return
     *      相加后的日期
     */
    public static Date addMonth(Date date , int addMonths){
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.add(Calendar.MONTH, addMonths);
        return calender.getTime();
    }

    /**
     * 加指定天数
     * @author slx
     * @date 2009-9-10 上午10:27:22
     * @modifyNote
     * @param date
     *      日期
     * @param addDays
     *      天数
     * @return
     *      相加后的日期
     */
    public static Date addDay(Date date , int addDays){
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.add(Calendar.DAY_OF_YEAR, addDays);
        return calender.getTime();
    }

    /**
     * 得到一年的第一天
     * @author slx
     * @date 2009-9-10 上午11:14:23
     * @modifyNote
     * @param year
     *      年
     * @return
     *      一年的第一天
     */
    public static Date getFirstDateOfYear(int year){
        Calendar calender = Calendar.getInstance();
        calender.set(Calendar.YEAR,year);
        calender.set(Calendar.DAY_OF_YEAR, calender.getActualMinimum(Calendar.DAY_OF_YEAR));
        setStartTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 得到一年的最后一天
     * @author slx
     * @date 2009-9-10 上午11:14:42
     * @modifyNote
     * @param year
     *      年
     * @return
     *      一年的最后一天
     */
    public static Date getLastDateOfYear(int year){
        Calendar calender = Calendar.getInstance();
        calender.set(Calendar.YEAR,year);
        calender.set(Calendar.DAY_OF_YEAR, calender.getActualMaximum(Calendar.DAY_OF_YEAR));
        setEndTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 判断当前日期是否是所在月份的最后一天
     * @author slx
     * @date 2009-9-10 上午10:54:36
     * @modifyNote
     * @param date
     *      日期
     * @return
     *      是最后一天为 true
     */
    public static boolean isLastDayOfMonth(Date date) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        int day = calender.get(Calendar.DAY_OF_MONTH);
        int lastDay = calender.getActualMaximum(Calendar.DAY_OF_MONTH);
        return day == lastDay ;
    }

    /**
     * 得到指定月的最后一天
     * @author slx
     * @date 2009-9-10 上午11:09:56
     * @modifyNote
     * @param year
     *      年
     * @param month
     *      月
     * @return
     *      最后一天
     */
    public static Date getLastDayOfMonth(int year , int month){
        Calendar calender = Calendar.getInstance();
        calender.set(year, month-1, 1);
        calender.set(Calendar.DAY_OF_MONTH, calender.getActualMaximum(Calendar.DAY_OF_MONTH));
        setEndTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 得到日期所在月的最后一天
     * @author slx
     * @date 2009-9-10 上午10:54:25
     * @modifyNote
     * @param date
     *      日期
     * @return
     *      所在月的最后一天
     */
    public static Date getLastDayOfMonth(Date date){
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.set(Calendar.DAY_OF_MONTH, calender.getActualMaximum(Calendar.DAY_OF_MONTH));
        setEndTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 设置到当前月的最后时刻
     * @author slx
     * @date 2010-10-18 上午11:04:56
     * @modifyNote
     * @param calender
     */
    private static void setEndTimeOfDay(Calendar calender){
        calender.set(Calendar.HOUR_OF_DAY, calender.getActualMaximum(Calendar.HOUR_OF_DAY));
        calender.set(Calendar.MINUTE, calender.getActualMaximum(Calendar.MINUTE));
        calender.set(Calendar.SECOND, calender.getActualMaximum(Calendar.SECOND));
        calender.set(Calendar.MILLISECOND, calender.getActualMaximum(Calendar.MILLISECOND));
    }

    /**
     * 得到指定月的第一天
     * @author slx
     * @date 2009-9-10 上午11:09:56
     * @modifyNote
     * @param year
     *      年
     * @param month
     *      月
     * @return
     *      第一天
     */
    public static Date getFirstDayOfMonth(int year , int month){
        Calendar calender = Calendar.getInstance();
        calender.set(year, month-1, 1);
        calender.set(Calendar.DAY_OF_MONTH, calender.getActualMinimum(Calendar.DAY_OF_MONTH));
        setStartTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 得到指定日期所在月的第一天
     * @author slx
     * @date 2009-9-10 上午11:09:56
     * @modifyNote
     * @param date
     *      日期
     * @return
     *      第一天
     */
    public static Date getFirstDayOfMonth(Date date){
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        calender.set(Calendar.DAY_OF_MONTH, calender.getActualMinimum(Calendar.DAY_OF_MONTH));
        setStartTimeOfDay(calender);
        return calender.getTime();
    }

    /**
     * 设置到月份开始的时刻
     * @author slx
     * @date 2010-10-18 上午11:06:12
     * @modifyNote
     * @param calender
     */
    private static void setStartTimeOfDay(Calendar calender){
        calender.set(Calendar.HOUR_OF_DAY, calender.getActualMinimum(Calendar.HOUR_OF_DAY));
        calender.set(Calendar.MINUTE, calender.getActualMinimum(Calendar.MINUTE));
        calender.set(Calendar.SECOND, calender.getActualMinimum(Calendar.SECOND));
        calender.set(Calendar.MILLISECOND, calender.getActualMinimum(Calendar.MILLISECOND));
    }

    public static Date getStartTimeOfDay(Date date){
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        setStartTimeOfDay(calender);
        return calender.getTime();
    }

    public static Date getEndTimeOfDay(Date date){
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        setEndTimeOfDay(calender);
        return calender.getTime();

    }

    /**
     * 得到当前年月
     * 
     * @author yongtree
     * @date 2008-11-22 上午11:25:24
     * @return 格式:2008-11
     * @throws ParseException
     */
    public static  String getThisYearMonth() throws ParseException {
        return getYearMonth(new Date());
    }

    /**
     * 得到年月
     * 
     * @author slx
     * @date 2010年4月16日13:09:23
     * @return 格式:2008-11
     * @throws ParseException
     */
    public static  String  getYearMonth(Date date){
        Calendar today = Calendar.getInstance();
        today.setTime(date);
        return (today.get(Calendar.YEAR)) + "-" + ((today.get(Calendar.MONTH)+1)>=10?(today.get(Calendar.MONTH)+1):("0"+(today.get(Calendar.MONTH) + 1)));
    }

    /**
     * 计算两个日期之间相差的月份数
     * <br> 日期顺序不分先后不会返回负数
     * <br> 不足一个月不算做一个月
     * @author slx
     * @date 2010年4月16日11:32:51
     * @modifyNote
     * @param date1
     *      日期1
     * @param date2
     *      日期2
     * @return
     *      月数
     */
    public static int getBetweenMonths(Date date1, Date date2){      
        int iMonth = 0;      
        int flag = 0;      
        Calendar objCalendarDate1 = Calendar.getInstance();      
        objCalendarDate1.setTime(date1);      

        Calendar objCalendarDate2 = Calendar.getInstance();      
        objCalendarDate2.setTime(date2);      

        if (objCalendarDate2.equals(objCalendarDate1))      
            return 0;      
        if (objCalendarDate1.after(objCalendarDate2)){      
            Calendar temp = objCalendarDate1;      
            objCalendarDate1 = objCalendarDate2;      
            objCalendarDate2 = temp;      
        }      
        if (objCalendarDate2.get(Calendar.DAY_OF_MONTH) < objCalendarDate1.get(Calendar.DAY_OF_MONTH))      
            flag = 1;      

        if (objCalendarDate2.get(Calendar.YEAR) > objCalendarDate1.get(Calendar.YEAR))      
            iMonth = ((objCalendarDate2.get(Calendar.YEAR) - objCalendarDate1.get(Calendar.YEAR))      
                    * 12 + objCalendarDate2.get(Calendar.MONTH) - flag)      
                    - objCalendarDate1.get(Calendar.MONTH);      
        else     
            iMonth = objCalendarDate2.get(Calendar.MONTH)      
                    - objCalendarDate1.get(Calendar.MONTH) - flag;      

        return iMonth;      
    }

    /**
     * 计算两个日期之间相差的年份数
     * <br> 日期顺序不分先后不会返回负数
     * <br> 不足一个年不算做一个年
     * @author slx
     * @date 2010年4月16日12:01:46
     * @modifyNote
     * @param date1
     *      日期1
     * @param date2
     *      日期2
     * @return
     *      年数
     */
    public static int getBetweenYears(Date date1, Date date2){  
        return getBetweenMonths(date1 ,date2) / 12;
    }

    public static void main(String[] args) throws Exception {
//      Date d1 = parseToDate("2009-11-29", null);
//      Date d2 = parseToDate("2007-12-29", null);
        System.out.println(formatDate(getFirstDayOfMonth(2010,10),"yyyy-MM-dd HH:mm:ss.SSS"));

        System.out.println(formatDate(getLastDateOfYear(2009),"yyyy-MM-dd HH:mm:ss.SSS"));
        System.out.println(formatDate(getFirstDateOfYear(2009),"yyyy-MM-dd HH:mm:ss.SSS"));
        System.out.println(formatDate(getEndTimeOfDay(new Date()),"yyyy-MM-dd HH:mm:ss.SSS"));
    }
}

EnumDescription.java

package com.posoftframework.enums;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 枚举描述
 * 
 * @author slx
 * @date 2009-9-2 下午05:13:57
 * @version 1.0
 */
@Target( {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumDescription {

    String value();
}

EODisplayName.java

package com.posoftframework.entity.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 实体显示用名称(中文名)
 * 
 * @author slx
 * @date 2010-7-1 上午08:55:19
 * @version 1.0
 */
@Target( {ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface EODisplayName {

    String value();

}

FieldDisplayName.java

/************************* 版权声明 *********************************
 *                                                                  *
 *                     版权所有:百洋软件                           *
 *          Copyright (c) 2010 by www.po-soft.com                *
 *                                                                  *
 ************************* 变更记录 *********************************
 *
 * 创建者:slx   创建日期: 2010-7-1
 * 备注:
 * 
 * 修改者:       修改日期:
 * 备注:
 * 
 */    

package com.posoftframework.entity.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 字段显示名(中文名)注解
 * @author slx
 * @date 2010-7-1 上午08:56:37
 * @version 1.0
 */
@Target( {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldDisplayName {

    String value();
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值