package com.dubh.common.dao.hibernate;

import com.dubh.common.dao.Dao;
import org.hibernate.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 作者姓名: dubaohui
 * @version 创建时间：2015-5-15 上午11:20:08 类说明：公用方法实现类
 */
public class BaseDaoHibernate implements Dao {
	@Autowired
	private SessionFactory sessionFactory;

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

	
	/**
	 * 添加对象
	 * 
	 * @param object
	 *            实体类
	 * @throws Exception
	 */
	public void saveObject(Object object) throws Exception {
		Session session = null;
		Transaction tx=null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory().openSession();
			tx = session.beginTransaction();
			String entityName = getEntityName(object);
			session.save(entityName, object);
			tx.commit();
		} catch (Exception ex) {
			if(tx !=null){
				   tx.rollback();
				}
			throw new RuntimeException("saveObject：" + ex);
		} finally {

			closeResouce(session);
		}
	}

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	/**
	 * 更新对象
	 * 
	 * @param object
	 *            实体对象
	 * @throws Exception
	 */
	public void updateObject(Object object) throws Exception {
		
		Session session = null;
		Transaction tx=null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory().openSession();
			tx = session.beginTransaction();
			String entityName = getEntityName(object);
			session.update(entityName, object);
			tx.commit();
		} catch (Exception ex) {
			if(tx !=null){
			   tx.rollback();
			}
			throw new RuntimeException("updateObject：" + ex);
		} finally {
			closeResouce(session);
		}
	}

	/**
	 * 删除对象
	 * 
	 * @param clazz
	 *            实体类
	 * @param id
	 *            主键
	 * @throws Exception
	 */
	public void removeObject(Class clazz, Serializable id) throws Exception {
		Session session = null;
		Transaction tx = null;
		try{
			session = sessionFactory.getCurrentSession().getSessionFactory().openSession();
			tx = session.beginTransaction();
			session.delete(getObject(clazz, id));
			tx.commit();
		}catch(Exception ex){
			if(null !=tx){
				tx.rollback();
			}
			throw new RuntimeException("removeObject：" + ex);
		}finally{
			closeResouce(session);
		}
	}

	/**
	 * 通过传入hql语句进行批量更新对象
	 * 
	 * @param hqlStr
	 *            HQL语句
	 * @throws Exception
	 */
	public void updateHql(String hqlStr) throws Exception {
		Session session = null;
		Transaction tx = null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			tx = session.beginTransaction();
			Query query = session.createQuery(hqlStr);
			query.executeUpdate();
			tx.commit();
		} catch (Exception ex) {
			if(tx !=null){
				tx.rollback();
			}
			throw new RuntimeException("updateObjects" + ex);
		} finally {

			closeResouce(session);
		}

	}

	/**
	 * 获取单一对象
	 * 
	 * @param clazz
	 *            实体类
	 * @param id
	 *            主键
	 * @return
	 */
	public Object getObject(Class clazz, Serializable id) {
		Object o = sessionFactory.getCurrentSession().get(clazz, id);

		if (o == null) {
			throw new ObjectRetrievalFailureException(clazz, id);
		}

		return o;
	}

	/**
	 * 通过传入hql语句获取记录集,并支持分页功能
	 * 
	 * @param hqlStr
	 *            HQL语句
	 * @param pageNo
	 *            页码
	 * @param pageSize
	 *            页面大小
	 * @return 返回记录集
	 * @throws Exception
	 */
	public List getRsByHql(String hqlStr, int pageNo, int pageSize)
			throws Exception {
		List list = new ArrayList();
		Session session = null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			Query query = session.createQuery(hqlStr);
			query.setFirstResult(getFirstSize(pageNo, pageSize));
			query.setMaxResults(pageSize);
			list = query.list();
			System.out.println(list);
			return list;
		} catch (HibernateException ex) {
			throw new RuntimeException("getRsByHql" + ex);
		} finally {
			closeResouce(session);
		}
	}

	/**
	 * 通过传入标准sql语句获取记录集
	 * 
	 * @param sqlStr
	 *            SQL语句
	 * @return 返回记录集
	 * @throws Exception
	 */
	public List getRsBySql(String sqlStr) throws Exception {
		Session session = null;
		try {
			long startTime=System.currentTimeMillis();
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			SQLQuery sqlQuery = session.createSQLQuery(sqlStr);
			System.out.println("getRsBySql1:"+(System.currentTimeMillis()-startTime));
			List list=sqlQuery.list();
			System.out.println("getRsBySql2:"+(System.currentTimeMillis()-startTime));
			return list;
		} catch (HibernateException ex) {
			throw new RuntimeException("getRsBySql： " + ex);
		} finally {
			closeResouce(session);
		}
	}

	/**
	 * 通过传入标准sql语句获取记录集,并支持分页
	 * 
	 * @param sqlStr
	 *            SQL语句
	 * @param pageNo
	 *            页码
	 * @param pageSize
	 *            页面大小
	 * @return 返回记录集
	 * @throws Exception
	 */
	public List getRsBySql(String sqlStr, int pageNo, int pageSize)
			throws Exception {
		Session session = null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			SQLQuery sqlQuery = session.createSQLQuery(sqlStr);
		//	sqlQuery.list().size();
			sqlQuery.setFirstResult(getFirstSize(pageNo, pageSize));
			sqlQuery.setMaxResults(pageSize);
			return sqlQuery.list();
		} catch (HibernateException ex) {
			throw new RuntimeException("getRsBySql： " + ex);
		} finally {
			closeResouce(session);
		}
	}

	/**
	 * 通过传入标准sql语句获取记录集行数
	 * 
	 * @param sqlStr
	 *            SQL语句
	 * @return 返回记录集数量
	 * @throws Exception
	 */
	public Integer getRsCountsBySql(String sqlStr) throws Exception {
		// TODO Auto-generated method stub
		Session session = null;
		Integer count = new Integer(0);
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			SQLQuery sqlQuery = session.createSQLQuery(sqlStr);
			List list = sqlQuery.list();
			if (null != list && list.size() > 0) {
				count = list.size();
			}
			return count;
		} catch (HibernateException ex) {
			throw new RuntimeException("getRsCountsBySql： " + ex);

		} finally {
			closeResouce(session);
		}
	}
	/**
	 * 通过传入标准hql语句获取记录集行数
	 * 
	 * @param hqlStr
	 *            SQL语句
	 * @return 返回记录集数量
	 * @throws Exception
	 */
	public Integer getRsCountsBySelectHql(String hqlStr) throws Exception {
		// TODO Auto-generated method stub
		Session session = null;
		Integer count = new Integer(0);
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			String countsql="select count(*)"+hqlStr.substring(hqlStr.toLowerCase().indexOf("from"));
			
			//createSQLQuery和createQuery
			 count = Integer.valueOf(session.createQuery(countsql).uniqueResult().toString());
			
			return count;
		} catch (HibernateException ex) {
			throw new RuntimeException("getRsCountsBySql： " + ex);

		} finally {
			closeResouce(session);
		}
	}
	
	/**
	 * 通过传入标准sql语句获取记录集行数
	 * 
	 * @param sqlStr
	 *            SQL语句
	 * @return 返回记录集数量
	 * @throws Exception
	 */
	public Integer getRsCountsBySelectSql(String sqlStr) throws Exception {
		// TODO Auto-generated method stub
		Session session = null;
		Integer count = new Integer(0);
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
//			String countsql="select count(*)"+sqlStr.substring(sqlStr.toLowerCase().indexOf("from"));
			String countsql="select count(*)"+sqlStr.substring(sqlStr.toLowerCase().lastIndexOf("from"));
			//createSQLQuery和createQuery
			 count = Integer.valueOf(session.createSQLQuery(countsql).uniqueResult().toString());
			
			return count;
		} catch (HibernateException ex) {
			throw new RuntimeException("getRsCountsBySql： " + ex);

		} finally {
			closeResouce(session);
		}
	}
	
	/**
	 * 通过传入标准sql语句获取单个sql执行语句
	 * 
	 * @param sqlStr
	 *            SQL语句
	 * @return 返回记录集数量
	 * @throws Exception
	 */
	public Double getRsSingleCountsBySelectSql(String sqlStr) throws Exception {
		Session session = null;
		Double count = new Double(0);
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			String countsql=sqlStr;
			
			 count = Double.valueOf((session.createSQLQuery(countsql).uniqueResult()).toString());
			
			return count;
		} catch (HibernateException ex) {
			throw new RuntimeException("getRsCountsBySql： " + ex);

		}catch (NullPointerException ex) {
			ex.printStackTrace();
			return 0.0;

		}  finally {
			closeResouce(session);
		}
	}
	/**
	 * 通过传入标准hql语句获取记录集行数
	 * 
	 * @param hqlStr
	 *            HQL语句
	 * @throws Exception
	 */
	public Integer getRsCountsByHql(String hqlStr) throws Exception {
		// TODO Auto-generated method stub
		Session session = null;
		Integer count = new Integer(0);
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			Query query = session.createQuery(hqlStr);
			List list = query.list();
			if (null != list && list.size() > 0) {
				count = list.size();
			}
			return count;
		} catch (HibernateException ex) {
			throw new RuntimeException("getRsCountsByHql：" + ex);

		} finally {
			closeResouce(session);
		}
	}

	/**
	 * 通过传入hql语句获取记录集
	 * 
	 * @param hqlStr
	 *            HQL语句
	 * @return 返回记录集
	 * @throws Exception
	 */
	public List getRsByHql(String hqlStr) throws Exception {
		Query query = sessionFactory.getCurrentSession().createQuery(hqlStr);
		return query.list();
	}

	/**
	 * 批量删除数据
	 * 
	 * @param hqlStr
	 *            HQL语句
	 * @throws Exception
	 */
	public void deleteHql(String hqlStr) throws Exception {
		Session session = null;
		Transaction tx = null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			tx = session.beginTransaction();
			Query query = session.createQuery(hqlStr);
			query.executeUpdate();
			tx.commit();
		} catch (Exception ex) {
			if(tx !=null){
				tx.rollback();
			}
			throw new RuntimeException("deleteHql：" + ex);
		} finally {
			closeResouce(session);
		}

	}

	/**
	 * 删除数据
	 * 
	 * @param object
	 *            实体对象
	 */
	public void deleteObject(Object object) throws Exception {
		Session session =null;
		Transaction tx = null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory().openSession();
			tx = session.beginTransaction();
			session.delete(object);
			tx.commit();
		} catch (Exception e) {
			if(tx !=null){
				tx.rollback();
			}
			throw new RuntimeException("deleteObject：" + e);
		}finally{
			closeResouce(session);
		}
	}

	/**
	 * 关闭资源
	 * 
	 * @param object
	 * @throws Exception
	 */
	protected void closeResouce(Object object) throws Exception {
		if (null == object)
			return;

		if (object instanceof Connection) {
			Connection conn = (Connection) object;
			conn.close();
		} else if (object instanceof Statement) {
			Statement statement = (Statement) object;
			statement.close();
		} else if (object instanceof PreparedStatement) {
			PreparedStatement prepared = (PreparedStatement) object;
			prepared.close();
		} else if (object instanceof ResultSet) {
			ResultSet rs = (ResultSet) object;
			rs.close();
		} else if (object instanceof Session) {
			Session session = (Session) object;
			session.close();
		}

	}

	/**
	 * 获得实体对象名称
	 * 
	 * @param object
	 *            实体对象
	 * @return
	 */
	private String getEntityName(Object object) {
		String entityName = new String("");
		try {
			Class objectClass = object.getClass();
			entityName = objectClass.getName();
		} catch (Exception ex) {
			throw new RuntimeException("" + ex);
		}
		return entityName;
	}

	/**
	 * 保存或更新一个实体对象
	 * 
	 * @param object
	 *            实体对象
	 * @throws Exception
	 *             异常信息
	 */
	public void saveOrUpdate(Object object) throws Exception {
		Session session =null;
		Transaction tx = null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory().openSession();
			tx = session.beginTransaction();
			session.saveOrUpdate(object);
			session.flush();
			session.clear();
			tx.commit();
		} catch (Exception e) {
			if(tx !=null){
				tx.rollback();
			}
			throw new RuntimeException("saveOrUpdate " + e);
		}finally{
			closeResouce(session);
		}

	}

	/**
	 * 获得当前分页开始的记录数
	 * 
	 * @param pageNo
	 *            页码
	 * @param pageSize
	 *            页面大小
	 * @return 当前分页开始记录数
	 */
	private int getFirstSize(int pageNo, int pageSize) {
		int firstSize = 0;
		firstSize = (pageNo - 1) * pageSize;
		return firstSize;
	}

	public void updateSql(String sql) throws Exception {
		Session session = null;
		Transaction tx = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			SQLQuery query = session.createSQLQuery(sql);
			query.executeUpdate();
			tx.commit();
		} catch (Exception ex) {
			if(tx !=null){
				tx.rollback();
			}
			throw new RuntimeException("updateSql：" + ex);
		} finally {
			closeResouce(session);
		}
	}

	/**
	 * 调用存储过程信息
	 * 
	 * @param stroName
	 * @throws Exception
	 */
	public void getcallStor(String stroName, String parm) throws Exception {
		Session session = null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			String proc = "{ call " + stroName + "(:param) }";
			SQLQuery query = session.createSQLQuery(proc);
			if (null != parm && !"".equals(parm)) {
				query.setParameter("param", parm);
			}
			query.executeUpdate();
		} catch (Exception ex) {

			throw new RuntimeException("getcallStor：" + ex);

		} finally {

			closeResouce(session);
		}
	}

	public void createView(String sqlStr) throws Exception {
		Session session = null;
		Transaction tx = null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			tx = session.beginTransaction();
			SQLQuery query = sessionFactory.getCurrentSession().createSQLQuery(
					sqlStr);
			query.executeUpdate();
			tx.commit();
		} catch (Exception ex) {
			if(tx !=null){
				tx.rollback();
			}
			throw new RuntimeException("createView：" + ex);

		} finally {

			closeResouce(session);
		}

		
	}

	public void deletes(String hqlStr) throws Exception {
		Session session = null;
		Transaction tx = null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			tx = session.beginTransaction();
			Query query = session.createQuery(hqlStr);
			query.executeUpdate();
			tx.commit();
		} catch (Exception ex) {
			if(tx !=null){
				tx.rollback();
			}
			throw new RuntimeException("deletes：" + ex);

		} finally {

			closeResouce(session);
		}

	}

	@Override
	public Object getObjectHql(String hql) throws Exception {
		// TODO Auto-generated method stub
		Session session = null;
		Object obj = null;
		try {
			session = sessionFactory.getCurrentSession().getSessionFactory()
					.openSession();
			Query query = session.createQuery(hql);
			obj = query.uniqueResult();
		} catch (Exception ex) {
			throw new RuntimeException("getObjectHql：" + ex);
		} finally {
			closeResouce(session);
		}

		return obj;
	}
	
	
	public  Session getSession() {  
        Session session = null;  
        if(null==session || false==session.isOpen()){  
            session = sessionFactory.openSession();  
        }else{
        	session=sessionFactory.getCurrentSession();
        }
        return session;  
    }
}
