package ssh.base;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.List;
import javax.annotation.Resource;
import javax.persistence.Entity;
import ssh.utils.QueryResult;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;

//定义抽象类继承DAO,抽象出所有实体通用的方法,方便其他类继承就可以了,abstract定义了只能继承。
@Component	//放到Spring里,让Spring管理
public abstract class DaoSupport implements DAO {
	
	//注入hibernateTemplate,使用protected,其他类继承后可以直接使用
	public HibernateTemplate hibernateTemplate;
	
	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	@Resource 		//注入hibernateTemplate
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}
	
	
	/**保存数据 
	 * 调用方法:save(new User("shazhuzhu",20)
	 */
	public void save(Object entity) {
		hibernateTemplate.save(entity);
	}
	
	
	/**更新数据 
	 * 调用方法:update(new User(1,"shazhuzhu",20); 其中1为ID
	 */
	public void update(Object entity) {
		hibernateTemplate.update(entity);	//把游离状态的实体BENA同步到数据库
	}
	
	
	/**删除单条记录
	 * 调用方法:delete(User.class,1); 其中1为ID
	 */
	public <T> void delete(Class<T> entityClass,Object entityid) {
		delete(entityClass, new Object[]{entityid});	//调用下面的方法
	
	}
	
	
	//删除多条记录
	public <T> void delete(Class<T> entityClass,Object[] entityids) {
		for(Object id:entityids){
			T t=find(entityClass,id);	////调用下面的find方法先把实体类查找出来,然后在DEL,这样才能通过ID删除数据
			if(t!=null)					//先判断需要删除的数据是否存在
			hibernateTemplate.delete(t);		
		}
	}
	
	
	/**查询指定ID的记录
	 * 调用方法:find(User.class,1); 其中1为ID
	 */
	@SuppressWarnings("unchecked")
	public <T> T find(Class<T> entityClass, Object entityId) {	
		return (T) hibernateTemplate.get(entityClass,(Serializable) entityId);
	}
	
	
	/**
	 * 获得分页数据
	 * QueryResult<T> 泛型定义在类上。因为需要返回查询的数据List,和查询的总条数,所以需要自定义类型返回2个数据
	 * @param <T>	泛型
	 * @param entityClass 实体类
	 * @param firstIndex 开始索引 firstIndex和maxResult都为-1时代表不分页
	 * @param maxResult 需要获取的记录数
	 * @param wherejpql where条件语句
	 * @param queryParams 条件语句参数
	 * @param orderby 排序,LinkedHashMap先进先出,使用这个是因为先进去的放到第一位,order by key1 desc,key2 asc	
	 * @return
	 * 
	 * 调用方法
	 * LinkedHashMap<String , String> orderby=new LinkedHashMap<String, String>();
	 * orderby.put("id", "asc");
	 * QueryResult<TestVo> qr=testDAO.getScrollData(TestVo.class, 1, 10,"o.name=? and o.title=?",new Object[]{"a","1"},orderby);
	 * for (TestVo q : qr.getResultlist()) {
	 * 		System.out.println(q.getName());
	 * }
	 * System.out.println(qr.getTotalrecord());
	 */
	@SuppressWarnings("unchecked")	//不检查类型,不然会有黄色线提示错误。
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult,
			String wherejpql,Object[] queryParams,LinkedHashMap<String, String> orderby) {
		
		QueryResult qr = new QueryResult<T>();	//定义保存数据类型
		String entityname = getEntityName(entityClass);	//获取实体类名称,方法下面定义了
		
		String hql="select o from "+entityname+" o " + (wherejpql==null? "" :"where " + wherejpql) + buildOrderby(orderby);
		System.out.println(hql);
		qr.setResultlist(getListForPage(hql, firstindex, maxresult, queryParams));	//调用hibernateTemplate的扩张方法进行分页处理
		
		String hql2="select count(o) from "+entityname+" o " + (wherejpql==null? "" :"where " + wherejpql);
		Long total=(Long) hibernateTemplate.find(hql2,queryParams).get(0);			//查询总记录数
		
		qr.setTotalrecord(total);
		return qr;
	}
	
	
	 /**
	 * HibernateTemplate 只支持 .setMaxResults(int) 方法。
     * 因此,做 Spring+Hibernate 分页处理要使用到一个接口 org.springframework.orm.hibernate3.HibernateCallback
	 * 来灵活操作数据库,该接口中有一个未实现的方法 Object doInHibernate (Session session),用以获得并利用 session 进行操作(自动创建、销毁)。

     * 分页通用方法
     * @param sql           HQL查询语句
     * @param firstindex    起始记录下标
     * @param maxresult     读取记录数
     * @return              List 结果集
     */
    @SuppressWarnings("unchecked")
	public  List getListForPage(final String hql, final int firstindex, final int maxresult,final Object[] queryParams) {
        try {
            List list = hibernateTemplate.executeFind(new HibernateCallback() {
				
				public Object doInHibernate(Session session) throws HibernateException,SQLException {  
					Query query =  session.createQuery(hql);
					
					if(firstindex!=-1 && maxresult!=-1){	//方便设置-1时不分页
						query.setFirstResult(firstindex);
						query.setMaxResults(maxresult);
					}
					setQueryParams(query, queryParams);		//调用下面方法插入where传递过来的参数
					return  query.list();
				}
			});
            return list;
        } catch (RuntimeException re) {
            throw re;
        }
    }
	
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult,LinkedHashMap<String, String> orderby) {
		return getScrollData(entityClass,firstindex,maxresult,null,null,orderby);
	}
	
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult,String wherejpql,Object[] queryParams) {
		return getScrollData(entityClass,firstindex,maxresult,wherejpql,queryParams,null);
	}

	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult) {
		return getScrollData(entityClass,firstindex,maxresult,null,null,null);
	}

	public <T> QueryResult<T> getScrollData(Class<T> entityClass) {
		return getScrollData(entityClass,-1,-1);	//主方法定义-1为不分页
	}



	/**
	 * 获取实体类的名称
	 * @param <T>
	 * @param entityClass
	 * @return
	 */
	protected <T> String getEntityName(Class<T> entityClass) {
		String entityname=entityClass.getSimpleName();			//如果实体类上面的@Entity(name=xxx)没有指定名称,直接为默认类名称
		Entity entity=entityClass.getAnnotation(Entity.class);	//获取@Entity注解
		if(entity.name()!=null&&!"".equals(entity.name())){		//判断注解的name是否为空
			entityname=entity.name();
		}
		return entityname;
	}
	
	
	/**
	 * 组装order by语句
	 * @param orderby
	 * @return  //	order by o.key desc,key2 asc
	 */
	protected 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()){	//取得Map的Key的集合
				orderbyql.append("o.").append(key).append(" ").append(orderby.get(key)).append(",");	
			}
			orderbyql.deleteCharAt(orderbyql.length()-1);
		}
		return orderbyql.toString();
	}

	
	/**
	 * 为Where语句传递参数
	 * @param query
	 * @param queryParams
	 * o.key = ?1 and o.name=?2 这是错误的,JPA的问号索引是从1开始的,而HibernateTemplate是从0开始的,HibernateTemplate执行HQL语句时,HQL的语句中'?'号面是不带数字的
	 * o.key = ? and o.name=? 正确
	 */
	protected void setQueryParams(Query query,Object[] queryParams) {
		if(queryParams!=null && queryParams.length>0){
			for(int i=0;i<queryParams.length;i++){		//JPA的问号索引是从1开始的,而HibernateTemplate是从0开始的	
				query.setParameter(i, queryParams[i]);	//如果是JPA:i+1
			}
		}
	}
	
}
最近下载更多
PaymentCodeSystem  LV11 2022年9月9日
panyu329  LV1 2021年6月3日
and123456  LV11 2021年4月20日
雨后江岸天破晓  LV1 2020年6月23日
tumuwang  LV1 2019年12月4日
sixiongbin  LV8 2019年11月28日
r31506144  LV1 2019年5月20日
xiex909  LV27 2019年2月17日
意必固我  LV1 2019年1月16日
稀饭囡  LV9 2018年7月11日
最近浏览更多
PaymentCodeSystem  LV11 2022年9月9日
好的好的  LV8 2021年8月19日
.空运绵熊.  LV1 2021年6月5日
panyu329  LV1 2021年6月3日
jibamao  LV2 2021年4月27日
and123456  LV11 2021年4月20日
小星七的  LV12 2021年3月16日
0592lyj  LV9 2021年3月11日
mocker  LV6 2021年1月27日
ck10086  LV1 2021年1月11日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友