当前位置: 首页 > 知识库问答 >
问题:

如何在select语句中从JOOQ模型调用postgresql函数?

拓拔俊德
2023-03-14
Exception in thread "main" org.jooq.exception.DataAccessException: SQL [select "tact_shard_0"."records"."id", "public"."merge_fields_json"("old_json" := ?, "new_json" := ?) from "shard_0"."records" where "shard_0"."records"."record_type" = ?]; ERROR: function public.merge_fields_json(old_json => character varying, new_json => character varying) does not exist
  Hint: No function matches the given name and argument types. You might need to add explicit type casts.
apply plugin: "java"
apply plugin: "application"

mainClassName = "com.vault.server.VaultServer"

sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8

defaultTasks = ['clean', 'build']

sourceSets {
    main {
        java { srcDir 'src' }
        resources { srcDir 'resources' }
    }
    test {
        java { srcDir 'test' }
        resources { srcDir 'resources' }
    }
    integTest {
        java.srcDir file('integrationTest')
        resources.srcDir file('resources')
        compileClasspath += sourceSets.main.output + sourceSets.test.output
        runtimeClasspath = output + compileClasspath
    }
}

repositories { mavenCentral() }

dependencies {
    compile "log4j:log4j:1.2.17"
    compile "org.apache.commons:commons-lang3:3.3.2"
    compile "org.jooq:jooq:3.8.4"
    compile "org.jooq:jooq-meta:3.8.4"
    compile "org.jooq:jooq-codegen:3.8.4"
    compile "com.google.guava:guava:17.0"
    compile "org.apache.httpcomponents:httpclient:4.3.4"
    compile "com.fasterxml.jackson.core:jackson-databind:2.4.1.1"
    compile "commons-io:commons-io:2.4"
    compile "org.eclipse.jetty.aggregate:jetty-all-server:8.1.15.v20140411"
    compile "org.yaml:snakeyaml:1.13"
    compile "redis.clients:jedis:2.6.0"
    compile 'org.apache.commons:commons-collections4:4.0'
    compile 'com.google.code.gson:gson:2.3.1'
    compile 'org.postgresql:postgresql:9.4.1208.jre7'
    compile 'org.apache.commons:commons-dbcp2:2.0.1'
    compile group: 'javax.ws.rs', name: 'jsr311-api', version: '1.1.1'
    compile group: 'com.sun.jersey', name: 'jersey-bundle', version: '1.19'
    compile group: 'com.sun.jersey', name: 'jersey-server', version: '1.19'
    compile group: 'com.sun.jersey', name: 'jersey-core', version: '1.19'
    compile group: 'com.sun.jersey', name: 'jersey-servlet', version: '1.19'
    compile group: 'com.sun.jersey', name: 'jersey-json', version: '1.19'
    compile group: 'com.sun.jersey', name: 'jersey-client', version: '1.19'
    compile group: 'com.sun.jersey', name: 'jersey-grizzly2', version: '1.19'
    compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
    testCompile group: 'org.glassfish.jersey.containers', name: 'jersey-container-grizzly2-servlet', version: '2.21'
    testCompile group: 'com.sun.jersey.jersey-test-framework', name: 'jersey-test-framework-core', version: '1.19'
    testCompile group: 'com.sun.jersey.jersey-test-framework', name: 'jersey-test-framework-external', version: '1.19'
    testCompile group: 'com.sun.jersey.jersey-test-framework', name: 'jersey-test-framework-http', version: '1.19'
    testCompile group: 'com.sun.jersey.jersey-test-framework', name: 'jersey-test-framework-grizzly2', version: '1.19'
    testCompile group: 'org.glassfish.jersey.test-framework.providers', name: 'jersey-test-framework-provider-jetty', version: '2.6'
    testCompile group: 'com.sun.jersey.test.framework', name: 'jersey-test-framework', version: '1.0.3.1'
    testCompile "org.hamcrest:hamcrest-library:1.3"
    testCompile "junit:junit:4.11"
    testCompile "org.mockito:mockito-all:1.8.4"
    testCompile "org.easymock:easymock:3.4"
    testCompile "cglib:cglib:3.2.4"
    testCompile "org.objenesis:objenesis:2.4"
}

configurations {
  integTestCompile { extendsFrom testCompile, compile }
  integTestRuntime { extendsFrom integTestCompile, testRuntime }
}

jar {
    // adds runtime dependencies to jar package
    from(configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }) {
        // remove all signature files
        exclude "META-INF/*.SF"
        exclude "META-INF/*.DSA"
        exclude "META-INF/*.RSA"
    }
    baseName = 'vault'
    manifest.attributes("Main-Class": mainClassName);
}

test {
  exclude 'com/vault/**'

  maxHeapSize '1024m'
  minHeapSize '512m'

}

task integTest(type: Test) {
  testClassesDir = project.sourceSets.integTest.output.classesDir
  classpath = project.sourceSets.integTest.runtimeClasspath
  exclude 'com/vault/**'

  maxHeapSize '1024m'
  minHeapSize '512m'
}

tasks.withType(Test) {
  testLogging { events 'passed' }

  if (System.getProperty('DEBUG', 'false') == 'true') {
    jvmArgs '-Xdebug',
      '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=4000'
  }
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.0'
}

task generateVersion() {
    def git_hash = new ByteArrayOutputStream()
    exec{
        executable "git"
        args "rev-parse", "--verify", "HEAD"
        standardOutput = git_hash
    }
    def version = git_hash.toString()
    new File("./resources/version").write(version)
    println "Git version is: " + version
}

build.dependsOn generateVersion

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'nu.studer:gradle-jooq-plugin:1.0.5'
        classpath 'org.postgresql:postgresql:9.4.1208.jre7' // database-specific JDBC driver
        classpath 'com.google.code.gson:gson:2.3.1'
    }
}
apply plugin: 'nu.studer.jooq'

jooq {
    recordsDb(sourceSets.main) {
        jdbc {
            driver = 'org.postgresql.Driver'
            url = 'jdbc:postgresql://localhost:5432/'
            user = 'postgres'
            password = 'xyz'
        }
        generator {
            name = 'org.jooq.util.DefaultGenerator'
            strategy {
                name = 'org.jooq.util.DefaultGeneratorStrategy'
            }
            database {
                name = 'org.jooq.util.postgres.PostgresDatabase'
                schemata {
                    schema {
                        inputSchema = "shard_0"
                    }
                }
            }
            customTypes {
                customType {
                    name = "JsonElement"
                    converter = "com.vault.dao.PostgresJSONGsonBinding"
                }
            }
            forcedTypes {
                forcedType {
                    name = "JsonElement"
                    expression = ".*data.*|.*tags.*"
                    types = ".*"
                }
            }
            generate {
                relations = true
                deprecated = false
                records = true
                immutablePojos = true
                fluentSetters = true
            }
            target {
                packageName = 'com.vault.jooq'
                directory = 'target/generated-sources'
            }
        }
    }
}
package com.vault.dao;


import static org.jooq.tools.Convert.convert;
import java.sql.*;
import java.util.Objects;
import java.util.logging.Logger;

import org.apache.log4j.spi.LoggerFactory;
import org.jooq.*;
import org.jooq.impl.DSL;
import com.google.gson.*;

// We're binding <T> = Object (unknown JDBC type), and <U> = JsonElement (user type)
public class PostgresJSONGsonBinding implements Binding<Object, JsonElement> {

  // The converter does all the work
  @Override
  public Converter<Object, JsonElement> converter() {
    return new Converter<Object, JsonElement>() {
      @Override
      public JsonElement from(Object t) {
        return t == null ? JsonNull.INSTANCE : new Gson().fromJson("" + t, JsonElement.class);
      }

      @Override
      public Object to(JsonElement u) {
        return u == null || u == JsonNull.INSTANCE ? null : new Gson().toJson(u);
      }

      @Override
      public Class<Object> fromType() {
        return Object.class;
      }

      @Override
      public Class<JsonElement> toType() {
        return JsonElement.class;
      }
    };
  }

  // Rending a bind variable for the binding context's value and casting it to the json type
  @Override
  public void sql(BindingSQLContext<JsonElement> ctx) throws SQLException {
    ctx.render().visit(DSL.val(ctx.convert(converter()).value())).sql("::json");
  }

  // Registering VARCHAR types for JDBC CallableStatement OUT parameters
  @Override
  public void register(BindingRegisterContext<JsonElement> ctx) throws SQLException {
    ctx.statement().registerOutParameter(ctx.index(), Types.VARCHAR);
  }

  // Converting the JsonElement to a String value and setting that on a JDBC PreparedStatement
  @Override
  public void set(BindingSetStatementContext<JsonElement> ctx) throws SQLException {
    ctx.statement().setString(ctx.index(), Objects.toString(ctx.convert(converter()).value(), null));
  }

  // Getting a String value from a JDBC ResultSet and converting that to a JsonElement
  @Override
  public void get(BindingGetResultSetContext<JsonElement> ctx) throws SQLException {
    ctx.convert(converter()).value(ctx.resultSet().getString(ctx.index()));
  }

  // Getting a String value from a JDBC CallableStatement and converting that to a JsonElement
  @Override
  public void get(BindingGetStatementContext<JsonElement> ctx) throws SQLException {
    ctx.convert(converter()).value(ctx.statement().getString(ctx.index()));
  }

  // Setting a value on a JDBC SQLOutput (useful for Oracle OBJECT types)
  @Override
  public void set(BindingSetSQLOutputContext<JsonElement> ctx) throws SQLException {
    throw new SQLFeatureNotSupportedException();
  }

  // Getting a value from a JDBC SQLInput (useful for Oracle OBJECT types)
  @Override
  public void get(BindingGetSQLInputContext<JsonElement> ctx) throws SQLException {
    throw new SQLFeatureNotSupportedException();
  }
} 

共有1个答案

孟哲
2023-03-14

这里有两件事你应该纠正:

为了解决这个问题,您可以修改强制类型声明:

        forcedTypes {
            forcedType {
                name = "JsonElement"
                expression = ".*data.*|.*tags.*|.*\.(old|new)_json"
                types = ".*"
            }
        }

修改还将匹配名为old_jsonnew_json的函数参数。现在,这还没有完成,这就是jOOQ默认绑定字符串的原因。

@Override
public void sql(BindingSQLContext<JsonElement> ctx) throws SQLException {
    ctx.render().visit(DSL.val(ctx.convert(converter()).value())).sql("::jsonb");
    //                                                                 ^^^^^^^ fix here
}
 类似资料:
  • 我的Postgres版本:“PostgreSQL 9.4.1,由Visual C++build 1800编译,32位” 我要处理的桌子;包含列 EventTime-Timestamp不带时区 SerialNumber-可变字符(32) sourceid-integer 和其他4列 下面是我的select语句

  • 问题内容: 我创建结合两个表的SELECT语句,和的基础上,参照表,并在一个映射到。映射到未在数据库中的任何地方出现,我想创建“关于即时”的SELECT语句中。以下是我的架构: 这是一些示例数据: 我需要从输出表中获取给定设备每个区域的关联字段。每个映射到一个。对于此示例: 处理映射的一种方法是创建一个新表 并使用以下SQL获取设备1的所有区域以及标志: 但是,我正在寻找一种创建区域编号到输出类型

  • 问题内容: 在PostgreSQL 9.1中,PL / pgSQL给出了一个查询: 其中的类型(例如“ table_name”)。 如何获得“ relname”的适当值,该值可直接在语句中用作: 在PL / pgSQL脚本中? 使用如: 失败与: “(”或附近的语法错误LINE 55:UPDATE quote_ident(r.relname)…。 我正在使用的完整代码: 我敢肯定这种事情经常发生,

  • 问题内容: 在WHERE子句中有使用SELECT语句描述的名称吗?这是好/不好的做法吗? 这会是更好的选择吗? 它远没有那么优雅,但是运行起来比以前的版本要快。我不喜欢它,因为它在GUI中没有非常清晰地显示(并且SQL初学者需要理解它)。我可以将其分为两个独立的查询,但是随后事情变得混乱了…… 注意:我不仅需要日期和分数(例如姓名) 问题答案: 称为相关子查询。它有它的用途。

  • 数据库:Sybase Advantage 11 在我对数据进行规范化的过程中,我试图删除从以下语句中得到的结果:

  • 我的问题是, 如何正确创建select语句? 如何最好地添加空格分隔符? 是否有更好的替代JOOQ(when=case)条件子句?