Mapper icon indicating copy to clipboard operation
Mapper copied to clipboard

selectByExample的一个bug

Open luger1990 opened this issue 4 years ago • 3 comments

当table中有逻辑删除字段的时候执行下面这段代码会报错(sex为空的时候报错)

public PageInfo<SysAdmin> list(Integer sex) {
        Example example = new Example(SysAdmin.class);
        Example.Criteria criteria = example.createCriteria();
        if (null != sex) {
            criteria.andEqualTo("sex", sex);
        }
        return new PageInfo<SysAdmin>(this.selectByExample(example));
    }

错误为:

SQL: SELECT  id,username,nickname,email,phone_number,sex,avatar,slat,password,status,del_status,last_ip,last_time,create_time,update_time,create_admin_id,create_admin_name,update_admin_id,update_admin_name,remark  FROM t_sys_admin  WHERE del_status = 0 and
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
; bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

执行的slq最后多了个and ———————————————————————————————————————————————— 原因如下: 动态生成的mybatis如下:

SELECT <choose><when test="@tk.mybatis.mapper.util.OGNL@hasCountColumn(_parameter)">COUNT(<if test="distinct">distinct </if>${countColumn})</when><otherwise>COUNT(*)</otherwise></choose> FROM t_sys_admin <if test="_parameter != null"><where>
 ${@tk.mybatis.mapper.util.OGNL@andNotLogicDelete(_parameter)} 
 <trim prefix="(" prefixOverrides="and |or " suffix=")">
  <foreach collection="oredCriteria" item="criteria">
    <if test="criteria.valid">
      ${@tk.mybatis.mapper.util.OGNL@andOr(criteria)}      
	  <trim prefix="(" prefixOverrides="and |or " suffix=")">
        <foreach collection="criteria.criteria" item="criterion">
          <choose>
            <when test="criterion.noValue">
              ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition}
            </when>
            <when test="criterion.singleValue">
              ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition} #{criterion.value}
            </when>
            <when test="criterion.betweenValue">
              ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
            </when>
            <when test="criterion.listValue">
              ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition}
              <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                #{listItem}
              </foreach>
            </when>
          </choose>
        </foreach>
      </trim>
    </if>
  </foreach>
 </trim>
</where></if><if test="@tk.mybatis.mapper.util.OGNL@hasForUpdate(_parameter)">FOR UPDATE</if>

其中判断是否有逻辑删除的方法andNotLogicDelete如下:

public static String andNotLogicDelete(Object parameter) {
        String result = "";
        if (parameter instanceof Example) {
            Example example = (Example) parameter;
            Map<String, EntityColumn> propertyMap = example.getPropertyMap();

            for (Map.Entry<String, EntityColumn> entry: propertyMap.entrySet()) {
                EntityColumn column = entry.getValue();
                if (column.getEntityField().isAnnotationPresent(LogicDelete.class)) {
                    // 未逻辑删除的条件
                    result = column.getColumn() + " = " + SqlHelper.getLogicDeletedValue(column, false);

                    // 如果Example中有条件,则拼接" and ",
                    // 如果是空的oredCriteria,则where中只有逻辑删除注解的未删除条件
                    if (example.getOredCriteria() != null && example.getOredCriteria().size() != 0) {
                        result += " and "; //看这看这看这xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxx 这里会多一个and
                    }
                }
            }
        }
        return result;
    }

这是个bug吗,还是我是用的不对

luger1990 avatar Sep 16 '21 12:09 luger1990

主要问题在于下面的if条件代码判断有问题

if (example.getOredCriteria() != null && example.getOredCriteria().size() != 0) {
     result += " and "; //看这看这看这xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxx 这里会多一个and
 }

luger1990 avatar Sep 17 '21 03:09 luger1990

感谢反馈,方便推个PR修复吗?

abel533 avatar Sep 18 '21 05:09 abel533

感谢反馈,方便推个PR修复吗?

ok

luger1990 avatar Sep 20 '21 16:09 luger1990