@Override
  public List<CompilationUnit> getCompilationUnits() {
    FullyQualifiedTable table = introspectedTable.getFullyQualifiedTable();
    progressCallback.startTask(getString("Progress.9", table.toString())); // $NON-NLS-1$
    Plugin plugins = context.getPlugins();
    CommentGenerator commentGenerator = context.getCommentGenerator();

    TopLevelClass topLevelClass = new TopLevelClass(introspectedTable.getRecordWithBLOBsType());
    topLevelClass.setVisibility(JavaVisibility.PUBLIC);
    commentGenerator.addJavaFileComment(topLevelClass);

    topLevelClass.addJavaDocLine("/**");
    topLevelClass.addJavaDocLine("* " + table.getDomainObjectName());
    topLevelClass.addJavaDocLine("* table:" + table.getIntrospectedTableName());
    topLevelClass.addJavaDocLine("* ");
    topLevelClass.addJavaDocLine("* @author 王欣");
    topLevelClass.addJavaDocLine("* @version v1.0");
    // topLevelClass.addJavaDocLine("* @copy 鸿旭图码");
    topLevelClass.addJavaDocLine("* @copy wangxin");
    topLevelClass.addJavaDocLine(
        "* @date " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    topLevelClass.addJavaDocLine("*/");

    String rootClass = getRootClass();
    if (introspectedTable.getRules().generateBaseRecordClass()) {
      topLevelClass.setSuperClass(introspectedTable.getBaseRecordType());
    } else {
      topLevelClass.setSuperClass(introspectedTable.getPrimaryKeyType());
    }

    if (introspectedTable.isConstructorBased()) {
      addParameterizedConstructor(topLevelClass);

      if (!introspectedTable.isImmutable()) {
        addDefaultConstructor(topLevelClass);
      }
    }

    for (IntrospectedColumn introspectedColumn : introspectedTable.getBLOBColumns()) {
      if (RootClassInfo.getInstance(rootClass, warnings).containsProperty(introspectedColumn)) {
        continue;
      }

      Field field = getJavaBeansField(introspectedColumn);
      if (plugins.modelFieldGenerated(
          field,
          topLevelClass,
          introspectedColumn,
          introspectedTable,
          Plugin.ModelClassType.RECORD_WITH_BLOBS)) {
        topLevelClass.addField(field);
        topLevelClass.addImportedType(field.getType());
      }

      Method method = getJavaBeansGetter(introspectedColumn);
      if (plugins.modelGetterMethodGenerated(
          method,
          topLevelClass,
          introspectedColumn,
          introspectedTable,
          Plugin.ModelClassType.RECORD_WITH_BLOBS)) {
        topLevelClass.addMethod(method);
      }

      if (!introspectedTable.isImmutable()) {
        method = getJavaBeansSetter(introspectedColumn);
        if (plugins.modelSetterMethodGenerated(
            method,
            topLevelClass,
            introspectedColumn,
            introspectedTable,
            Plugin.ModelClassType.RECORD_WITH_BLOBS)) {
          topLevelClass.addMethod(method);
        }
      }
    }

    List<CompilationUnit> answer = new ArrayList<CompilationUnit>();
    if (context.getPlugins().modelRecordWithBLOBsClassGenerated(topLevelClass, introspectedTable)) {
      answer.add(topLevelClass);
    }
    return answer;
  }
 private void addGetRecordMethods(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, MyBatisClasses cls, String base, String withBLOBs, String expression) {
     String returnType = cls.names.base;
     topLevelClass.addImportedType(cls.imports.base);
     String listType = "java.util.List<"+returnType+">";
     if (!base.startsWith(SKIP) && introspectedTable.getRules().generateSelectByExampleWithoutBLOBs()) {
         topLevelClass.addMethod(method(
             PUBLIC, new FullyQualifiedJavaType(returnType), base, _(sqlSession, "sql"), __(
                 listType + " list = sql.getMapper(" + cls.names.mapper + ".class).selectByExample(this);",
                 "return "+expression.replace("@result", returnType)+";"
         )));
         topLevelClass.addMethod(method(
             PUBLIC, new FullyQualifiedJavaType(returnType), base, _(cls.types.mapper, "mapper"), __(
                 listType + " list = mapper.selectByExample(this);",
                 "return "+expression.replace("@result", returnType)+";"
         )));
     }
     if (introspectedTable.hasBLOBColumns() && !withBLOBs.startsWith(SKIP) && introspectedTable.getRules().generateSelectByExampleWithBLOBs()) {
         if (cls.exists.blob) {
             returnType = cls.names.blob;
             topLevelClass.addImportedType(cls.imports.blob);
         }
         listType = "java.util.List<"+returnType+">";
         topLevelClass.addMethod(method(
             PUBLIC, new FullyQualifiedJavaType(returnType), withBLOBs, _(sqlSession, "sql"), __(
                 listType + " list = sql.getMapper(" + cls.names.mapper + ".class).selectByExampleWithBLOBs(this);",
                 "return "+expression.replace("@result", returnType)+";"
         )));
         topLevelClass.addMethod(method(
             PUBLIC, new FullyQualifiedJavaType(returnType), withBLOBs, _(cls.types.mapper, "mapper"), __(
                 listType + " list = mapper.selectByExampleWithBLOBs(this);",
                 "return "+expression.replace("@result", returnType)+";"
         )));
     }
 }
 private void addListMethods(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, MyBatisClasses cls) {
     String returnType = "java.util.List<"+cls.names.base+">";
     topLevelClass.addImportedType(cls.imports.base);
     if (!listMethod.startsWith(SKIP) && introspectedTable.getRules().generateSelectByExampleWithoutBLOBs()) {
         topLevelClass.addMethod(method(
             PUBLIC, new FullyQualifiedJavaType(returnType), listMethod, _(sqlSession, "sql"), __(
                 "return sql.getMapper(" + cls.names.mapper + ".class).selectByExample(this);"
         )));
         topLevelClass.addMethod(method(
             PUBLIC, new FullyQualifiedJavaType(returnType), listMethod, _(cls.types.mapper, "mapper"), __(
                 "return mapper.selectByExample(this);"
         )));
     }
     if (introspectedTable.hasBLOBColumns() && !listWithBLOBsMethod.startsWith(SKIP) && introspectedTable.getRules().generateSelectByExampleWithBLOBs()) {
         if (cls.exists.blob) {
             returnType = "java.util.List<" + cls.names.blob + ">";
             topLevelClass.addImportedType(cls.imports.blob);
         }
         topLevelClass.addMethod(method(
             PUBLIC, new FullyQualifiedJavaType(returnType), listWithBLOBsMethod, _(sqlSession, "sql"), __(
                 "return sql.getMapper("+cls.names.mapper+".class).selectByExampleWithBLOBs(this);"
         )));
         topLevelClass.addMethod(method(
             PUBLIC, new FullyQualifiedJavaType(returnType), listWithBLOBsMethod, _(cls.types.mapper, "mapper"), __(
                 "return mapper.selectByExampleWithBLOBs(this);"
         )));
     }
 }
    private void addUserDefinedMethods(TopLevelClass exampleClass, Interface mapperClass, IntrospectedTable introspectedTable, MyBatisClasses cls) {
        for (Method action : mapperClass.getMethods()) {
            if (!userDefinedMethods.matcher(action.getName()).matches()) continue;
            StringBuilder args = new StringBuilder();
            List<Parameter> params = new ArrayList<Parameter>();
            boolean example = false;
            if (action.getParameters() != null)
                for (Parameter param : action.getParameters()) {
                    String name;
                    if (Objects.equals(param.getType(), exampleClass.getType())) {
                        example = true;
                        name = "this";
                    } else {
                        name = param.getName();
                        params.add(new Parameter(param.getType(), name));
                    }
                    if (args.length() > 0)
                        args.append(", ");
                    args.append(name);
                }
            if (!example) {
                //System.err.println("Invalid user-defined mapper method: "+action.getName());
                continue;
            }

            exampleClass.addMethod(method(
                PUBLIC, INT, action.getName(), _(sqlSession, "sql"), params.toArray(new Parameter[params.size()]), __(
                    "return sql.getMapper(" + cls.names.mapper + ".class)."+action.getName()+"("+args+");"
            )));
            exampleClass.addMethod(method(
                PUBLIC, INT, action.getName(), _(cls.types.mapper, "mapper"), params.toArray(new Parameter[params.size()]), __(
                    "return mapper."+action.getName()+"("+args+");"
            )));
        }
    }
  /** 添加方法 */
  protected void addMethod(TopLevelClass topLevelClass) {
    Method method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setName("setSuccess");
    method.addParameter(
        new Parameter(FullyQualifiedJavaType.getBooleanPrimitiveInstance(), "success"));
    method.addBodyLine("this.success = success;");
    topLevelClass.addMethod(method);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setReturnType(FullyQualifiedJavaType.getBooleanPrimitiveInstance());
    method.setName("isSuccess");
    method.addBodyLine("return success;");
    topLevelClass.addMethod(method);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setName("setMessage");
    method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "message"));
    method.addBodyLine("this.message = message;");
    topLevelClass.addMethod(method);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setReturnType(FullyQualifiedJavaType.getStringInstance());
    method.setName("getMessage");
    method.addBodyLine("return message;");
    topLevelClass.addMethod(method);
  }
 private void addLimit(
     TopLevelClass topLevelClass, IntrospectedTable introspectedTable, String name) {
   CommentGenerator commentGenerator = context.getCommentGenerator();
   FullyQualifiedJavaType limitType = new FullyQualifiedJavaType("com.tommy.common.Limit");
   topLevelClass.addImportedType(limitType);
   Field field = new Field();
   field.setVisibility(JavaVisibility.PROTECTED);
   field.setType(limitType);
   field.setName(name);
   commentGenerator.addFieldComment(field, introspectedTable);
   topLevelClass.addField(field);
   char c = name.charAt(0);
   String camel = Character.toUpperCase(c) + name.substring(1);
   Method method = new Method();
   method.setVisibility(JavaVisibility.PUBLIC);
   method.setName("set" + camel);
   method.addParameter(new Parameter(limitType, name));
   method.addBodyLine("this." + name + "=" + name + ";");
   commentGenerator.addGeneralMethodComment(method, introspectedTable);
   topLevelClass.addMethod(method);
   method = new Method();
   method.setVisibility(JavaVisibility.PUBLIC);
   method.setReturnType(limitType);
   method.setName("get" + camel);
   method.addBodyLine("return " + name + ";");
   commentGenerator.addGeneralMethodComment(method, introspectedTable);
   topLevelClass.addMethod(method);
 }
 private void addUpdateMethods(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, MyBatisClasses cls, String base, String withBLOBs, boolean selective) {
     String record = cls.names.base;
     topLevelClass.addImportedType(cls.imports.base);
     String mapperMethod = selective ? "updateByExampleSelective" : "updateByExample";
     Rules r = introspectedTable.getRules();
     if (!base.startsWith(SKIP) && ( selective ? r.generateUpdateByExampleSelective() : r.generateUpdateByExampleWithoutBLOBs() )) {
         if (selective && r.generateRecordWithBLOBsClass()) {
             record = cls.names.blob;
             topLevelClass.addImportedType(cls.imports.blob);
         }
         topLevelClass.addMethod(method(
             PUBLIC, INT, base, _(sqlSession, "sql"), _(new FullyQualifiedJavaType(record), "record"), __(
                 "return sql.getMapper(" + cls.names.mapper + ".class)."+mapperMethod+"(record, this);"
         )));
         topLevelClass.addMethod(method(
             PUBLIC, INT, base, _(cls.types.mapper, "mapper"), _(new FullyQualifiedJavaType(record), "record"), __(
                 "return mapper."+mapperMethod+"(record, this);"
         )));
     }
     if (introspectedTable.hasBLOBColumns() && !withBLOBs.startsWith(SKIP) && !selective && r.generateUpdateByExampleWithBLOBs()) {
         if (r.generateRecordWithBLOBsClass()) {
             record = cls.names.blob;
             topLevelClass.addImportedType(cls.imports.blob);
         }
         mapperMethod = selective ? "updateByExampleSelectiveWithBLOBs" /* not supported */ : "updateByExampleWithBLOBs";
         topLevelClass.addMethod(method(
             PUBLIC, INT, withBLOBs, _(sqlSession, "sql"), _(new FullyQualifiedJavaType(record), "record"), __(
                 "return sql.getMapper(" + cls.names.mapper + ".class)."+mapperMethod+"(record, this);"
         )));
         topLevelClass.addMethod(method(
             PUBLIC, INT, withBLOBs, _(cls.types.mapper, "mapper"), _(new FullyQualifiedJavaType(record), "record"), __(
                 "return mapper."+mapperMethod+"(record, this);"
         )));
     }
 }
 private void addCountMethods(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, MyBatisClasses cls) {
     if (!countMethod.startsWith(SKIP) && introspectedTable.getRules().generateCountByExample()) {
         topLevelClass.addMethod(method(
             PUBLIC, INT, countMethod, _(sqlSession, "sql"), __(
                 "return sql.getMapper(" + cls.names.mapper + ".class).countByExample(this);"
         )));
         topLevelClass.addMethod(method(
             PUBLIC, INT, countMethod, _(cls.types.mapper, "mapper"), __(
                 "return mapper.countByExample(this);"
         )));
     }
 }
 /** 添加方法 */
 protected void addMethod(TopLevelClass topLevelClass, String tableName) {
   Method method2 = new Method();
   for (int i = 0; i < methods.size(); i++) {
     Method method = new Method();
     method2 = methods.get(i);
     method = method2;
     method.removeAllBodyLines();
     method.removeAnnotation();
     StringBuilder sb = new StringBuilder();
     sb.append("return this.");
     sb.append(getDaoShort());
     sb.append(method.getName());
     sb.append("(");
     List<Parameter> list = method.getParameters();
     for (int j = 0; j < list.size(); j++) {
       sb.append(list.get(j).getName());
       sb.append(",");
     }
     sb.setLength(sb.length() - 1);
     sb.append(");");
     method.addBodyLine(sb.toString());
     topLevelClass.addMethod(method);
   }
   methods.clear();
 }
  @Override
  public void addClassElements(TopLevelClass topLevelClass) {
    Set<String> staticImports = new TreeSet<String>();
    Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>();

    staticImports.add("org.apache.ibatis.jdbc.SqlBuilder.BEGIN"); // $NON-NLS-1$
    staticImports.add("org.apache.ibatis.jdbc.SqlBuilder.UPDATE"); // $NON-NLS-1$
    staticImports.add("org.apache.ibatis.jdbc.SqlBuilder.SET"); // $NON-NLS-1$
    staticImports.add("org.apache.ibatis.jdbc.SqlBuilder.SQL"); // $NON-NLS-1$

    importedTypes.add(new FullyQualifiedJavaType("java.util.Map")); // $NON-NLS-1$

    Method method = new Method(getMethodName());
    method.setReturnType(FullyQualifiedJavaType.getStringInstance());
    method.setVisibility(JavaVisibility.PUBLIC);
    method.addParameter(
        new Parameter(
            new FullyQualifiedJavaType(
                "java.util.Map<java.lang.String, java.lang.Object>"), //$NON-NLS-1$
            "parameter")); //$NON-NLS-1$
    //        method.addJavaDocLine("根据主键更新所有字段的数据,不含BLOB字段。");
    context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);

    method.addBodyLine("BEGIN();"); // $NON-NLS-1$

    method.addBodyLine(
        String.format(
            "UPDATE(\"%s\");", //$NON-NLS-1$
            escapeStringForJava(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime())));
    method.addBodyLine(""); // $NON-NLS-1$

    for (IntrospectedColumn introspectedColumn : getColumns()) {
      StringBuilder sb = new StringBuilder();
      sb.append(getParameterClause(introspectedColumn));
      sb.insert(2, "record."); // $NON-NLS-1$

      method.addBodyLine(
          String.format(
              "SET(\"%s = %s\");", //$NON-NLS-1$
              escapeStringForJava(getAliasedEscapedColumnName(introspectedColumn)), sb.toString()));
    }

    method.addBodyLine(""); // $NON-NLS-1$

    FullyQualifiedJavaType example = new FullyQualifiedJavaType(introspectedTable.getExampleType());
    importedTypes.add(example);
    method.addBodyLine(
        String.format(
            "%s example = (%s) parameter.get(\"example\");", //$NON-NLS-1$
            example.getShortName(), example.getShortName()));

    method.addBodyLine("applyWhere(example, true);"); // $NON-NLS-1$
    method.addBodyLine("return SQL();"); // $NON-NLS-1$

    if (callPlugins(method, topLevelClass)) {
      topLevelClass.addStaticImports(staticImports);
      topLevelClass.addImportedTypes(importedTypes);
      topLevelClass.addMethod(method);
    }
  }
  @Override
  public void addImplementationElements(TopLevelClass topLevelClass) {
    Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>();
    Method method = getMethodShell(importedTypes);

    if (generateForJava5) {
      method.addSuppressTypeWarningsAnnotation();
    }

    StringBuilder sb = new StringBuilder();
    sb.append(method.getReturnType().getShortName());
    sb.append(" list = "); // $NON-NLS-1$
    sb.append(
        daoTemplate.getQueryForListMethod(
            introspectedTable.getIbatis2SqlMapNamespace(),
            introspectedTable.getSelectByExampleStatementId(),
            "example")); //$NON-NLS-1$
    method.addBodyLine(sb.toString());
    method.addBodyLine("return list;"); // $NON-NLS-1$

    if (context
        .getPlugins()
        .clientSelectByExampleWithoutBLOBsMethodGenerated(
            method, topLevelClass, introspectedTable)) {
      topLevelClass.addImportedTypes(importedTypes);
      topLevelClass.addMethod(method);
    }
  }
  @Override
  public void addImplementationElements(TopLevelClass topLevelClass) {
    Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>();
    Method method = getMethodShell(importedTypes);

    FullyQualifiedJavaType returnType = method.getReturnType();
    StringBuilder sb = new StringBuilder();

    if (returnType != null) {
      sb.append("Object newKey = "); // $NON-NLS-1$
    }

    sb.append(
        daoTemplate.getInsertMethod(
            introspectedTable.getIbatis2SqlMapNamespace(),
            introspectedTable.getInsertSelectiveStatementId(),
            "record")); //$NON-NLS-1$
    method.addBodyLine(sb.toString());

    if (returnType != null) {
      if ("Object".equals(returnType.getShortName())) { // $NON-NLS-1$
        // no need to cast if the return type is Object
        method.addBodyLine("return newKey;"); // $NON-NLS-1$
      } else {
        sb.setLength(0);

        if (returnType.isPrimitive()) {
          PrimitiveTypeWrapper ptw = returnType.getPrimitiveTypeWrapper();
          sb.append("return (("); // $NON-NLS-1$
          sb.append(ptw.getShortName());
          sb.append(") newKey"); // $NON-NLS-1$
          sb.append(")."); // $NON-NLS-1$
          sb.append(ptw.getToPrimitiveMethod());
          sb.append(';');
        } else {
          sb.append("return ("); // $NON-NLS-1$
          sb.append(returnType.getShortName());
          sb.append(") newKey;"); // $NON-NLS-1$
        }

        method.addBodyLine(sb.toString());
      }
    }

    if (context
        .getPlugins()
        .clientInsertSelectiveMethodGenerated(method, topLevelClass, introspectedTable)) {
      topLevelClass.addImportedTypes(importedTypes);
      topLevelClass.addMethod(method);
    }
  }
  protected void addDefaultNoArgConstructor(
      TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
    Method defaultNoArgConstructor = new Method();
    defaultNoArgConstructor.setVisibility(JavaVisibility.PUBLIC);
    defaultNoArgConstructor.setName(topLevelClass.getType().getShortName());
    defaultNoArgConstructor.setConstructor(true);
    defaultNoArgConstructor.addBodyLine("//Needed For JAXB serialization.");

    context
        .getCommentGenerator()
        .addGeneralMethodComment(defaultNoArgConstructor, introspectedTable);

    topLevelClass.addMethod(defaultNoArgConstructor);
  }
  private void addParameterizedConstructor(TopLevelClass topLevelClass) {
    Method method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setConstructor(true);
    method.setName(topLevelClass.getType().getShortName());
    context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);

    for (IntrospectedColumn introspectedColumn : introspectedTable.getAllColumns()) {
      method.addParameter(
          new Parameter(
              introspectedColumn.getFullyQualifiedJavaType(),
              introspectedColumn.getJavaProperty()));
    }

    boolean comma = false;
    StringBuilder sb = new StringBuilder();
    sb.append("super("); // $NON-NLS-1$
    for (IntrospectedColumn introspectedColumn : introspectedTable.getNonBLOBColumns()) {
      if (comma) {
        sb.append(", "); // $NON-NLS-1$
      } else {
        comma = true;
      }
      sb.append(introspectedColumn.getJavaProperty());
    }
    sb.append(");"); // $NON-NLS-1$
    method.addBodyLine(sb.toString());

    for (IntrospectedColumn introspectedColumn : introspectedTable.getBLOBColumns()) {
      sb.setLength(0);
      sb.append("this."); // $NON-NLS-1$
      sb.append(introspectedColumn.getJavaProperty());
      sb.append(" = "); // $NON-NLS-1$
      sb.append(introspectedColumn.getJavaProperty());
      sb.append(';');
      method.addBodyLine(sb.toString());
    }

    topLevelClass.addMethod(method);
  }
  @Override
  public void addImplementationElements(TopLevelClass topLevelClass) {
    Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>();
    Method method = getMethodShell(importedTypes);

    StringBuilder sb = new StringBuilder();
    sb.append("int rows = "); // $NON-NLS-1$
    sb.append(
        daoTemplate.getUpdateMethod(
            introspectedTable.getIbatis2SqlMapNamespace(),
            introspectedTable.getUpdateByPrimaryKeyWithBLOBsStatementId(),
            "record")); //$NON-NLS-1$
    method.addBodyLine(sb.toString());

    method.addBodyLine("return rows;"); // $NON-NLS-1$

    if (context
        .getPlugins()
        .clientUpdateByPrimaryKeyWithBLOBsMethodGenerated(
            method, topLevelClass, introspectedTable)) {
      topLevelClass.addImportedTypes(importedTypes);
      topLevelClass.addMethod(method);
    }
  }
  /**
   * 添加实现类
   *
   * @param introspectedTable
   * @param tableName
   * @param files
   */
  protected void addServiceImpl(
      TopLevelClass topLevelClass,
      IntrospectedTable introspectedTable,
      String tableName,
      List<GeneratedJavaFile> files) {
    topLevelClass.setVisibility(JavaVisibility.PUBLIC);
    // 设置实现的接口
    topLevelClass.addSuperInterface(interfaceType);

    if (enableAnnotation) {
      topLevelClass.addAnnotation("@Service");
      topLevelClass.addImportedType(service);
    }
    // 添加引用dao
    addField(topLevelClass, tableName);
    // 添加方法
    topLevelClass.addMethod(countByExample(introspectedTable, tableName));
    topLevelClass.addMethod(selectByPrimaryKey(introspectedTable, tableName));
    topLevelClass.addMethod(selectByExample(introspectedTable, tableName));

    /** type 的意义 pojo 1 ;key 2 ;example 3 ;pojo+example 4 */
    if (enableDeleteByPrimaryKey) {
      topLevelClass.addMethod(
          getOtherInteger("deleteByPrimaryKey", introspectedTable, tableName, 2));
    }
    if (enableUpdateByPrimaryKeySelective) {
      topLevelClass.addMethod(
          getOtherInteger("updateByPrimaryKeySelective", introspectedTable, tableName, 1));
    }
    if (enableUpdateByPrimaryKey) {
      topLevelClass.addMethod(
          getOtherInteger("updateByPrimaryKey", introspectedTable, tableName, 1));
    }
    if (enableDeleteByExample) {
      topLevelClass.addMethod(getOtherInteger("deleteByExample", introspectedTable, tableName, 3));
    }
    if (enableUpdateByExampleSelective) {
      topLevelClass.addMethod(
          getOtherInteger("updateByExampleSelective", introspectedTable, tableName, 4));
    }
    if (enableUpdateByExample) {
      topLevelClass.addMethod(getOtherInteger("updateByExample", introspectedTable, tableName, 4));
    }
    if (enableInsert) {
      topLevelClass.addMethod(getOtherInsertboolean("insert", introspectedTable, tableName));
    }
    if (enableInsertSelective) {
      topLevelClass.addMethod(
          getOtherInsertboolean("insertSelective", introspectedTable, tableName));
    }
    // 生成文件
    GeneratedJavaFile file =
        new GeneratedJavaFile(
            topLevelClass,
            project,
            context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
            context.getJavaFormatter());
    files.add(file);
  }
  @Override
  public List<CompilationUnit> getCompilationUnits() {
    FullyQualifiedTable table = introspectedTable.getFullyQualifiedTable();
    progressCallback.startTask(getString("Progress.6", table.toString())); // $NON-NLS-1$
    CommentGenerator commentGenerator = context.getCommentGenerator();

    FullyQualifiedJavaType type = new FullyQualifiedJavaType(introspectedTable.getExampleType());
    TopLevelClass topLevelClass = new TopLevelClass(type);
    topLevelClass.setVisibility(JavaVisibility.PUBLIC);
    commentGenerator.addJavaFileComment(topLevelClass);

    // add default constructor
    Method method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setConstructor(true);
    method.setName(type.getShortName());
    method.addBodyLine("oredCriteria = new ArrayList<Criteria>();"); // $NON-NLS-1$

    commentGenerator.addGeneralMethodComment(method, introspectedTable);
    topLevelClass.addMethod(method);

    // add field, getter, setter for orderby clause
    Field field = new Field();
    field.setVisibility(JavaVisibility.PROTECTED);
    field.setType(FullyQualifiedJavaType.getStringInstance());
    field.setName("orderByClause"); // $NON-NLS-1$
    commentGenerator.addFieldComment(field, introspectedTable);
    topLevelClass.addField(field);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setName("setOrderByClause"); // $NON-NLS-1$
    method.addParameter(
        new Parameter(FullyQualifiedJavaType.getStringInstance(), "orderByClause")); // $NON-NLS-1$
    method.addBodyLine("this.orderByClause = orderByClause;"); // $NON-NLS-1$
    commentGenerator.addGeneralMethodComment(method, introspectedTable);
    topLevelClass.addMethod(method);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setReturnType(FullyQualifiedJavaType.getStringInstance());
    method.setName("getOrderByClause"); // $NON-NLS-1$
    method.addBodyLine("return orderByClause;"); // $NON-NLS-1$
    commentGenerator.addGeneralMethodComment(method, introspectedTable);
    topLevelClass.addMethod(method);

    // add field, getter, setter for distinct
    field = new Field();
    field.setVisibility(JavaVisibility.PROTECTED);
    field.setType(FullyQualifiedJavaType.getBooleanPrimitiveInstance());
    field.setName("distinct"); // $NON-NLS-1$
    commentGenerator.addFieldComment(field, introspectedTable);
    topLevelClass.addField(field);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setName("setDistinct"); // $NON-NLS-1$
    method.addParameter(
        new Parameter(
            FullyQualifiedJavaType.getBooleanPrimitiveInstance(), "distinct")); // $NON-NLS-1$
    method.addBodyLine("this.distinct = distinct;"); // $NON-NLS-1$
    commentGenerator.addGeneralMethodComment(method, introspectedTable);
    topLevelClass.addMethod(method);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setReturnType(FullyQualifiedJavaType.getBooleanPrimitiveInstance());
    method.setName("isDistinct"); // $NON-NLS-1$
    method.addBodyLine("return distinct;"); // $NON-NLS-1$
    commentGenerator.addGeneralMethodComment(method, introspectedTable);
    topLevelClass.addMethod(method);

    // add field and methods for the list of ored criteria
    field = new Field();
    field.setVisibility(JavaVisibility.PROTECTED);

    FullyQualifiedJavaType fqjt =
        new FullyQualifiedJavaType("java.util.List<Criteria>"); // $NON-NLS-1$
    field.setType(fqjt);
    field.setName("oredCriteria"); // $NON-NLS-1$
    commentGenerator.addFieldComment(field, introspectedTable);
    topLevelClass.addField(field);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setReturnType(fqjt);
    method.setName("getOredCriteria"); // $NON-NLS-1$
    method.addBodyLine("return oredCriteria;"); // $NON-NLS-1$
    commentGenerator.addGeneralMethodComment(method, introspectedTable);
    topLevelClass.addMethod(method);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setName("or"); // $NON-NLS-1$
    method.addParameter(
        new Parameter(FullyQualifiedJavaType.getCriteriaInstance(), "criteria")); // $NON-NLS-1$
    method.addBodyLine("oredCriteria.add(criteria);"); // $NON-NLS-1$
    commentGenerator.addGeneralMethodComment(method, introspectedTable);
    topLevelClass.addMethod(method);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setName("or"); // $NON-NLS-1$
    method.setReturnType(FullyQualifiedJavaType.getCriteriaInstance());
    method.addBodyLine("Criteria criteria = createCriteriaInternal();"); // $NON-NLS-1$
    method.addBodyLine("oredCriteria.add(criteria);"); // $NON-NLS-1$
    method.addBodyLine("return criteria;"); // $NON-NLS-1$
    commentGenerator.addGeneralMethodComment(method, introspectedTable);
    topLevelClass.addMethod(method);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setName("createCriteria"); // $NON-NLS-1$
    method.setReturnType(FullyQualifiedJavaType.getCriteriaInstance());
    method.addBodyLine("Criteria criteria = createCriteriaInternal();"); // $NON-NLS-1$
    method.addBodyLine("if (oredCriteria.size() == 0) {"); // $NON-NLS-1$
    method.addBodyLine("oredCriteria.add(criteria);"); // $NON-NLS-1$
    method.addBodyLine("}"); // $NON-NLS-1$
    method.addBodyLine("return criteria;"); // $NON-NLS-1$
    commentGenerator.addGeneralMethodComment(method, introspectedTable);
    topLevelClass.addMethod(method);

    method = new Method();
    method.setVisibility(JavaVisibility.PROTECTED);
    method.setName("createCriteriaInternal"); // $NON-NLS-1$
    method.setReturnType(FullyQualifiedJavaType.getCriteriaInstance());
    method.addBodyLine("Criteria criteria = new Criteria();"); // $NON-NLS-1$
    method.addBodyLine("return criteria;"); // $NON-NLS-1$
    commentGenerator.addGeneralMethodComment(method, introspectedTable);
    topLevelClass.addMethod(method);

    method = new Method();
    method.setVisibility(JavaVisibility.PUBLIC);
    method.setName("clear"); // $NON-NLS-1$
    method.addBodyLine("oredCriteria.clear();"); // $NON-NLS-1$
    method.addBodyLine("orderByClause = null;"); // $NON-NLS-1$
    method.addBodyLine("distinct = false;"); // $NON-NLS-1$
    commentGenerator.addGeneralMethodComment(method, introspectedTable);
    topLevelClass.addMethod(method);

    // now generate the inner class that holds the AND conditions
    topLevelClass.addInnerClass(getGeneratedCriteriaInnerClass(topLevelClass));

    topLevelClass.addInnerClass(getCriteriaInnerClass(topLevelClass));

    topLevelClass.addInnerClass(getCriterionInnerClass(topLevelClass));

    List<CompilationUnit> answer = new ArrayList<CompilationUnit>();
    if (context.getPlugins().modelExampleClassGenerated(topLevelClass, introspectedTable)) {
      answer.add(topLevelClass);
    }
    return answer;
  }