package org.crazycake.formSqlBuilder; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.persistence.Table; import org.crazycake.formSqlBuilder.annotation.DefaultSort; import org.crazycake.formSqlBuilder.exception.FormIsNullException; import org.crazycake.formSqlBuilder.model.Rule; import org.crazycake.formSqlBuilder.model.Sort; import org.crazycake.formSqlBuilder.model.SqlAndParams; import org.crazycake.formSqlBuilder.prop.RuleSchemeLoader; import org.crazycake.formSqlBuilder.ruleGenerator.DefaultRuleSchemeGenerator; import org.crazycake.formSqlBuilder.ruleGenerator.IRuleSchemeGenerator; import org.crazycake.utils.CamelNameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 将表单 * @author Administrator * */ public class FormSqlBuilder { private static Logger logger = LoggerFactory.getLogger(FormSqlBuilder.class); /** * 要查询的表名 */ private String tableName; /** * 排序的条件 */ private List<Sort> sorts = new ArrayList<Sort>(); /** * 单页最大记录数 */ private int rows; /** * 当前到第几页 */ private int page; /** * 查询表单 */ private Object form; /** * 动态传入的ruleScheme,如果有这个,优先使用 * 如果没有就使用 IRuleSchemeGenerator 创建 * 如果没有IRuleSchemeGenerator,就在HbJsonRuleScheme里面找 */ private Map<String, Rule> ruleScheme; /** * ruleScheme生成器 * 如果没有 IRuleSchemeGenerator 就在 HbJsonRuleScheme里面找 */ private IRuleSchemeGenerator ruleSchemeGenerator; /** * json文件里面的 rule scheme (映射规则) 的id */ private String ruleId; public FormSqlBuilder(Object form, String ruleId){ this.form = form; this.ruleId = ruleId; } /** * 添加排序 * @param sorts * @return */ public FormSqlBuilder addSort(Sort sort){ this.sorts.add(sort); return this; } /** * 添加翻页 * @param pageCount 单页最大记录数 * @param pageNum 当前到第几页 * @return */ public FormSqlBuilder addLimit(int page, int rows){ this.rows = rows; this.page = page; return this; } /** * 获取查询规则的MAP queryRule * @return */ private Map<String, Rule> generateRuleScheme() { Map<String, Rule> ruleScheme; if(this.ruleSchemeGenerator != null){ //如果有配置ruleSchemeGenerator,就用这个生成 ruleScheme = this.ruleSchemeGenerator.generateRuleScheme(this.form); }else if(ruleId != null && !"".equals(ruleId)){ //如果有配置 ruleId ruleScheme = RuleSchemeLoader.get(ruleId); }else{ //如果全部没有就采用默认的DefaultRuleSchemeGenerator DefaultRuleSchemeGenerator defaultRuleSchemeGenerator = new DefaultRuleSchemeGenerator(); ruleScheme = defaultRuleSchemeGenerator.generateRuleScheme(this.form); } return ruleScheme; } /** * 构建出的PreparedStatement对象专门用于统计行数 * @param session * @return * @throws SQLException * @throws InvocationTargetException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws IllegalArgumentException * @throws NoSuchFieldException * @throws SecurityException * @throws HqlBuildException */ public SqlAndParams buildCount() throws FormIsNullException, SQLException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchFieldException{ if(this.form == null){ throw new FormIsNullException("form cannot be null!"); } //如果表名没有设置:1.根据注解获取表名 2.根据类名自动猜测 if(tableName == null){ tableName = guessTableName(form); } /* * 1. 生成查询规则 */ ruleScheme = generateRuleScheme(); /* * 2. 生成sql语句和参数列表 */ SqlGenerator sqlGenerator = new SqlGenerator(); SqlAndParams sqlAndParams = sqlGenerator.generateCountSqlAndParams(this.form, ruleScheme,tableName); String sql = sqlAndParams.getSql(); /** * 4. 添加Sort条件 */ sql = SqlGenerator.appendSort(sql,this.form,this.sorts); /** * 5. 添加分页条件 */ sql = SqlGenerator.appendPage(sql,this.page,this.rows); logger.debug("sql: " + sql); sqlAndParams.setSql(sql); return sqlAndParams; } /** * 使用session 构建出query对象 * 最核心的方法 * @param session * @param isCount * @return * @throws SQLException * @throws FormIsNullException * @throws InvocationTargetException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws IllegalArgumentException * @throws NoSuchFieldException * @throws SecurityException * @throws HqlBuildException */ public SqlAndParams build() throws SQLException, FormIsNullException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchFieldException{ if(this.form == null){ throw new FormIsNullException("form cannot be null!"); } //如果表名没有设置:1.根据注解获取表名 2.根据类名自动猜测 if(tableName == null){ tableName = guessTableName(form); } /* * 1. 生成查询规则 */ ruleScheme = generateRuleScheme(); //如果没有设置排序用默认排序 useDefaultSortIfNotSet(); /* * 2. 生成sql语句和参数列表 */ SqlGenerator sqlGenerator = new SqlGenerator(); SqlAndParams sqlAndParams = sqlGenerator.generateSqlAndParams(this.form, ruleScheme,tableName); String sql = sqlAndParams.getSql(); /** * 4. 添加Sort条件 */ sql = SqlGenerator.appendSort(sql,this.form,this.sorts); /** * 5. 添加分页条件 */ sql = SqlGenerator.appendPage(sql,this.page,this.rows); logger.debug("sql: " + sql); sqlAndParams.setSql(sql); return sqlAndParams; } /** * 如果没有设置排序字段用默认排序 * @throws NoSuchMethodException */ private void useDefaultSortIfNotSet() throws NoSuchMethodException { if(this.sorts == null || this.sorts.size() == 0){ List<Sort> sortsList = new ArrayList<Sort>(); Field[] fields = form.getClass().getDeclaredFields(); for(Field f:fields){ String getterName = "get" + CamelNameUtils.capitalize(f.getName()); Method getter = form.getClass().getMethod(getterName); DefaultSort defaultSortAnno = getter.getAnnotation(DefaultSort.class); if(defaultSortAnno!=null){ boolean asc = defaultSortAnno.asc(); String orderStr = ""; if(asc){ orderStr = "asc"; }else{ orderStr = "desc"; } Sort sort = new Sort(f.getName(), orderStr); sortsList.add(sort); } } this.sorts = sortsList; } } /** * 通过form类猜测表名 * @param form * @return */ private String guessTableName(Object form) { String tableName = ""; Table tableAnno = form.getClass().getAnnotation(Table.class); if(tableAnno != null){ tableName = tableAnno.name(); }else{ String className = form.getClass().getName(); String camelName = className.substring(className.lastIndexOf(".")+1); tableName = CamelNameUtils.camel2underscore(camelName); } return tableName; } public String getTableName() { return tableName; } public void setTableName(String tableName) { this.tableName = tableName; } public Object getForm() { return form; } public void setForm(Object form) { this.form = form; } public String getRuleId() { return ruleId; } public void setRuleId(String ruleId) { this.ruleId = ruleId; } public IRuleSchemeGenerator getRuleSchemeGenerator() { return ruleSchemeGenerator; } public void setRuleSchemeGenerator(IRuleSchemeGenerator ruleSchemeGenerator) { this.ruleSchemeGenerator = ruleSchemeGenerator; } public Map<String, Rule> getRuleScheme() { return ruleScheme; } public void setRuleScheme(Map<String, Rule> ruleScheme) { this.ruleScheme = ruleScheme; } }