package cn.estsh.i3plus.pojo.base.jpa.dao;

import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.common.Pager;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;

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

/**
 * @Description : 自定义Repository的方法接口
 * @Reference : 对jpaRepository进行扩展
 * @Author : alwaysfrin
 * @CreateDate : 2018-09-13 10:34
 * @Modify:
 **/
@NoRepositoryBean
public interface BaseRepository <T, ID extends Serializable> extends JpaRepository<T, ID> {

    /**
     * 清空一级缓存，可能影响service中对象的状态，慎用
     */
    void clearSession();

    /**
     * 清除一级缓存对象，设为游离态
     * @param t
     */
    void detachObject(T t);

    /**
     * 清除一级缓存集合，设为游离态
     * @param list
     */
    void detachList(List<T> list);

    /**
     * 新增对象<br/>
     * 注意：如果对象id是long，并且为0，则设为
     * 字符串，并且没有赋值，该方法将自动设置为uuid值
     * @param item
     *            持久对象，或者对象集合
     */
    T insert(T item);

    /**
     * 新增对象<br/>
     * 注意：如果对象id是long，并且为0，则设为
     * 字符串，并且没有赋值，该方法将自动设置为uuid值
     * @param item
     *            持久对象，或者对象集合
     * @param initParam 是否需要初始化值为null的属性，
     */
    T insert(T item,boolean initParam);

    /**
     * 更新对象数据
     *
     * @param item
     *            持久对象，或者对象集合
     */
    void update(Object... item);

    /**
     * 执行ql语句
     * hql写法：update obj set name = ？，问号舒徐需要和list顺序一致
     * @param qlString 基于jpa标准的ql语句
     * @param values ql中的T参数值,单个参数值或者多个参数值
     * @return 返回执行后受影响的数据个数
     */
    int executeUpdate(String qlString, Object... values);

    /**
     * 执行ql语句
     * hql写法：update obj set name = :name
     * @param qlString 基于jpa标准的ql语句
     * @param params key表示ql中参数变量名，value表示该参数变量值
     * @return 返回执行后受影响的数据个数
     */
    int executeUpdate(String qlString, Map<String, Object> params);

    /**
     * 执行ql语句，可以是更新或者删除操作
     * hql写法：update obj set name = ？，问号舒徐需要和list顺序一致
     * @param qlString 基于jpa标准的ql语句
     * @param values ql中的T参数值
     * @return 返回执行后受影响的数据个数
     */
    int executeUpdate(String qlString, List<Object> values);

    /**
     * 强删除
     */
    void deleteById(ID id);
    int deleteByProperty(String propName, Object propValue);
    int deleteByPropertyIn(String propName, Object[] propValues);
    int deleteByIds(ID[] ids);
    int deleteByProperties(String[] propNames, Object[] objValues);

    /**
     * 通过多单属性进行单个值更新
     * @param conditionName
     * @param conditionValue
     * @param propertyName
     * @param propertyValue
     */
    int updateByProperties(String conditionName, Object conditionValue, String propertyName, Object propertyValue);

    /**
     * 通过单个属性进行多个值更新
     * @param conditionName
     * @param conditionValue
     * @param propertyName
     * @param propertyValue
     */
    int updateByProperties(String conditionName, Object conditionValue, String[] propertyName, Object[] propertyValue);

    /**
     * 通过属性进行多个值更新
     * @param propertyName
     * @param propertyValue
     */
    int updateByProperties(String propertyName, Object propertyValue,DdlPackBean packBean);
    int updateByProperties(String[] propertyName, Object[] propertyValue,DdlPackBean packBean);


    /**
     * 通过多个属性进行单个值更新
     * @param conditionName
     * @param conditionValue
     * @param propertyName
     * @param propertyValue
     */
    int updateByProperties(String[] conditionName, Object[] conditionValue, String propertyName, Object propertyValue);

    /**
     * 通过多个属性进行多个值更新
     * @param conditionName 查询属性名称
     * @param conditionValue 查询属性值
     * @param propertyName 更新属性名称
     * @param propertyValue 更新属性值
     */
    int updateByProperties(String[] conditionName, Object[] conditionValue, String[] propertyName, Object[] propertyValue);

    /**
     * 通过多单属性进行单个值更新(eg： price = price + :price)
     * @param conditionName
     * @param conditionValue
     * @param propertyName
     * @param propertyValue
     */
    int updateByPropertiesWithVal(String conditionName, Object conditionValue, String propertyName, Object propertyValue);

    /**
     * 通过单个属性进行多个值更新(eg： price = price + :price)
     * @param conditionName
     * @param conditionValue
     * @param propertyName
     * @param propertyValue
     */
    int updateByPropertiesWithVal(String conditionName, Object conditionValue, String[] propertyName, Object[] propertyValue);

    /**
     * 通过属性进行多个值更新(eg： price = price + :price)
     * @param propertyName
     * @param propertyValue
     */
    int updateByPropertiesWithVal(String propertyName, Object propertyValue,DdlPackBean packBean);
    int updateByPropertiesWithVal(String[] propertyName, Object[] propertyValue,DdlPackBean packBean);


    /**
     * 通过多个属性进行单个值更新(eg： price = price + :price)
     * @param conditionName
     * @param conditionValue
     * @param propertyName
     * @param propertyValue
     */
    int updateByPropertiesWithVal(String[] conditionName, Object[] conditionValue, String propertyName, Object propertyValue);

    /**
     * 通过多个属性进行多个值更新(eg： price = price + :price)
     * @param conditionName 查询属性名称
     * @param conditionValue 查询属性值
     * @param propertyName 更新属性名称
     * @param propertyValue 更新属性值
     */
    int updateByPropertiesWithVal(String[] conditionName, Object[] conditionValue, String[] propertyName, Object[] propertyValue);

    /**
     * 根据 hqlWhere 批量修改制定字段
     * @param hqlWhere
     * @param propertyName  修改的字段名称
     * @param propertyValue 修改后的值
     * @return
     */
    int updateByHqlWhere(String hqlWhere,String propertyName, Object propertyValue);

    /**
     * 批量修改数据熟悉
     * @param hqlWhere      HQL where 语句
     * @param propertyName  修改的字段名称
     * @param propertyValue 修改后的值
     * @return
     */
    int updateByHqlWhere(String hqlWhere,String[] propertyName, Object[] propertyValue);

    T getById(long id);

    List<T> list();

    List<T> list(final String hql);

    List<T> listPager(Pager pager);

    List<T> findByPage(final DdlPackBean packBean, final int offset, final int pageSize);

    /**
     * @param hql hql入参需要用问号代替
     * @param values 按照入参问号的顺序进行赋值
     * @param offset
     * @param pageSize
     * @return
     */
    List<T> findByPage(final String hql, final Object[] values, final int offset, final int pageSize);

    List<T> findByProperty(String propertyName, Object value);



    List<T> findByProperty(String[] propertyNames, Object[] values);

    List<T> findByProperty(String propertyName, Object value,String orderByStuff);

    List<T> findByProperty(String[] propertyNames, Object[] values,String orderByStuff);

    T getByProperty(DdlPackBean packBean);

    T getByProperty(String propertyName, Object value);

    T getByProperty(String[] propertyNames, Object[] values);

    @Deprecated
    T getByPropertyPager(String[] propertyNames, Object[] values,Pager pager);

    int listCount();

    int findByPropertyCount(String propertyName, Object value);

    T findByVendorNoProperty(String vendorNo);

    int findByPropertyCount(String[] propertyNames, Object[] values);

    List<T> findByPropertyPage(String propertyName, Object value,String orderByStuff,Pager pager);

    List<T> findByPropertyPage(String[] propertyNames, Object[] values,String orderByStuff,Pager pager);

    @Deprecated
    List<T> findByHql(String hql);

    @Deprecated
    List<T> findByHqlWhere(String hqlWhere);

    List<T> findByHqlWhere(DdlPackBean packBean);

    List<T> findByHqlWhere(String hqlWhere,String[] propertyNames, Object[] values,String orderByStuff);

    int findByHqlWhereCount(String hqlWhere,String[] propertyNames, Object[] values);

    List<T> findByHqlWherePage(String hqlWhere, Pager pager,String[] propertyNames, Object[] values,String orderByStuff);

    @Deprecated
    List<T> findByHqlWherePage(String hqlWhere, Pager pager);

    List<T> findByHqlWherePage(DdlPackBean packBean, Pager pager);

    @Deprecated
    int findByHqlWhereCount(String hqlWhere);

    int findByHqlWhereCount(DdlPackBean packBean);

    int findByHqlCount(String hql);

    int findByHqlCount(String hql,String[] paramName,Object[] paramValue);

    @Deprecated
    List<T> findByHqlPage(String hql, Pager pager);

    List<T> findByHqlPage(DdlPackBean packBean, Pager pager);

    List<T> findByHqlPage(String hql, Pager pager,String[] paramName,Object[] paramValue);

    @Deprecated
    List findBySql(String sql);

    @Deprecated
    List<?> findBySql(String sql,Class entity);

    @Deprecated
    List findBySqlPage(String sql,Pager pager);

    @Deprecated
    List<?> findBySqlPage(String sql,Class entity,Pager pager);

    @Deprecated
    int executeSql(String sql);

    @Deprecated
    int findBySqlCount(String sql);

    @Deprecated
    double findBySqlSumDouble(String sql,String columnName);

    @Deprecated
    double findByHqlDouble(String hql);

    double findByHqlDouble(DdlPackBean packBean);

    @Deprecated
    long findByHqlLong(String hql);

    long findByHqlLong(DdlPackBean packBean);

    @Deprecated
    List<T> findByHqlTopWhere(String hqlWhere,int topNum);

    List<T> findByHqlTopWhere(DdlPackBean packBean,int topNum);

    @Deprecated
    List<T> findColumnsByHql(String hql, String hqlWhere, String orderByStuff, Pager pager);

    /**********************  多表联查，返回Object[]数组根据hql查询翻页信息  开始 ****************************/
    List<Object[]> findByHqlObjects(String hql);

    List<Object[]> findByHqlObjects(String hql,String[] paramName,Object[] paramValue);

    List<Object[]> findByHqlPageObjects(String hql, Pager pager);

    List<Object[]> findByHqlPageObjects(String hql, Pager pager,String[] paramName,Object[] paramValue);

    List<Object[]> findBySqlObjList(String sql);

    List<Object[]> findBySqlObjListByPager(String sql,Pager pager);

    /****************** 部分业务处理 *******************/

    /**
     * 弱删除
     * @return count
     */
    int deleteWeaklyById(ID id,String username);
    int deleteWeaklyByIds(Long[] ids,String username) ;
    int deleteWeaklyByProperty(String propName, Object propValue,String username);
    int deleteWeaklyByPropertyIn(String propName, Object[] propValues,String username);
    int deleteWeaklyByProperties(String[] propNames, Object[] objValues,String username);

    /**
     * 更新启用禁用
     * @return count
     */
    int updateValidStatusById(ID id,int status,String username);
    int updateValidStatusByIds(Long[] ids,int status,String username) ;
    int updateValidStatusByProperty(String propName, Object propValue,int status,String username);
    int updateValidStatusByPropertyIn(String propName, Object[] propValues,int status,String username);
    int updateValidStatusByProperties(String[] propNames, Object[] objValues,int status,String username);

    boolean isExitByProperty(String propertyName, Object value);

    boolean isExitByProperty(String[] propertyNames, Object[] values);

    boolean isExitByPropertyDemo(String[] propertyNames, Object[] values);

    boolean isExitByHqlWhere(String hqlWhere,String[] propertyNames, Object[] values);

    boolean isExitByHqlWhere(String hqlWhere);

    @Deprecated
    boolean isExitByHql(String hql);

    boolean isExitByHql(DdlPackBean packBean);

    boolean isExitByHql(String hql,String[] paramName,Object[] paramValue);

    boolean isExitBySql(String sql);

    double findSumByProperty(String sumPropertyName,String groupByName,String propertyName, Object value);

    double findSumByProperties(String sumPropertyName,String groupByName,String[] paramName,Object[] paramValue);

    double findAvgByProperty(String sumPropertyName,String groupByName,String propertyName, Object value);

    double findAvgByProperties(String sumPropertyName,String groupByName,String[] paramName,Object[] paramValue);

    double findMaxByProperty(String sumPropertyName,String groupByName,String propertyName, Object value);

    double findMaxByProperties(String sumPropertyName,String groupByName,String[] paramName,Object[] paramValue);

    double findMinByProperty(String sumPropertyName,String groupByName,String propertyName, Object value);

    double findMinByProperties(String sumPropertyName,String groupByName,String[] paramName,Object[] paramValue);

    List<T> findByHqlWhereByClear(DdlPackBean packBean, String dateTime);

}
