package cn.service.orm.sqltoy;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.constant.CommonConst;
import cn.orm.abs.ISqlToyDao;
import cn.orm.sqltoy.config.model.EntityMeta;
import cn.orm.sqltoy.dao.impl.SqlToyLazyDaoImpl;
import cn.orm.sqltoy.exception.DataAccessException;
import cn.orm.sqltoy.model.EntityQuery;
import cn.orm.sqltoy.model.EntityUpdate;
import cn.orm.sqltoy.model.Page;
import cn.orm.sqltoy.plus.Wrapper;
import cn.orm.sqltoy.plus.toolkit.ColumnUtils;
import cn.orm.sqltoy.utils.StringUtil;
import cn.orm.util.builder.BuildSQL;
import cn.orm.util.builder.BuildWhere;
import cn.orm.util.builder.base.SQLDelete;
import cn.service.orm.sqlsam.SqlToySamDao;
import cn.util.core.IsKit;
import cn.util.core.TypeKit;
import cn.util.string.JsonKit;
import cn.util.string.NamingKit;
import cn.util.string.StringKit;

@Service
public class SqlToyDaoImpl extends SqlToyLazyDaoImpl implements ISqlToyDao
{
	/////////////////////////////////
	/**确保结果与给定的检索字段的次序一致*/
    /////////////////////////////////
	/**查询条件whereMap*/
	@Override
	public List<Map<String, Object>> getList_order(String tableName,String item,Map<String, Object> whereMap){
		String sql = BuildSQL.queryByItem(tableName,item,whereMap);
		return TypeKit.cast(super.findBySql(sql,null,null,LinkedHashMap.class));
	}
	@Override
	public List<Map<String, Object>> getList_order(String tableName,String item,Map<String, Object> whereMap,String rangeField)
	{
		String sql = BuildSQL.queryByItem(tableName,item,whereMap,rangeField);
		return TypeKit.cast(super.findBySql(sql,null,LinkedHashMap.class));
	}
	/**查询条件criteria的格式：格式："键|值,键|值"*/
	@Override
	public List<Map<String, Object>> getList_order(String tableName,String item,String criteria)
	{
		String sql = BuildSQL.queryByItem(tableName,item,criteria);
		return TypeKit.cast(super.findBySql(sql,null,null,LinkedHashMap.class));
	}
	@Override
	public List<Map<String, Object>> getListBySql_order(String sql){
		return TypeKit.cast(super.findBySql(sql,null,LinkedHashMap.class));
	}
	@Override
	public List<Map<String, Object>> getListBySql_order(String sql,Map<String, Object> paramsMap){
		return TypeKit.cast(super.findBySql(sql,paramsMap,LinkedHashMap.class));
	}
	
	@Override
	public List<Map<String, Object>> getListByPage_order(String tableName,Map<String, Object> paramMap,String rangeField)
	{
		if(IsKit.isNull(paramMap) || IsKit.isNull(tableName) ) {
			return null;
		}
		String sql = BuildSQL.query(tableName,paramMap,rangeField);
		return TypeKit.cast(super.findBySql(sql,null,LinkedHashMap.class));  
	}

    /////////////////////////////////
	/**查询结果可以转换为某个实体类*/
	/////////////////////////////////
	/**参数paramMap含有分页信息和查询条件信息*/
	@Override
	public List<?> getEntityListBySql(String sqlId,Map<String, Object> paramsMap, Class<?> voClass){
		return super.findBySql(sqlId,paramsMap,voClass);
	}	
	@Override
	public List<?> getEntityList(String sqlId, Class<?> voClass){
		return super.findBySql(sqlId,null,voClass);
	}
	@Override
	public List<?> getEntityList(String tableName, Map<String, Object> paramsMap, Class<?> voClass){
		String sql = BuildSQL.query(tableName,paramsMap);
		return super.findBySql(sql,null,voClass);
	}
	/**获取若干记录size*/
	@Override
	public List<?> getEntityTop(String tableName,Serializable entity,Map<String, Object> whereParam,double size)
	{
		String sql = BuildSQL.query(tableName,whereParam);
		List<?> list = super.findTopBySql(sql,entity,size);
		return list; 		
	}
	
	/**最多一条记录*/
	@Override
	public Map<String,Object> getMapBySql(String sql,Map<String, Object> queryParam){
		List<?> list = super.findBySql(sql,queryParam,Map.class);
		if(IsKit.isNotNullOrEmpty(list)) {
			return TypeKit.cast(list.get(0));	
		}
		return null;
	}
	


	public void xbm() {}
	
	/////////////////////////////////////
	/**数据库分页查询
	 * 此处的参数格式是由前端vue项目确定的。
	 * 页面传来的翻页及查询条件参数paramsMap: 
	 * {
	 *  "pageNo":1,"pageSize":10,"ipaddr":"*11*","userName":"*22*","status":"1",
	 *  "params":{"beginTime":"2022-01-05T16:00:00.000Z","endTime":"2022-02-13T16:00:00.000Z"}
	 * }
	 * 其中：params={}是区间取值参数比如时间；pageNo=1, pageSize=10,外的其他参数也是查询参数
	 * 表中字段不要用：pageSize和pageNo; 或页面用pageNum替换pageNo(页面误用)
	 * *11* 前端用md-input
	 * */
	@Override
	public Page<?> getPage(String tableName,Map<String, Object> pageMap)
	{
		return getPage(tableName,pageMap,"");
	}
	@Override
	public Page<?> getPageBySql(String sqlId,Map<String, Object> pageMap)
	{
		Page<?> page = getPage(pageMap);
		return super.findPageBySql(page,sqlId,null,Map.class);
	}
	
	@Override
	public Page<?> getPage(String tableName,Map<String, Object> pageMap,String rangeField)
	{
		if(IsKit.isNull(pageMap) || IsKit.isNull(tableName)) {
			return null;
		}
		String sql = BuildSQL.query(tableName,pageMap,rangeField);
		System.out.println("paramMapsql:"+sql);
		Page<?> page = getPage(pageMap);
		return super.findPageBySql(page,sql,null,Map.class);
	}

	@Override
	public List<Map<String, Object>> getList(String tableName,String item)
	{
		String sql = BuildSQL.getList(tableName,item);
		List<Map<String, Object>> data = TypeKit.cast(super.findBySql(sql,null,null,Map.class));
		return NamingKit.underlineToCaml(data);
	}

	@Override
	public List<Map<String, Object>> getList(String tableName,Map<String, Object> whereParam){
		String sql = BuildSQL.query(tableName,whereParam);
		return TypeKit.cast(super.findBySql(sql,null,null,Map.class));
	}

	/**最多一条记录*/
	@Override
	public Map<String,Object> getMap(String tableName,Map<String, Object> whereMap){
		String sql = BuildSQL.query(tableName,whereMap);
		List<?> list = super.findBySql(sql,null,null,Map.class);
		if(IsKit.isNotNullOrEmpty(list)) {
			return TypeKit.cast(list.get(0));	
		}
		return null;
	}

	/**最多一条记录, 返回给定的字段item*/
	@Override
	public Map<String,Object> getMap(String tableName,String item,Map<String, Object> whereMap){
		String sql = BuildSQL.queryByItem(tableName,item,whereMap);
		List<?> list = super.findBySql(sql,null,null,Map.class);
		if(IsKit.isNotNullOrEmpty(list)) {
			return TypeKit.cast(list.get(0));	
		}
		return null;
	}
	


	/**仅返回指定字段的值*/
	@Override
	public List<Map<String, Object>> getListBySql_w(String sql,Map<String, Object> queryParam){
		return TypeKit.cast(super.findBySql(sql,queryParam,null));
	}

	@Override
	public List<Map<String, Object>> getListBySql(String sql){
		return getListBySql(sql,null);
	}
	@Override
	public List<Map<String, Object>> getListBySql(String sql,Map<String, Object> queryParam){
		return TypeKit.cast(super.findBySql(sql,queryParam,Map.class));
	}
	@Override
	public List<Map<String, Object>> getList_or(String tableName,Map<String, Object> whereParam){
		String sql = BuildSQL.query_or(tableName,whereParam);
		return TypeKit.cast(super.findBySql(sql,null,null,null));
	}

	/**条件参数paramMap: 
	 * {
	 *  "ipaddr":"*11*","userName":"*22*","status":"1",
	 *  "params":{"beginTime":"2022-01-05T16:00:00.000Z","endTime":"2022-02-13T16:00:00.000Z"}
	 * }
	 * 其中：params={}是区间取值参数比如时间；rangeField对应的表中字段，默认为beginTime和endTime
	 */
	@Override
	public List<Map<String, Object>> getListByPage(String tableName,Map<String, Object> paramMap,String rangeField)
	{
		if(IsKit.isNull(paramMap) || IsKit.isNull(tableName) ) {
			return null;
		}
		String sql = BuildSQL.query(tableName,paramMap,rangeField);
		return TypeKit.cast(super.findBySql(sql,null,Map.class));  
	}
	@Override
	public List<Map<String, Object>> getList(String tableName)
	{
		return getList(tableName,"");
	}
	/**功能同上findByTable(String tableName,String item)，
	 * rField字段为保证不重复的字段；where为查询条件*/
	@Override
	public List<Map<String, Object>> getList(String tableName,String item,String rField,String where)
	{
		String sql = BuildSQL.queryByWhere(tableName,item,rField,where);
		return TypeKit.cast(super.findBySql(sql,null,null,Map.class));
	}

	/**某个字段field等于List中不同值(或关系)*/
	@Override
	public List<Map<String, Object>> getList(String tableName,String field,List<?> paramList)
	{
		String sql = BuildSQL.sql_query(tableName,field,paramList);
		return TypeKit.cast(super.findBySql(sql,null,null,Map.class));
	}
	@Override
	public List<Map<String, Object>> getList(String tableName,String item,Map<String, Object> criteria)
	{
		String sql = BuildSQL.queryByItem(tableName,item,criteria);
		return TypeKit.cast(super.findBySql(sql,null,null,Map.class));
	}
	/**仅返回所给出的字段查询语句
	 * findBySql(sql,null,null,null); 只有数据  没有字段名
	 * findBySql(sql,null,null,Map.class);返回类型：List<Map>
	 * */
	@Override
	public List<Map<String, Object>> getList(String tableName,String item,String criteria)
	{
		String sql = BuildSQL.queryByItem(tableName,item,criteria);
		return TypeKit.cast(super.findBySql(sql,null,null,Map.class));
	}

	/*将满足条件的某个字段field以","拼接字符串作为结果返回*/ 
	@Override
	public Map<String, Object> getFieldByGroup(String tableName,String field,Map<String, Object> criteria)
	{
		String sql = BuildSQL.getFieldByGroup(tableName,field,criteria);
		List<?> result = super.findBySql(sql,null,null,Map.class);
		if(IsKit.isNotNullOrEmpty(result)) {
			return TypeKit.cast(result.get(0));
		}
		return null;
	}
	
	/**单表：批量删除 默认单一主键uuid*/
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean delBatch(String tableName, List<String> idList)
	{
		String sql = null;
		if (IsKit.isNotNullOrEmpty(idList)) {
			sql = BuildSQL.delete(tableName,CommonConst.DEFAULT_PRIMARY_KEY,idList);
		}
		if(IsKit.isNotNull(sql)) {
			return super.executeSql(sql) > 0;
		}
		else
			return false;
	}
	/**删除一条记录 默认单一主键uuid*/
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean delById(String tableName,String id) {
		String sql = BuildSQL.delete(tableName,CommonConst.DEFAULT_PRIMARY_KEY,id);
		return super.executeSql(sql) > 0;
	}

	/**单库：删除一条记录 删除条件whereParam*/
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean delById(String tableName,Map<String, Object> whereParam) {
		String sql = BuildSQL.delete(tableName,whereParam);
		return super.executeSql(sql) > 0;
	}

	/**单表：先删除满足条件的记录，然后进行插入 */
	@Transactional(rollbackFor = Exception.class)
	@Override 
	public Boolean delInsert(String tableName, Map<String,Object> jsonArray) 
	{
		//避免全删
		if(IsKit.isNullOrEmpty(tableName) || IsKit.isNullOrEmpty(jsonArray)){
			return false;
		}
		//处理删除操作
		Map<String,Object> whereMap = JsonKit.json2Map_jackson(TypeKit.objToStr(jsonArray.get("where")));
		String sql = BuildSQL.delete(tableName,whereMap);
		int num = 0;
		if(super.executeSql(sql) > 0) {
			++num;
		}

		//处理插入操作
		List<Map<String,Object>> paramList = new ArrayList<Map<String,Object>>();
		String jsonListStr = TypeKit.objToStr(jsonArray.get("data"));
		paramList = JsonKit.json2List_gson(jsonListStr);
		sql = BuildSQL.BatchInsert(tableName,paramList);
		return super.executeSql(sql) > 0 && num >= 0;
	} 

	/**多表: 批量删除记录 删除条件keyParam一样*/
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean delBatch_where(String tableName,Map<String, Object> keyParam) 
	{   
		//避免全删keyParam
		if(IsKit.isNullOrEmpty(tableName) || IsKit.isNullOrEmpty(keyParam)){
			return false;
		}
		//构造查询条件
		String where = BuildWhere.genQueryWrapper(keyParam);
		if(IsKit.isNull(where)){
			return false;
		}
		String[] tableNames = tableName.split(",");
		String sql = "";
		Integer num = -1;
		for (int i = 0; i <tableNames.length; i++){
			sql = new SQLDelete().fromTable(tableNames[i]).where(where).create();
			if(super.executeSql(sql) > 0) {
				++num;
			}
		}
		return num >= 0;
	}

	/**删除满足条件的所有记录； 即供单一主键对象的批量删除*/
	@Override
	public Boolean deleteByBean(Class<?> tablePojo,Object[] values) 
	{
		return (super.deleteByIds(tablePojo,values) > 0);
	}

	/**删除满足条件的所有记录； 即供单一主键对象的批量删除*/
	@Override
	public Boolean delByIds(String tableName,String field,Object[] values) 
	{
		int num = 0;
		String [] val = StringKit.objArrayToStrArray(values);
		String sql = BuildSQL.delete(tableName,field,val);
		if(super.executeSql(sql) > 0) {
			num++;
		}
		return (num > 0);
	}
	
	/**删除所有记录*/
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean removeAll(String tableName) {
		String sql = BuildSQL.removeAll(tableName);
		return super.executeSql(sql) > 0;
	}

	/**对单个对象的某个属性进行更新，属性值位空的不进行更新*/
	@Override
	public Boolean updateFieldByBean(Class<?> entityClass,Map<String,Object> updateMap,Map<String,Object> whereMap){
		EntityUpdate entityUpdate = BuildWhere.updateWrapper(updateMap,whereMap);
		return super.updateByQuery(entityClass,entityUpdate) > 0;
	}

	/**单表：批量更新 页面给定条件 keyParam条件字段：主键|取值 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean updateBatch_where(String tableName,String keyParam,Map<String,Object> setMap)
	{
		String sql = BuildSQL.update(tableName,setMap,keyParam);
		return super.executeSql(sql) >= 0;
	}

	/**单表：批量更新 单一主键uuid */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean updateBatch(String tableName,List<String> idList,Map<String,Object> setMap)
	{
		Map<String,Object> whereMap = new HashMap<>();
		whereMap.put(CommonConst.DEFAULT_PRIMARY_KEY,"FUNIN("+ TypeKit.listToStr(idList)+")");
		//UPDATE t_sys_post SET delFlag = "1" WHERE (id >='IN('1'')  AND (id <=''2')')
		String sql = BuildSQL.update(tableName,setMap, whereMap);
		return super.executeSql(sql) >= 0;
	}	

	/**单表：更新一条记录 默认单一主键uuid */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean update(String tableName,String keyValue,Map<String,Object> setMap)
	{
		Map<String,Object> whereMap = new HashMap<>();
		whereMap.put(CommonConst.DEFAULT_PRIMARY_KEY, keyValue);
		String sql = BuildSQL.update(tableName,setMap,whereMap);
		return super.executeSql(sql) >= 0;
	}	

	/**单表：更新一条记录*/
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean update(String tableName, Map<String, Object> mapRecord) 
	{
		String sql = BuildSQL.update(tableName,mapRecord);
		System.out.println("1:"+sql);
		return super.executeSql(sql) >= 0;
	} 

	/**插入一条新记录*/
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean insert(String tableName, Map<String, Object> mapRecord) 
	{
		String sql = BuildSQL.insert(tableName,mapRecord);
		return super.executeSql(sql) > 0;
	}

	/**插入一条新记录 genKey:true系统自动产生主键*/
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean insert(String tableName, Map<String, Object> mapRecord,Boolean genKey) 
	{
		String sql = BuildSQL.insert(tableName,mapRecord,genKey);
		return super.executeSql(sql) > 0;
	}

	
	/**返回满足条件记录数：参数paramsMap不含有区间条件*/
	@Override
	public Long getRecordNum(String tableName,Map<String, Object> paramsMap) {
		String sql = BuildSQL.getRecordNum(tableName,paramsMap);
		return super.getCount(sql,null);
	}

	/**查询是否存在满足查询条件的；最多一条记录：参数paramsMap不含有区间条件*/
	@Override
	public Boolean ifExistRecord(String tableName,Map<String, Object> paramsMap) {
		String sql = BuildSQL.queryOne(tableName,paramsMap);
		return super.getCount(sql,null) > 0;
	}

	/**辅助方法*/
	@Override
	public Page<?> getPage(Integer pageNo,Integer pageSize)
	{
		int size = 10;
		if(IsKit.isNotNull(pageSize) && pageSize > 0) {
			size = pageSize;
		}
		long num = 1l;
		if(IsKit.isNotNull(pageNo) && pageNo > 0) {
			num = pageNo;
		}
		return new Page<>(size,num);
	}
	@Override
	public Page<?> getPage(Map<String, Object> pageMap)
	{
		if(IsKit.isNull(pageMap)) {
			return new Page<>(10,1);
		}
		int pageSize =  0;
		Object obj = pageMap.get("pageSize");
		if(IsKit.isNotNullOrEmpty(obj)) {
			pageSize = TypeKit.objToInt(obj);
			pageMap.remove("pageSize");
		}

		long pageNo = 1l;
		Object value = pageMap.get("pageNo");
		if(IsKit.isNullOrEmpty(value)) {
			value = pageMap.get("pageNum");
			if(IsKit.isNotNullOrEmpty(value)){
				pageNo =TypeKit.objToLong(value);
			}
			else {
				pageMap.remove("pageNum");
			}
		}
		else{
			pageMap.remove("pageNo");
			pageNo =TypeKit.objToLong(value);
		}
		return new Page<>(pageSize,pageNo);
	}


	/**如下方法为移植SqlSam部分方法*/
	/**	
	 * 批量写数据到数据库。语句逐条执行executeBatch
	 * String[] b1 = list.toArray(new String[1]); //这里的参数只为指定返回类型，所以与数组的大小无关
	 * Object[] b2 = list.toArray(); //如果不指定的话，只能以Object[]来接收
	 */
	@Override
	public int executeBatch(ArrayList<String> list)
	{
		if(IsKit.isNullOrEmpty(list)) {
			return -1;
		}
		//String[] arrString = list.toArray(new String[list.size()]);
		return executeBatch(list.stream().toArray(String[]::new));
	}

	@Override
	public int executeBatch(String[] sql) 
	{
		return sqlToySamDao.executeBatch(sql);
	}
	//插入记录一条,并返回id -1表示插入失败
	@Override
	public int insertAndGenIndex(String tableName, Map<String, Object> mapRecord)
	{
		return sqlToySamDao.insertAndGenIndex( tableName,mapRecord);		
	}
	/**批量删除多表的记录 主键keyParam*/
	@Override
	public Boolean delBatch(String tableName,Map<String, Object> keyParam) 
	{
		ArrayList<String> sqlList = new ArrayList<String>();
		if (IsKit.isNotNullOrEmpty(keyParam)) {
			sqlList = BuildSQL.deletes(tableName,keyParam);
		}
		int result = 0;
		if(IsKit.isNotNullOrEmpty(sqlList)) {
			result = this.executeBatch(sqlList);
		}
		return result >= 0;
	}

	@Autowired
	private SqlToySamDao sqlToySamDao;
	/**如上方法为移植SqlSam部分方法*/	
	
	/////////////////////////////////
	/**如下方法为SqlToyHelperDaoImpl对应方法*/
	/////////////////////////////////
	/**
     * 查询一条记录,如果出现多条记录,获取其中第一条记录
     *
     * @param wrapper
     * @return
     */
    public <T> T findOne(Wrapper<T> wrapper) {
        List<T> rs = findList(wrapper);
        if (rs == null || rs.isEmpty()) {
            return null;
        }
        return rs.get(0);
    }

    /**
     * 根据查询条件查询, 仅支持单表条件
     *
     * @param wrapper - 查询条件
     * @return 结果集
     */
    public <T> List<T> findList(Wrapper<T> wrapper) {
        return super.findEntity(wrapper.entityClass(), getEntityQuery(wrapper));
    }

    /**
     * 根据查询条件分页查询, 仅支持单表条件
     *
     * @param wrapper - 查询条件
     * @param page    - 分页条件
     * @param <T>
     * @return
     */
    public <T> Page<T> findPage(Wrapper<T> wrapper, Page<?> page) {
        return super.findPageEntity(page, wrapper.entityClass(), getEntityQuery(wrapper));
    }

    /**
     * 删除
     *
     * @param wrapper - 删除条件
     * @param <T>
     */
    public <T> long delete(Wrapper<T> wrapper) {
        return super.deleteByQuery(wrapper.entityClass(), getEntityQuery(wrapper));
    }

    /**
     * 统计
     *
     * @param wrapper - 统计条件
     * @param <T>
     */
    public <T> long count(Wrapper<T> wrapper) {
        return super.getCount(wrapper.entityClass(), getEntityQuery(wrapper));
    }

    /**
     * 更新
     *
     * @param updateWrapper - 更新参数条件对象
     * @param <T>
     */
    public <T> long update(Wrapper<T> updateWrapper) {
        return super.updateByQuery(updateWrapper.entityClass(), getEntityUpdate(updateWrapper));
    }

    /**
     * 更新
     *
     * @param t       - 更新元数据
     * @param wrapper - 更新参数条件对象
     * @param <T>
     * @return
     */
    public <T> long update(T t, Wrapper<T> wrapper) {
        return super.updateByQuery(wrapper.entityClass(), getEntityUpdate(t, wrapper));
    }

    /**
     * @param setMap  - 更新元数据
     * @param wrapper - 更新参数条件对象
     * @param <T>
     * @return
     */
    public <T> long update(Map<String, Object> setMap, Wrapper<T> wrapper) {
        return super.updateByQuery(wrapper.entityClass(), getEntityUpdate(setMap, wrapper));
    }

    /**
     * 获取查询条件对象
     *
     * @param wrapper - 查询条件
     * @param <T>
     * @return
     */
    private <T> EntityQuery getEntityQuery(Wrapper<T> wrapper) {
        EntityMeta entityMeta = super.getEntityMeta(wrapper.entityClass());
        //开始组装sql
        wrapper.assemble(entityMeta::getColumnName);
        EntityQuery entityQuery = EntityQuery.create().where(wrapper.getSqlSegment());
        // fix where无参数，报org.sagacity.sqltoy.utils.SqlUtil：Parameter index out of range (1 > number of parameters, which is 0).问题
        Map<String, Object> paramMap = wrapper.getSqlSegmentParamMap();
        if (paramMap != null && !paramMap.isEmpty()) {
            entityQuery.values(wrapper.getSqlSegmentParamMap());
        }

        if (wrapper.getSelectColumns() != null && !wrapper.getSelectColumns().isEmpty()) {
            entityQuery.select(wrapper.getSelectColumns().toArray(new String[0]));
        }
        return entityQuery;
    }

    /**
     * 组装更新条件
     *
     * @param updateWrapper - 更新条件
     * @param <T>
     * @return
     */
    private <T> EntityUpdate getEntityUpdate(Wrapper<T> updateWrapper) {
        Map<String, Object> setMap = updateWrapper.getSetMap();
        return getEntityUpdate(setMap, updateWrapper);
    }

    /**
     * @param t                - 更新元数据
     * @param queryWrapper     - 更新的查询条件
     * @param forceUpdateProps - 忽略字段
     * @param <T>
     * @return
     */
    private <T> EntityUpdate getEntityUpdate(T t, Wrapper<T> queryWrapper, String... forceUpdateProps) {
        EntityUpdate entityUpdate = EntityUpdate.create();
        EntityMeta entityMeta = super.getEntityMeta(queryWrapper.entityClass());
        Iterator<Map.Entry<String, String>> iterator = entityMeta.getColumnFieldMap().entrySet().iterator();
        Map<String, Object> setParamMap = ColumnUtils.objectToObjectMap(t, forceUpdateProps);
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            Object value = setParamMap.get(entry.getKey());
            if (value != null) {
                entityUpdate.set(entry.getKey(), value);
            }
        }
        return getEntityUpdate(setParamMap, queryWrapper);
    }

    /**
     * 组装更新条件
     *
     * @param queryWrapper - 更新的查询条件
     * @param <T>
     * @return
     */
    private <T> EntityUpdate getEntityUpdate(Map<String, Object> setMap, Wrapper<T> queryWrapper) {
        if (setMap == null || setMap.size() == 0) {
            throw new DataAccessException("sqlToy plus update param can not empty");
        }
        EntityMeta entityMeta = super.getEntityMeta(queryWrapper.entityClass());
        //开始组装sql
        queryWrapper.assemble(entityMeta::getColumnName);
        EntityUpdate entityUpdate = EntityUpdate.create();
        setMap.forEach(entityUpdate::set);
        // 当where无参数时，添加默认条件1=1，解决SqlToyDaoSupport.updateByQuery#1964的where语句中的?数量跟对应values 数组长度不一致,请检查!异常。
        String sqlSegment = queryWrapper.getSqlSegment();
        Map<String, Object> paramMap = queryWrapper.getSqlSegmentParamMap();
        if (paramMap.isEmpty()) {
            sqlSegment = StringUtil.isBlank(sqlSegment) ? "1=:DEFAULT_VALUE " : ("1=:DEFAULT_VALUE AND " + sqlSegment);
            paramMap.put("DEFAULT_VALUE", 1);
        }
        return entityUpdate.where(sqlSegment).values(paramMap);
    }
}