对象转条件 
目标对象需要加上@ConditionTarget(实体类) 或者本身就是实体类
@ConditionTarget(实体类) 标记这个类的目标实体类 
为什么要加这个?答:为了减少字段配置,默认是继承@ConditionTarget(实体类)的实体类
如何配置属性的查询条件类型? 
默认情况下,字段有值就会自动拼接 eq行为;但是, 不是所有的条件的都是等于(eq),所以 我们需要在类上加一个注解;@Condition
@Condition 属性介绍 
| 名称 | 必须 | 说明 | 
|---|---|---|
| value | 否 | 条件的类型,默认是EQ | 
| target | 目标实体类 | 可忽略,默认和@ConditionTarget(实体类)一样或者是当前实体类 | 
| property | 否 | 目标实体类的属性名,如果和实体类字段一样,则可忽略 | 
| storey | 否 | source实体类的存储层级 | 
| likeMode | 否 | like的方式,左like,右like等等 | 
| toEndDayTime | 否 | 默认false,将日期转成到这天的最后1秒 只支持 lte 和 between的第2个参数 支持类型为LocalDate/Date/String/Long/LocalDateTime | 
| defaultValue | 否 | 默认值,支持动态值;支持基本类型的默认值 支持动态默认值,也可以自定义默认值; 例如 官方的默认值 "{NOW}" "{TODAY}" "{NOW}" 支持单个时间 "{TODAY}" 时间范围(数组类型或者集合类型字段) | 
@Conditions 属性介绍 
该注解是1字段对应多列的条件映射;用于关键字多列搜索场景
| 名称 | 必须 | 说明 | 
|---|---|---|
| value | 否 | 多个 @Condition 注解配置 | 
| logic | 否 | 默认为OR,条件拼接逻辑标识符 | 
@ConditionGroup 属性介绍 
该注解是对应obj查询类的字段进行分组;用于需要 and or 嵌套的情况
| 名称 | 必须 | 说明 | 
|---|---|---|
| value | 否 | 分组列配置 | 
| logic | 否 | 默认为AND,条件拼接逻辑标识符 | 
POJO 实例 
java
import cn.xbatis.db.annotations.Condition;
import cn.xbatis.db.annotations.ConditionTarget;
import com.xbatis.core.test.DO.SysUser;
import lombok.Data;
import static cn.xbatis.db.annotations.Condition.Type.*;
@Data
@ConditionTarget(SysUser.class)
public class QueryREQ {
    private Integer id;
    @Condition(value = LIKE)
    private String userName;
    @Condition(property = SysUser.Fields.id, value = GT)
    private Integer gtId;
    @Condition(property = SysUser.Fields.id, value = GTE)
    private Integer gteId;
    @Condition(property = SysUser.Fields.id, value = LT)
    private Integer ltId;
    @Condition(property = SysUser.Fields.id, value = LTE)
    private Integer lteId;
    @Condition(property = SysUser.Fields.id, value = BETWEEN)
    private Integer[] btIds;
    @Conditions(
            logic = Logic.OR,
            value = {
                    @Condition(property = SysUser.Fields.userName, value = LIKE),
                    @Condition(property = SysUser.Fields.password, value = LIKE)
            }
    )
    private String keyword;
}如何用? 
java
    QueryREQ queryReq = new QueryREQ();
    queryReq.setId(1);
    
    Integer id = QueryChain.of(sysUserMapper)
            .where(queryReq)
            .select(SysUser::getId)
            .returnType(Integer.class)
            .get();如何实现内嵌形式的条件,例如 id1=1 and (id2=2 or id3=3) 
java
@Data
@ConditionTarget(SysUser.class)
@ConditionGroup(value = {QueryREQ.Fields.id1, QueryREQ.Fields.id2}, logic = Logic.OR)
@FieldNameConstants
public class QueryREQ {
    private Integer id1;
    private Integer id2;
    private Integer id3;
}如何实现内嵌形式的条件,例如 id1=1 or (id2=2 and id3=3) 
java
@Data
@ConditionTarget(value=SysUser.class, logic = Logic.OR)
@ConditionGroup(value = {QueryREQ.Fields.id1, QueryREQ.Fields.id2})
@FieldNameConstants
public class QueryREQ {
    private Integer id1;
    private Integer id2;
    private Integer id3;
}如何在拼接条件前,做一些处理,例如设置参数的值 
以下为了 查询7天,30天的数据,约定前端传 timeType =day7 和timeType = day30
java
import java.time.LocalDate;
@Data
@ConditionTarget(value = SysUser.class)
@FieldNameConstants
public class QueryREQ implements ObjectConditionLifeCycle {
    
    private String timeType;
    @Condition(property = SysUser.Fields.createTime, value = BETWEEN, toEndDayTime = true)
    private LocalDate[] rangeTime;
    @Override
    public void beforeBuildCondition() {
        //System.out.println("在构建条件前执行");
        if (StringUtils.isNotBlank(timeType)) {
            // 此处用到动态值获取,this.timeType 为 day7 或 day30
            this.rangeTimes = XbatisGlobalConfig.getDynamicValue(this.getClass(), LocalDate[].class, this.timeType);
        }
    }
}
public class MyXbatisGlobalConfig(){
    
    void init(){
        //注入最近7天的动态值
        XbatisGlobalConfig.setDynamicValue("{day7}",(clazz,type)->{
            return new LocalDate[] {LocalDate.now().minusDays(7),LocalDate.now()};
        });
        //注入最近30天的动态值
        XbatisGlobalConfig.setDynamicValue("{day30}",(clazz,type)->{
            return new LocalDate[] {LocalDate.now().minusDays(30),LocalDate.now()};
        });
    }
}查询没有区别,就可以简化前端传参的操作
