package com.wisedu.coeus.core.dao;

import com.wisedu.coeus.core.db.PageMaker;
import com.wisedu.coeus.core.exception.DatabaseException;
import com.wisedu.coeus.debug.Logger;
import com.wisedu.coeus.debug.LoggerFactory;
import com.wisedu.coeus.util.ObjectUtils;
import com.wisedu.coeus.util.Strings;
import com.wisedu.coeus.util.sql.SqlHelper;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;


public class BaseDao extends HibernateDaoSupport {
    protected static Logger LOGGER = LoggerFactory.getLogger(BaseDao.class);
    @Autowired
    protected SqlHelper sqlHelper;

    @Autowired
    public void init(HibernateTemplate hibernateTemplate) {
        super.setHibernateTemplate(hibernateTemplate);

        ConvertUtils.register(new DateConverter(), Date.class);
    }

    /**
     * 装载实体
     *
     * @param clazz
     * @param id
     * @param <T>
     * @return
     */
    protected <T> T load(Class<T> clazz, Serializable id) {

        return (T) getHibernateTemplate().get(clazz, id);
    }

    /**
     * 插入实体
     *
     * @param entity 实体对象
     * @throws DatabaseException
     */
    public void insert(Object entity) throws DatabaseException {
        getHibernateTemplate().save(entity);
    }

    public void insertOrUpdate(Object entity) throws DatabaseException {
        getHibernateTemplate().saveOrUpdate(entity);
    }

    /**
     * 批量插入实体
     *
     * @param entityList
     * @throws DatabaseException
     */
    public void insertAll(List entityList)
            throws DatabaseException {
        for (int i = 0; i < entityList.size(); i++) {
            getHibernateTemplate().save(entityList.get(i));
        }
    }

    /**
     * 批量插入/更新实体
     *
     * @param entityList
     * @throws DatabaseException
     */
    public void insertOrUpateAll(List entityList)
            throws DatabaseException {
        for (int i = 0; i < entityList.size(); i++) {
            getHibernateTemplate().saveOrUpdate(entityList.get(i));
        }
    }

    /**
     * 更新实体
     *
     * @param entity
     * @throws DatabaseException
     */
    public void update(Object entity)
            throws DatabaseException {
        getHibernateTemplate().update(entity);
    }

    /**
     * 批量更新实体
     *
     * @param entityList
     * @throws DatabaseException
     */
    public void updateAll(List entityList)
            throws DatabaseException {
        for (int i = 0; i < entityList.size(); i++) {
            getHibernateTemplate().update(entityList.get(i));
        }
    }

    /**
     * 删除实体
     *
     * @param entity
     * @throws DatabaseException
     */
    public void delete(Object entity)
            throws DatabaseException {
        getHibernateTemplate().delete(entity);
    }

    /**
     * 批量删除实体
     *
     * @param entityList
     * @throws DatabaseException
     */
    public void deleteAll(List entityList)
            throws DatabaseException {
        for (int i = 0; i < entityList.size(); i++) {
            getHibernateTemplate().delete(entityList.get(i));
        }
    }

    public void flush() {
        getHibernateTemplate().flush();
    }

    public void merge(Object entity) {
        getHibernateTemplate().merge(entity);
    }
    /**
     * 执行SQL语句
     *
     * @param sql
     * @param params
     * @throws DatabaseException
     */
    public int exec(String sql, Map<String, Object> params)
            throws DatabaseException {
        SQLQuery sqlQuery = getSessionFactory().getCurrentSession().createSQLQuery(sql);
        if (params != null) {
            sqlQuery.setProperties(params);
        }
        return sqlQuery.executeUpdate();
    }

    public int queryForInt(String sql, Map<String, Object> params)
            throws DatabaseException {
        int rowCount = 0;
        try {
            SQLQuery sqlQuery = getSessionFactory().getCurrentSession().createSQLQuery(sql);
            if (params != null) {
                sqlQuery.setProperties(params);
            }

            Object obj = sqlQuery.uniqueResult();
            if (obj != null) {
                if (obj instanceof BigInteger) {
                    rowCount = ((BigInteger) obj).intValue();
                } else if (obj instanceof BigDecimal) {
                    rowCount = ((BigDecimal) obj).intValue();
                } else {
                    rowCount = Integer.parseInt(obj.toString());
                }
            }
        } catch (Exception e) {
            LOGGER.warn(e.getMessage(), e);
            throw new DatabaseException(e);
        }
        return rowCount;
    }

    public Long queryForLong(String sql, Map<String, Object> params)
            throws DatabaseException {
        Long val = null;
        try {
            SQLQuery sqlQuery = getSessionFactory().getCurrentSession().createSQLQuery(sql);
            if (params != null) {
                sqlQuery.setProperties(params);
            }

            Object obj = sqlQuery.uniqueResult();
            if (obj != null) {
                if (obj instanceof BigInteger) {
                    val = ((BigInteger) obj).longValue();
                } else if (obj instanceof BigDecimal) {
                    val = ((BigDecimal) obj).longValue();
                } else {
                    val = Long.parseLong(obj.toString());
                }
            }
        } catch (Exception e) {
            LOGGER.warn(e.getMessage(), e);
            throw new DatabaseException(e);
        }
        return val;
    }

    public String queryForString(String sql, Map<String, Object> params)
            throws DatabaseException {
        String val = null;
        try {
            SQLQuery sqlQuery = getSessionFactory().getCurrentSession().createSQLQuery(sql);
            if (params != null) {
                sqlQuery.setProperties(params);
            }

            Object obj = sqlQuery.uniqueResult();
            if (obj != null) {
                if (obj instanceof String) {
                    val = ((String) obj);
                } else {
                    val = obj.toString();
                }
            }
        } catch (Exception e) {
            LOGGER.warn(e.getMessage(), e);
            throw new DatabaseException(e);
        }
        return val;
    }

    public List queryForMapList(String sql, Map<String, Object> params, int pageIndex, int pageSize)
            throws DatabaseException {
        SQLQuery sqlQuery = getSessionFactory().getCurrentSession().createSQLQuery(sql);
        sqlQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        if (params != null) {
            sqlQuery.setProperties(params);
        }

        List list = null;

        try {
            if (pageSize > 0 && pageIndex > 0) {
                int startIndex = (pageIndex - 1) * pageSize;
                list = sqlQuery.setFirstResult(startIndex).setMaxResults(pageSize).list();
            } else {
                list = sqlQuery.list();
            }
        } catch (HibernateException he) {
            LOGGER.warn(he.getMessage(), he);
            throw new DatabaseException(he);
        }
        return list;
    }

    /**
     * 不分页查询数据。List元素为查询结果别名为键的Map
     *
     * @param sql    查询的SQL语句，支持:key格式对参数进行命令
     * @param params 参数Map，键为SQL语句中命令的参数
     * @return
     * @throws DatabaseException
     */
    public List query(String sql, Map<String, Object> params) throws DatabaseException {
        return queryForMapList(sql, params, 0, 0);
    }

    /**
     * 分页查询数据。List元素为查询结果别名为键的Map
     *
     * @param sql       查询的SQL语句，支持:key格式对参数进行命令
     * @param params    参数Map，键为SQL语句中命令的参数
     * @param pageIndex 分页页码
     * @param pageSize  分页大小
     * @return
     * @throws DatabaseException
     */
    public PageMaker query(String sql, Map<String, Object> params, int pageIndex, int pageSize)
            throws DatabaseException {
        String countSql = "select count(1) from (".concat(sql).concat(") count_temp");
        int rowCount = queryForInt(countSql, params);

        return query(sql, params, pageIndex, pageSize, rowCount);
    }

    public PageMaker query(String sql, Map<String, Object> params, int pageIndex, int pageSize, long rowCount)
            throws DatabaseException {
        PageMaker pageMaker = new PageMaker(pageIndex, pageSize, rowCount);
        pageMaker.setList(queryForMapList(sql, params, pageMaker.getPageIndex(), pageMaker.getPageSize()));

        return pageMaker;
    }

    /**
     * 分页查询数据。List元素为查询结果别名为键的Map
     *
     * @param sql       查询的SQL语句，支持:key格式对参数进行命令
     * @param params    参数Map，键为SQL语句中命令的参数
     * @param pageIndex 分页页码
     * @param pageSize  分页大小
     * @return
     * @throws DatabaseException
     */
    public PageMaker query(Class clazz, String sql, Map<String, Object> params, int pageIndex, int pageSize)
            throws DatabaseException {
        String countSql = "select count(1) from (".concat(sql).concat(") count_temp");
        int rowCount = queryForInt(countSql, params);

        return query(clazz, sql, params, pageIndex, pageSize, rowCount);
    }

    public PageMaker query(Class clazz, String sql, Map<String, Object> params, int pageIndex, int pageSize, long rowCount)
            throws DatabaseException {
        PageMaker pageMaker = new PageMaker(pageIndex, pageSize, rowCount);
        pageMaker.setList(queryForBeanList(clazz, sql, params, pageIndex, pageSize));
        return pageMaker;
    }

    public <T> List<T> queryForBeanList(Class<T> clazz, String sql, Map<String, Object> params, int pageIndex, int pageSize) {
        SQLQuery sqlQuery = getSessionFactory().getCurrentSession().createSQLQuery(sql);
        sqlQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        if (params != null) {
            sqlQuery.setProperties(params);
        }

        List list = null;

        List<T> entityList = new ArrayList<T>();

        try {
            if (pageSize > 0 && pageIndex > 0) {
                int startIndex = (pageIndex - 1) * pageSize;
                list = sqlQuery.setFirstResult(startIndex).setMaxResults(pageSize).list();
            } else {
                list = sqlQuery.list();
            }
        } catch (HibernateException he) {
            LOGGER.warn(he.getMessage(), he);
            throw new DatabaseException(he);
        }

        Method[] methods = clazz.getMethods();
        Map map = null;
        String fieldName = null;
        String methodName = null;

        Object[] objParam = new Object[1];
        Object objValue = null;

        T entity = null;

        for (int i = 0; i < list.size(); i++) {
            map = (Map) list.get(i);

            // 构造clazz
            try {
                entity = (T) clazz.newInstance();
            } catch (Exception e) {
                // 无法构造相应类的实例，返回null
                return null;
            }

            // 循环字段与类方法
            for (Object key : map.keySet()) {
                fieldName = key.toString();
                fieldName = fieldName.replace("_", "");

                objValue = map.get(key);
                if (Strings.isEmpty(objValue)) {
                    continue;
                }
                for (Method method : methods) {
                    methodName = "set".concat(fieldName);
                    if (method.getName().equalsIgnoreCase(methodName)) {
                        try {
                            objParam[0] = getValue(method, objValue);
                            method.invoke(entity, objParam);
                        } catch (IllegalAccessException e) {
                            LOGGER.info("method.getName() :" + method.getName());
                            LOGGER.warn(e.getMessage(), e);
                        } catch (IllegalArgumentException e) {
                            LOGGER.info("method.getName() :" + method.getName());
                            LOGGER.warn(e.getMessage(), e);
                        } catch (InvocationTargetException e) {
                            LOGGER.info("method.getName() :" + method.getName());
                            LOGGER.warn(e.getMessage(), e);
                        }
                        break;
                    }
                }
            }

            entityList.add(entity);
        }

        return entityList;
    }

    public List queryForEntityList(Class clazz, String sql, Map<String, Object> params, int pageIndex, int pageSize) {
        SQLQuery sqlQuery = getSessionFactory().getCurrentSession().createSQLQuery(sql);
        sqlQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        if (params != null) {
            sqlQuery.setProperties(params);
        }

        List list = null;

        List entityList = new ArrayList();

        try {
            if (pageSize > 0 && pageIndex > 0) {
                int startIndex = (pageIndex - 1) * pageSize;
                list = sqlQuery.setFirstResult(startIndex).setMaxResults(pageSize).list();
            } else {
                list = sqlQuery.list();
            }
        } catch (HibernateException he) {
            LOGGER.warn(he.getMessage(), he);
            throw new DatabaseException(he);
        }

        Method[] methods = clazz.getMethods();
        Map map = null;
        String fieldName = null;
        String methodName = null;

        Object[] objParam = new Object[1];
        Object objValue = null;

        Object entity = null;

        for (int i = 0; i < list.size(); i++) {
            map = (Map) list.get(i);

            // 构造clazz
            try {
                entity = clazz.newInstance();
            } catch (Exception e) {
                // 无法构造相应类的实例，返回null
                return null;
            }

            // 循环字段与类方法
            for (Object key : map.keySet()) {
                fieldName = key.toString();
                fieldName = fieldName.replace("_", "");

                objValue = map.get(key);
                if (Strings.isEmpty(objValue)) {
                    continue;
                }
                for (Method method : methods) {
                    methodName = "set".concat(fieldName);
                    if (method.getName().equalsIgnoreCase(methodName)) {
                        try {
                            objParam[0] = getValue(method, objValue);
                            method.invoke(entity, objParam);
                        } catch (IllegalAccessException e) {
                            LOGGER.warn(e.getMessage(), e);
                        } catch (IllegalArgumentException e) {
                            LOGGER.warn(e.getMessage(), e);
                        } catch (InvocationTargetException e) {
                            LOGGER.warn(e.getMessage(), e);
                        }
                        break;
                    }
                }
            }

            entityList.add(entity);
        }

        return entityList;
    }


    private static final String INSERT_TEMPLATE = "INSERT INTO {tableName} ({fields})VALUES ({fieldsValue})";

    private static final String LAST_INSERT_ID = "SELECT last_insert_id()";

    /**
     * 向表 ｛tableName｝ 插入实体 ｛autoEntity｝ 并 在 autoEntity 中塞入 数据库中的结果
     *
     * @param tableName
     * @param autoEntity
     * @throws DatabaseException
     */
    public void insert(String tableName, Object autoEntity) throws DatabaseException {
        Field[] fields = autoEntity.getClass().getDeclaredFields();
        StringBuffer fieldStr = new StringBuffer();
        StringBuffer fieldValueStr = new StringBuffer();
        Map params = new HashMap();
        Object entityIdValue = null;
        String idName = "";
        for (Field f : fields) {
            //获取字段中包含fieldMeta的注解
            Column column = f.getAnnotation(Column.class);
            Id id = f.getAnnotation(Id.class);
            String fName = f.getName();
            try {
                f.setAccessible(true);
                if (column != null && id == null && f.get(autoEntity) != null) {
                    fieldStr.append(column.name()).append(",");
                    fieldValueStr.append(" :").append(fName).append(" ,");
                    params.put(fName, f.get(autoEntity));
                }
                if (id != null) {
                    if (f.get(autoEntity) != null) {
                        entityIdValue = f.get(autoEntity);
                        fieldStr.append(column.name()).append(",");
                        fieldValueStr.append(" :").append(fName).append(" ,");
                        params.put(fName, f.get(autoEntity));
                    }
                    idName = fName;
                }
            } catch (IllegalAccessException e) {
                LOGGER.warn(e.getMessage(), e);
            }
        }
        fieldStr.setLength(fieldStr.length() - 1);
        fieldValueStr.setLength(fieldValueStr.length() - 1);
        String sql = INSERT_TEMPLATE.replace("{tableName}", tableName).replace("{fields}", fieldStr.toString()).replace("{fieldsValue}", fieldValueStr.toString());
        SQLQuery sqlQuery = getSessionFactory().getCurrentSession().createSQLQuery(sql);
        sqlQuery.setProperties(params);
        //插入
        sqlQuery.executeUpdate();
        //获取主键
        if (Strings.isNotEmpty(idName) && entityIdValue == null) {
            SQLQuery sqlQuery2 = getSessionFactory().getCurrentSession().createSQLQuery(LAST_INSERT_ID);
            Object object = sqlQuery2.uniqueResult();

            Long idValue = null;

            if (object instanceof BigInteger) {
                idValue = ((BigInteger) object).longValue();
            } else if (object instanceof BigDecimal) {
                idValue = ((BigDecimal) object).longValue();
            } else if (object instanceof Integer) {
                idValue = ((Integer) object).longValue();
            }
            if (null != idValue) {
                ObjectUtils.objectConcat(autoEntity, load(tableName, autoEntity.getClass(), idValue));
            }
        }
    }

    private static final String SELECT_TEMPLATE = "SELECT {fields} FROM {tableName} WHERE {Id} = :id";


    private static final String INSERT_NOT_EXISTS_TEMPLATE = "INSERT INTO {tableName} \n" +
            "({fieldNames}) \n" +
            "SELECT {fieldValues} \n" +
            "FROM dual \n" +
            "WHERE not exists (select * from {tableName} \n" +
            "where {idName} = {idValue} limit 1)";

    public int insertNotExists(Object autoEntity) throws DatabaseException {
        String tableName = null;
        Table table = autoEntity.getClass().getAnnotation(Table.class);
        if (table != null) {
            tableName = table.name();
        }
        Field[] fields = autoEntity.getClass().getDeclaredFields();
        StringBuffer fieldStr = new StringBuffer();
        StringBuffer fieldValueStr = new StringBuffer();
        Map params = new HashMap();
        Object entityIdValue = null;
        String idName = "";
        String idValue = "";
        for (Field f : fields) {
            //获取字段中包含fieldMeta的注解
            Column column = f.getAnnotation(Column.class);
            Id id = f.getAnnotation(Id.class);
            String fName = f.getName();
            try {
                f.setAccessible(true);
                if (column != null && id == null && f.get(autoEntity) != null) {
                    fieldStr.append(column.name()).append(",");
                    fieldValueStr.append(" :").append(fName).append(" ,");
                    params.put(fName, f.get(autoEntity));
                }
                if (id != null) {
                    if (f.get(autoEntity) != null) {
                        entityIdValue = f.get(autoEntity);
                        fieldStr.append(column.name()).append(",");
                        fieldValueStr.append(" :").append(fName).append(" ,");
                        params.put(fName, f.get(autoEntity));
                    }
                    idName = column.name();
                    idValue = ":" + fName;
                }
            } catch (IllegalAccessException e) {
                LOGGER.warn(e.getMessage(), e);
            }
        }
        fieldStr.setLength(fieldStr.length() - 1);
        fieldValueStr.setLength(fieldValueStr.length() - 1);
        String sql = INSERT_NOT_EXISTS_TEMPLATE.replace("{tableName}", tableName)
                .replace("{fieldNames}", fieldStr.toString())
                .replace("{fieldValues}", fieldValueStr.toString())
                .replace("{idName}", idName)
                .replace("{idValue}", idValue);
        SQLQuery sqlQuery = getSessionFactory().getCurrentSession().createSQLQuery(sql);
        sqlQuery.setProperties(params);
        //插入
        return sqlQuery.executeUpdate();
    }

    public int insertNotExists(String tableName, Object autoEntity) throws DatabaseException {
        Table table = autoEntity.getClass().getAnnotation(Table.class);
        if (tableName == null && table != null) {
            tableName = table.name();
        }
        Field[] fields = autoEntity.getClass().getDeclaredFields();
        StringBuffer fieldStr = new StringBuffer();
        StringBuffer fieldValueStr = new StringBuffer();
        Map params = new HashMap();
        Object entityIdValue = null;
        String idName = "";
        String idValue = "";
        for (Field f : fields) {
            //获取字段中包含fieldMeta的注解
            Column column = f.getAnnotation(Column.class);
            Id id = f.getAnnotation(Id.class);
            String fName = f.getName();
            try {
                f.setAccessible(true);
                if (column != null && id == null && f.get(autoEntity) != null) {
                    fieldStr.append(column.name()).append(",");
                    fieldValueStr.append(" :").append(fName).append(" ,");
                    params.put(fName, f.get(autoEntity));
                }
                if (id != null) {
                    if (f.get(autoEntity) != null) {
                        entityIdValue = f.get(autoEntity);
                        fieldStr.append(column.name()).append(",");
                        fieldValueStr.append(" :").append(fName).append(" ,");
                        params.put(fName, f.get(autoEntity));
                    }
                    idName = column.name();
                    idValue = ":" + fName;
                }
            } catch (IllegalAccessException e) {
                LOGGER.warn(e.getMessage(), e);
            }
        }
        fieldStr.setLength(fieldStr.length() - 1);
        fieldValueStr.setLength(fieldValueStr.length() - 1);
        String sql = INSERT_NOT_EXISTS_TEMPLATE.replace("{tableName}", tableName)
                .replace("{fieldNames}", fieldStr.toString())
                .replace("{fieldValues}", fieldValueStr.toString())
                .replace("{idName}", idName)
                .replace("{idValue}", idValue);
        SQLQuery sqlQuery = getSessionFactory().getCurrentSession().createSQLQuery(sql);
        sqlQuery.setProperties(params);
        //插入
        return sqlQuery.executeUpdate();
    }

    /**
     * 从表 ｛tableName｝ 中 查出 ｛clazz｝ 实体
     *
     * @param tableName
     * @param clazz
     * @param idValue
     * @param <T>
     * @return
     */
    protected <T> T load(String tableName, Class<T> clazz, Serializable idValue) {
        StringBuffer fieldAllStr = new StringBuffer();
        Field[] fields = clazz.getDeclaredFields();
        String idName = "";
        for (Field f : fields) {
            //获取字段中包含fieldMeta的注解
            Column column = f.getAnnotation(Column.class);
            Id id = f.getAnnotation(Id.class);
            String fName = f.getName();
            f.setAccessible(true);
            if (column != null) {
                fieldAllStr.append(column.name()).append(",");
                if (id != null) {
                    idName = column.name();
                }
            }
        }
        fieldAllStr.setLength(fieldAllStr.length() - 1);
        String selectStr = SELECT_TEMPLATE
                .replace("{tableName}", tableName)
                .replace("{fields}", fieldAllStr.toString())
                .replace("{Id}", idName);
        SQLQuery sqlQuery3 = getSessionFactory().getCurrentSession().createSQLQuery(selectStr);
        sqlQuery3.setParameter(new String("id"), idValue);
        sqlQuery3.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List list = sqlQuery3.list();
        T entity = null;
        // 构造clazz
        try {
            entity = clazz.newInstance();
        } catch (Exception e) {
            // 无法构造相应类的实例，返回null
            return null;
        }
        Method[] methods = clazz.getMethods();
        List<Method> methodList = ObjectUtils.filterSetMethods(methods);
        Map map = null;
        String fieldName = null;
        String methodName = null;

        Object[] objParam = new Object[1];
        Object objValue = null;

        map = (Map) list.get(0);

        // 循环字段与类方法
        Iterator iterator;
        for (Object key : map.keySet()) {
            fieldName = key.toString();
            fieldName = fieldName.replace("_", "");

            objValue = map.get(key);
            if (Strings.isEmpty(objValue)) {
                continue;
            }
            iterator = methodList.iterator();
            while (iterator.hasNext()) {
                Method method = (Method) iterator.next();
                methodName = "set".concat(fieldName);
                if (method.getName().equalsIgnoreCase(methodName)) {
                    try {
                        objParam[0] = getValue(method, objValue);
                        method.invoke(entity, objParam);
                    } catch (IllegalAccessException e) {
                        LOGGER.warn(e.getMessage(), e);
                    } catch (IllegalArgumentException e) {
                        LOGGER.warn(e.getMessage(), e);
                    } catch (InvocationTargetException e) {
                        LOGGER.warn(e.getMessage(), e);
                    }
                    iterator.remove();
                    break;
                }
            }
        }
        return (T) entity;
    }

    private static final String UPDATE_TEMPLATE = "UPDATE {tableName} SET {fields} WHERE {ids}";

    public void update(String _tableName, Object entity) {
        String tableName = null;
        Table table = entity.getClass().getAnnotation(Table.class);
        if (table != null) {
            tableName = table.name();
        }
        if (Strings.isNotEmpty(_tableName)) {
            tableName = _tableName;
        }
        if (tableName == null) {
            return;
        }
        Field[] declaredFields = entity.getClass().getDeclaredFields();
        StringBuffer fields = new StringBuffer();
        StringBuffer idStr = new StringBuffer();
        Map params = new HashMap();
        Object fValue;
        for (Field f : declaredFields) {
            //获取字段中包含fieldMeta的注解
            Column column = f.getAnnotation(Column.class);
            Id id = f.getAnnotation(Id.class);
            String fName = f.getName();
            f.setAccessible(true);
            try {
                fValue = f.get(entity);
                if (column != null && fValue != null) {
                    if (id != null) {
                        idStr.append(column.name()).append("= :").append(fName).append(",");
                    } else {
                        fields.append(column.name()).append("= :").append(fName).append(",");
                    }
                    params.put(fName, fValue);
                }
            } catch (IllegalAccessException e) {
                LOGGER.warn(e.getMessage(), e);
            }
        }
        if (idStr.length() > 0) {
            idStr.setLength(idStr.length() - 1);
        } else {
            return;
        }
        if (fields.length() > 0) {
            fields.setLength(fields.length() - 1);
        } else {
            return;
        }

        String sql = UPDATE_TEMPLATE.replace("{tableName}", tableName)
                .replace("{fields}", fields.toString())
                .replace("{ids}", idStr.toString());
        exec(sql, params);
    }

    public void updateEntity(String _tableName, Object entity) {
        String tableName = null;
        Table table = entity.getClass().getAnnotation(Table.class);
        if (table != null) {
            tableName = table.name();
        }
        if (Strings.isNotEmpty(_tableName)) {
            tableName = _tableName;
        }
        if (tableName == null) {
            return;
        }
        Method[] declaredMethods = entity.getClass().getDeclaredMethods();
        StringBuffer fields = new StringBuffer();
        StringBuffer idStr = new StringBuffer();
        Map params = new HashMap();
        Object fValue = null;
        for (Method m : declaredMethods) {
            //获取字段中包含fieldMeta的注解
            Column column = m.getAnnotation(Column.class);
            Id id = m.getAnnotation(Id.class);
            m.setAccessible(true);
            try {

                if (m.getName().startsWith("get")) {
                    fValue = m.invoke(entity);
                }
                if (column != null && fValue != null) {
                    if (id != null) {
                        idStr.append(column.name()).append("= :").append(column.name()).append(",");
                    } else {
                        fields.append(column.name()).append("= :").append(column.name()).append(",");
                    }
                    params.put(column.name(), fValue);
                }
            } catch (Exception e) {
                LOGGER.warn(e.getMessage(), e);
            }
        }
        if (idStr.length() > 0) {
            idStr.setLength(idStr.length() - 1);
        } else {
            return;
        }
        if (fields.length() > 0) {
            fields.setLength(fields.length() - 1);
        } else {
            return;
        }
        String sql = UPDATE_TEMPLATE.replace("{tableName}", tableName)
                .replace("{fields}", fields.toString())
                .replace("{ids}", idStr.toString());
        exec(sql, params);
    }

    public void commit() {
        this.getSessionFactory().getCurrentSession().getTransaction().commit();
    }

    private Object getValue(Method method, Object objValue) {
        Object o = null;
        if (objValue instanceof BigInteger) {
            if (method.getParameterTypes()[0] == Long.class) {
                o = ((BigInteger) objValue).longValue();
            } else if (method.getParameterTypes()[0] == Integer.class) {
                o = ((BigInteger) objValue).intValue();
            }
        } else if (objValue instanceof BigDecimal) {
            if (method.getParameterTypes()[0] == Long.class) {
                o = ((BigDecimal) objValue).longValue();
            } else if (method.getParameterTypes()[0] == Integer.class) {
                o = ((BigDecimal) objValue).intValue();
            } else if (method.getParameterTypes()[0] == Double.class) {
                o = ((BigDecimal) objValue).doubleValue();
            }
        } else if (objValue instanceof Long) {
            if (method.getParameterTypes()[0] == Integer.class) {
                o = ((Long) objValue).intValue();
            } else {
                o = objValue;
            }
        } else if (objValue instanceof Integer) {
            if (method.getParameterTypes()[0] == Long.class) {
                o = ((Integer) objValue).longValue();
            } else {
                o = objValue;
            }
        } else {
            o = objValue;
        }

        return o;
    }
}
