抽取思维(重构设计)
1、✿ class TeacherQueryObject中的代码:
@Data public class TeacherQueryObject { private String name; private Integer minAge; private Integer maxAge; private Integer dormBuildId = -1; // 封装占位符参数 private List<Object> parameters = new ArrayList<>(); //解决where 1=1 索引问题【定义一个容器,当容器放进了条件,取出容器的条件(第一个条件前拼接上where,其他拼接and)】 //封装查询条件 private List<String> conditions = new ArrayList<>(); public String getQuery() { StringBuilder sql = new StringBuilder(); // 拼接姓名 if (StringUtils.isNotBlank(name)) { conditions.add("name LIKE ?"); parameters.add("%" + name + "%"); } // 拼接最小年龄 if (minAge != null) { conditions.add("age >= ?"); parameters.add(minAge); } // 拼接最大年龄 if (maxAge != null) { conditions.add("age <= ?"); parameters.add(maxAge); } // 拼接宿舍编号 if (dormBuildId != -1) { conditions.add("dormBuildId = ?"); parameters.add(dormBuildId); } if(conditions.size() == 0) { return ""; } sql.append(" WHERE "); //利用Apached 的组件 Apache commons-lang 组件:StringUtils的join方法:把集合中每个元素使用特定的字符串连接起来 sql.append(StringUtils.join(conditions, " AND ")); return sql.toString(); } public List<Object> getParameters() { return parameters; }
2、✿ class DormBuildQueryObject的代码:
@Data public class DormBuildQueryObject { private Integer dormBuildId = -1; private String dormBuildName; private String dormBuildDetail; //封装占位符参数 private List<Object> parameters = new ArrayList<>(); //解决where 1=1 索引问题【定义一个容器,当容器放进了条件,取出容器的条件(第一个条件前拼接上where,其他拼接and)】 //封装查询条件 private List<String> conditions = new ArrayList<>(); public String getQuery() { StringBuilder sql = new StringBuilder(); // 拼接宿舍id if (dormBuildId != -1) { conditions.add("name LIKE ?"); parameters.add(dormBuildId); } // 拼接宿舍楼名 if (StringUtils.isNotBlank(dormBuildName)) { conditions.add("dormBuildName = ?"); parameters.add(dormBuildName); } // 拼接宿舍详情 if (StringUtils.isNotBlank(dormBuildDetail)) { conditions.add("dormBuildDetail = ?"); parameters.add(dormBuildDetail); } if(conditions.size() == 0) { return ""; } sql.append(" WHERE "); //利用Apached 的组件 Apache commons-lang 组件:StringUtils的join方法:把集合中每个元素使用特定的字符串连接起来 sql.append(StringUtils.join(conditions, " AND ")); return sql.toString(); } public List<Object> getParameters() { return parameters; }
抽取:
共同属性、方法(结构内容都相同)、方法(结构相同、内容不同)【处理为结构相同、内容也相同:抽取不同的内容封装成一个方法】
3、共性----①抽取到单独一个类中去 ②抽取到父类中(因为两个类的作用都是查询----抽到父类中)
● 细节:抽取到父类中的
属性
(尽量不改写成protected
---破坏封装)、方法
可以改写成protected
给子类重写
● 子类中的方法customizedQuery 中 conditions、parameters报错
● 原因:conditions、parameters集合在父类是封装成私有(不改成protected),报错可以封装分法提供接口给外界访问
(重点是要知道子类需要conditions 和 parameters的目的是什么?)
● 目的:将传递到子类中的条件、参数值添加到父类的conditions集合、parameters集合中去
✿ class QueryObject 父类中的代码:
package com.shan.query; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; //高级查询对象的基类,包含所有查询对象的共性 public class QueryObject { // 封装占位符参数 private List<Object> parameters = new ArrayList<>(); // 封装查询条件 private List<String> conditions = new ArrayList<>(); public String getQuery() { StringBuilder sql = new StringBuilder(); customizedQuery(); if (conditions.size() == 0) { return ""; } sql.append(" WHERE "); // 利用Apached 的组件 Apache commons-lang 组件:StringUtils的join方法:把集合中每个元素使用特定的字符串连接起来 sql.append(StringUtils.join(conditions, " AND ")); return sql.toString(); } public List<Object> getParameters() { return parameters; } //暴露给子类:让子类覆盖并编写自个的查询条件和参数 protected void customizedQuery() { } //暴露给子类:让子类在customizedQuery中调用,添加字节的查询条件和参数 protected void addQuery(String condition, Object param) { this.conditions.add(condition); this.parameters.add(param); } }
✿ class DormBuildQueryObject 继承父类中的代码:
@Data public class DormBuildQueryObject extends QueryObject{ private Integer dormBuildId = -1; private String dormBuildName; private String dormBuildDetail; // 自身的定制查询 public void customizedQuery() { // 拼接宿舍id if (dormBuildId != -1) { // conditions.add("name LIKE ?"); // parameters.add(dormBuildId); super.addQuery("name LIKE ?", dormBuildId); } // 拼接宿舍楼名 if (StringUtils.isNotBlank(dormBuildName)) { super.addQuery("dormBuildName = ?", dormBuildName); } // 拼接宿舍详情 if (StringUtils.isNotBlank(dormBuildDetail)) { super.addQuery("dormBuildDetail = ?", dormBuildDetail); } }