简体   繁体   English

如何消费 java Map<string,object> 在 JOOQ 中生成插入和更新 sql 查询(不生成代码)?</string,object>

[英]How to consume java Map<String,Object> to generate insert and update sql queries in JOOQ (without code generation)?

We are developing an application where we will generate forms at run time.我们正在开发一个应用程序,我们将在运行时生成 forms。 Now we need to perform CRUD operations on the data of the dynamic form.现在我们需要对动态表单的数据进行 CRUD 操作。

we want to save the record into the table by writing我们想通过写入将记录保存到表中

Map<String, String> map = new TreeMap<>();
    map.put("name","User Name");
    map.put("dob", "30-3-1995");
    map.put("address", "Address Line");
    map.put("city", "Jaipur");
    /* insert into user table */
    db.insert("user",map); // SAME AS JPA

Does java spring boot provides query builder like php CodeIgniter query builder java spring 启动是否提供查询生成器,例如 php Z8DD99C63C4DFD62F192784327

I am trying to use JOOQ to achieve the same.我正在尝试使用 JOOQ 来实现相同的目标。

    @Override
    public void testingJooq(){
        Field<String> username = field("username", String.class, "harigyan2");
        // How bindings bind the value to the Field?
        Field<String> password = field("password", String.class, "abcd");
        Field<String> email = field("email", String.class, "hg2@server.com");
        Field<Boolean> enabled = field("enabled", Boolean.TYPE, true);
        // list of columns to insert
        List<? extends Field<? extends Serializable>> columns = Arrays.asList(username, password, email, enabled);
        // list of corresponding values as columns 
        List<? extends Field<? extends Serializable>> values = Arrays.asList(field("harigyan2", String.class), field("pwdhere", String.class), field("harigyan@server.com", String.class), field("1", Boolean.TYPE));
        this.create.insertInto(table("user"), columns)
                .values(values).getSQL();
    }

The problems with the above code is that:上述代码的问题在于:

  1. the two lists columns and values should be in the same sequence and两个列表的列和值应该是相同的顺序,并且
  2. data types in the values should be matched with the table column data type in the code值中的数据类型应与代码中的表列数据类型匹配

Note: We can't use JOOQ with code generation because all the forms will be dynamic and will not have any corresponding Java Class (Entity class).注意:我们不能将 JOOQ 与代码生成一起使用,因为所有 forms 都是动态的,并且不会有任何对应的 Java Class(实体类)。

Map<String, Object> map = new TreeMap<>();
    map.put("name","User Name");
    map.put("dob", "30-3-1995");
    map.put("address", "Address Line");
    map.put("city", "Jaipur");
    /* insert into user table */
   this.create.insertInto(table('user')).values(map).execute();

It will be useful if above JOOQ insert statement find the fields names (map key name as column name) and values from the map<key, value> and create a insert sql statement.如果上面的 JOOQ 插入语句从 map<key, value> 中找到字段名称(映射键名作为列名)和值并创建插入 sql 语句,这将很有用。

We used php CodeIgniter in a project to build sql queries Php CodeIgniter Query Builder so we are trying to find something similar in java also. We used php CodeIgniter in a project to build sql queries Php CodeIgniter Query Builder so we are trying to find something similar in java also.

Your usage of plain SQL templates for column names您对列名的普通 SQL 模板的使用

Field<String> username = field("username", String.class, "harigyan2");

This doesn't do what you think it does.这并不像你认为的那样。 You're using a plain SQL template .您使用的是普通的 SQL 模板 But there's no bind parameter marker ( ? ), so your bind value "harigyan2" is superfluous.但是没有绑定参数标记( ? ),所以你的绑定值"harigyan2"是多余的。 Remove the value to do this, instead:删除值来执行此操作,而不是:

Field<String> username = field("username", String.class);

Or, avoid using plain SQL templates if you don't need them, eg by writing:或者,如果您不需要它们,请避免使用普通的 SQL 模板,例如通过编写:

Field<String> username = field(name("username"), String.class);

See also:https://blog.jooq.org/2020/04/03/whats-a-string-in-the-jooq-api另见:https://blog.jooq.org/2020/04/03/whats-a-string-in-the-jooq-api

Your usage of plain SQL templates for bind values您对绑定值的普通 SQL 模板的使用

Don't do this!不要这样做!

Arrays.asList(
  field("harigyan2", String.class), 
  field("pwdhere", String.class), 
  field("harigyan@server.com", String.class), 
  field("1", Boolean.TYPE)
);

You're again using plain SQL templates, meaning your strings will be included in your SQL statements verbatim .您再次使用普通的 SQL 模板,这意味着您的字符串将逐字包含在您的 SQL 语句中。 This leads to syntax errors and SQL injection.这会导致语法错误和 SQL 注入。 Use bind values by wrapping the values using DSL.val()通过使用DSL.val()包装值来使用绑定值

Arrays.asList(
  val("harigyan2", String.class), 
  val("pwdhere", String.class), 
  val("harigyan@server.com", String.class), 
  val("1", Boolean.TYPE)
);

Alternatively, re-use the type information from your previously defined field references:或者,重新使用之前定义的字段引用中的类型信息:

Arrays.asList(
  val("harigyan2", username), 
  val("pwdhere", password), 
  val("harigyan@server.com", email), 
  val("1", enabled)
);

Using a map directly直接使用 map

You can!你可以! If you have a Map<String, Object> , Map<Name, Object> or Map<Field<?>, Object> , just pass it to the insert statement:如果您有Map<String, Object>Map<Name, Object>Map<Field<?>, Object> ,只需将其传递给插入语句:

create.insertInto(table("user")).set(map).execute();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM