31

吐槽mybatis+熊猫哥优化教程

 4 years ago
source link: https://www.tuicool.com/articles/ZNnEneb
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

吐槽mybatis+熊猫哥优化教程

我将使用反射机制+自定义注解,该方法是由一个比我厉害的10倍的人教我的,感谢。百忙之中,水一篇 ,该文需要一定编程基础的人看

一,吐槽mybatis

我先吐槽这个动态条件sql,不知道mybatis那帮人为什么不能优化,可能是他们看这样的代码习惯了。反正我看到下面的代码,就感觉在看一堆shit,不仅辣眼睛,维护起来也是相当操蛋,是真的操蛋

<if test="customer.email != null and customer.email !=''">
            AND a.email like "%"#{customer.email}"%"
        </if>
        <if test="customer.salesName != null and customer.salesName !=''">
            AND d.sales_name = #{customer.salesName}
        </if>
        <if test="customer.firstName != null and customer.firstName !=''">
            AND a.first_name like "%"#{customer.firstName}"%"
        </if>
        <if test="customer.lastName != null and customer.lastName !=''">
            AND a.last_name like "%"#{customer.lastName}"%"
        </if>
        <if test="customer.whatapp != null and customer.whatapp !=''">
            AND a.whatapp like "%"#{customer.whatapp}"%"
        </if>
        <if test="customer.country != null and customer.country !=''">
            AND a.country = #{customer.country}
        </if>
        <if test="customer.province != null and customer.province !=''">
            AND a.province like "%"#{customer.province}"%"
        </if>
        <if test="customer.orderCount != null and customer.orderCount !=''">
            AND a.order_count like "%"#{customer.orderCount}"%"
        </if>
        <if test="customer.orderAmount != null and customer.orderAmount !=''">
            AND a.order_amount = #{customer.orderAmount}
        </if>
        <if test="customer.levelId != null and customer.levelId !=''">
            AND a.level_id = #{customer.levelId}
        </if>
        <if test="customer.lastLoginDateStartDate != null">
            AND s.last_order_date <![CDATA[>= ]]> #{customer.lastLoginDateStartDate}
        </if>
        <if test="customer.lastLoginDateEndDate != null">
            AND s.last_order_date <![CDATA[< ]]> #{customer.lastLoginDateEndDate}
        </if>
        <if test="customer.lastOrderDateStartDate != null">
            AND s.last_login_date <![CDATA[>= ]]> #{customer.lastOrderDateStartDate}
        </if>
        <if test="customer.lastOrderDateEndDate != null">
            AND s.last_login_date <![CDATA[< ]]> #{customer.lastOrderDateEndDate}
        </if>

        <if test="customer.createAtStartDate != null">
            AND s.create_at <![CDATA[>= ]]> #{customer.createAtStartDate}
        </if>
        <if test="customer.createAtEndDate != null">
            AND s.create_at <![CDATA[< ]]> #{customer.createAtEndDate}
        </if>

二,优化

安静看代码,上面一堆shit一样的代码,我已经优化为下面这样,变量名a,是不是干净又清爽,维护起来也是相当简单

<where>
            <foreach collection="conditionList" item="a" separator="and">
                    ${a}
            </foreach>
        </where>

熊猫哥优化教程

我将使用反射机制+自定义注解

第一:自定义注解annotation JewelryAlias

/**
 * @program:ant
 * @author:aodeng
 * @blog:低调小熊猫(https://aodeng.cc)
 * @微信公众号:低调小熊猫
 * @create:2019-06-04 18:41
 **/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface JewelryAlias {

    String value() default  "";

    String column() default  "";

    String type() default  "";
}

第二:封装工具:JewelryAnnotationUtil

/**
 * @author:aodeng(低调小熊猫)
 * @Description: TODO
 * @Date: 19-6-4
 **/
public class JewelryAnnotationUtil {

    private JewelryAnnotationUtil() {
    }

    public static List<String> getCondition(Object obj) throws IllegalAccessException {
        List<String> result = new ArrayList<>();
        System.out.println(obj.getClass()+"==============");
        Field[] fieldList = obj.getClass().getSuperclass().getDeclaredFields();
        for (Field field : obj.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(JewelryAlias.class) && (field.get(obj) != null)) {
                JewelryAlias j = field.getAnnotation(JewelryAlias.class);
                StringBuilder s = new StringBuilder();
                s.append(!StrUtil.isBlank(j.value()) ? j.value().concat(".") : "");
                s.append(!StrUtil.isBlank(j.column()) ? j.column() : field.getName());
                switch (j.type()) {
                    case "=":
                        s.append(" = ");
                        if(field.getType().equals(String.class)){
                            s.append("'").append(field.get(obj)).append("'");
                        }else{
                            s.append(field.get(obj));
                        }
                        break;
                    case "like":
                        s.append(" like ");
                        if(field.getType().equals(String.class)){
                            s.append("'").append("%").append(field.get(obj)).append("%").append("'");
                        }else{
                            s.append("%").append(field.get(obj)).append("%");
                        }
                        break;
                    default:
                        break;
                }
                result.add(s.toString());
            }

        }
        return result;
    }
	
}

举个例子

controller:

@RequestMapping(value = "/getOrderListByPage", method = RequestMethod.POST)
    public SuccessData getOrderListByPage(@RequestBody ConditionalQueryVo<SalesOrderQueryVo> queryVo) throws IllegalAccessException{
        if (ObjectUtil.isNull(queryVo.getConditionalObject())){
            queryVo.setConditionalObject(new SalesOrderQueryVo());
        }
        return CheckSqlStatus.getSuccessData(orderService.getOrderListByPage(JewelryAnnotationUtil.getCondition(queryVo.getConditionalObject()), queryVo.getPageIndex(), queryVo.getPageSize()));
    }

model:

/**
 * @author:aodeng(低调小熊猫)
 * @Description: TODO
 * @Date: 19-6-4
 **/
@Data
public class SalesOrderQueryVo {

    @JewelryAlias(value = "sot", column = "carrier_code", type = "=")
    private String carrierCode;

   @JewelryAlias(value = "sot", column = "track_number", type = "like")
    private String trackNumber;

    @JewelryAlias(value = "so", column = "order_increment", type = "like")
    private String orderIncrement;

    @JewelryAlias(value = "sot", column = "status", type = "=")
    private Integer status;
}

mapper:

List<SalesOrderModel> getOrderListByPage(Page<Object> page,@Param("conditionList") List<String> conditionList);


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK