有没有更好的方法用java从用户输入创建非常动态的sql?

azpvetkf  于 2021-06-20  发布在  Mysql
关注(0)|答案(0)|浏览(178)

报告是我们需求的一个重要部分,我的任务是创建一个通用的报告框架,允许用户指定希望从哪些列(跨多个表)获取数据、应用哪些条件以及希望数据采用哪种输出格式。
我需要将这些信息存储到一个'模板'对象,这样我就可以产生相同的报告一遍又一遍的结果一致。一旦我完成,我将给用户指定一个重复出现选项的能力,自动调用他们的'模板'每天,每周,每月,或每年如果他们选择启用它。
我想避免使用sql字符串作为输入来消除sql注入的风险,我做了一些工作,但似乎有比我现在做的更好的方法。
我创建了4种类型的java类来构造查询。
query:这是用户将提供的,用json指定他们的sql。
筛选器:用于指定要应用于查询的条件。
select:用于指定要从结果返回的列。
联接:用于指定联接应连接另一个表。
注意:我正在对照hibernate表和列注解验证所有表名和字段名,以确保它们有效。
缺少的是使用别名和not子句的功能,我稍后将添加这些功能。
我现在正在使用mysql,我的查询不需要与数据库无关。如果我需要重写它,如果我搬到另一个供应商,那就这样吧。

// This is my RequestBody
public class Query {

    private String from;
    private Filter filter;
    private List<Join> joins; 
    private List<Select> selections;

--

@ApiModel(value="filter", discriminator = "type", subTypes = {
          JoinerFilter.class, MultiFilter.class, SimpleFilter.class
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, 
              include = JsonTypeInfo.As.PROPERTY, 
              property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = JoinerFilter.class, name = "joiner"),
    @JsonSubTypes.Type(value = MultiFilter.class, name = "multi"),
    @JsonSubTypes.Type(value = SimpleFilter.class, name = "simple")
})
public abstract class Filter {

    public abstract void validate();

    public abstract String toSQL();
}

--

// This Filter is used to concatenate 2 Filters
@ApiModel(value = "joiner", parent = Filter.class)
public class JoinerFilter extends Filter {

    private enum JoinerCondition {
        AND, OR
    }

    private JoinerCondition condition;
    private Filter lhsFilter;
    private Filter rhsFilter;

--

// This Filter is used to perform a simple evaluation
@ApiModel(value = "simple", parent = Filter.class)
public class SimpleFilter extends Filter {

    private enum SimpleCondition {
        EQUAL, GREATER_THAN, LESS_THAN, LIKE
    }

    private String table;
    private String field;
    private String lhsFunction;
    private String rhsFunction;
    private SimpleCondition condition;
    private String value;

--

// This Filter is used to search multiple values at once
@ApiModel(value = "multi", parent = Filter.class)
public class MultiFilter extends Filter {

    private enum MultiCondition {
        BETWEEN, IN
    }

    private String table;
    private String field;
    private String lhsFunction;
    private String rhsFunction;
    private MultiCondition condition;
    private List<String> values;

--

public class Select {

    private String table;
    private String field;
    private String function;

--

public class Join {

    private enum JoinType {
        INNER_JOIN, LEFT_JOIN, CROSS_JOIN
    }

    private Filter on;
    private String table;
    private JoinType type;

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题