使用普通的intellij想法生成POJO @OneToMany

问题描述 投票:0回答:1

我将项目从Netbeans迁移到IntelliJ Idea,到目前为止,几乎所有工作都很好,但是,与Netbeans一样,我在映射实体时遇到了问题。我已经用groovy修改了脚本,并且几乎成功了一切,除了尝试获取JPA @OneToMany关系时,根据我的数据库模型,这种关联非常重要。

我的常规脚本

import com.intellij.database.model.DasConstraint
import com.intellij.database.model.DasTable
import com.intellij.database.model.DasObject
import com.intellij.database.model.DasDataSource
import com.intellij.database.model.ObjectKind
import com.intellij.database.util.Case
import com.intellij.database.util.DasUtil
import com.intellij.database.psi.DbColumn
import com.intellij.database.psi.DbColumnImpl
import com.intellij.database.psi.DbForeignKeyImpl
//@Grab('com.oracle:ojdbc6:11g')
//@GrabConfig(systemClassLoader=true)
import groovy.sql.Sql
//import java.sql.*
//import oracle.jdbc.driver.*

packageName = "co.com.project..."
author = "enginner"

forceNullable = (~/^(?:createdAt|created_at|updatedAt|updated_at)$/)
typeMapping = [
        (~/(?i)int|number|numeric/)       : "BigDecimal",
        (~/(?i)float|double|decimal|real/): "double",
        (~/(?i)datetime|timestamp/)       : "java.sql.Timestamp",
        (~/(?i)date/)                     : "Date",
        (~/(?i)time/)                     : "java.sql.Time",
        (~/(?i)varchar|varchar2|clob/)    : "String",
        (~/(?i)/)                         : "String"
]

FILES.chooseDirectoryAndSave("Choose directory", "Choose where to store generated files") { dir ->
    SELECTION.filter { it instanceof DasTable && it.getKind() == ObjectKind.TABLE }.each { generate(it, dir) }
    //SELECTION.filter { it instanceof DasDataSource }.each { generateListChild(it, dir) }
}

/*def generateListChild(datasource, dir){
    def info = datasource
    new File(dir,  "test.java").withPrintWriter { out -> generateListChildExtend(out, info) }
}

def generateListChildExtend(out, datasource){
    out.println "hello world"
    out.println "datasource $datasource"
}*/

def generate(table, dir) {
    def className = javaName(table.getName(), true)
    def fields = calcFields(table)
    new File(dir, className + ".java").withPrintWriter { out -> generate(out, className, fields, table) }
}

def connectDatabase(){
    def url = 'jdbc:oracle:thin:localhost:1521:database'
    def user = 'myUser'
    def password = 'password'
    def driver = 'oracle.jdbc.driver.OracleDriver'
    def sql = Sql.newInstance(url, user, password, driver)
        sql.close()
    //execute statement...
}

def generate(out, className, fields, table) {
    //This doesn't worked 
    connectDatabase()      

    def tableName = table.getName();    
    out.println "package $packageName"
    out.println ""
    out.println "import java.io.Serializable;"
    out.println "import java.math.BigDecimal;"
    out.println "import java.util.Date;"
    out.println "import java.util.List;"
    out.println "import javax.persistence.*;"
    out.println "import javax.validation.constraints.*;"
    out.println ""
    out.println "/**"
    out.println "*"
    out.println "* @author ${author}"
    out.println "*/"
    out.println "@Entity"
    out.println "@Table(name=\"${tableName}\")"
    out.println "public class ${underscoreToCamelCase(className)} implements Serializable {"
    out.println ""
    out.println "  private static final long serialVersionUID = 1L;"
    out.println ""
    def primaryKeyField
    fields.each() {
        if (it.annos != "") out.println "  ${it.annos}"
        if (it.primary) {
            primaryKeyField = underscoreToCamelCase(it.name)
            out.println "  @Id"
            out.println "  @Basic(optional = false)"
            out.println "  @GeneratedValue(generator = \"SQ_${tableName}\")"
            out.println "  @SequenceGenerator(name = \"SQ_${tableName}\", sequenceName = \"SQ_${tableName}\")"
        }
        if (it.nullable && !it.foreign) out.println "  @NotNull"
        if (it.foreign) {
            out.println "  @JoinColumn(name = \"${it.colName}\", referencedColumnName = \"${it.colName}\")"
            out.println "  @ManyToOne(fetch = FetchType.LAZY)"
            it.foreignKeys.each() { fk ->
                if (DasUtil.containsName(it.colName, fk.getColumnsRef())) {
                    out.println "  private ${underscoreToCamelCase(javaName(fk.getRefTableName(), true))} ${underscoreToCamelCase(it.name)};"
                }
            }
        } else {
            out.println "  @Column(name=\"${it.colName}\")"
            if (it.type.equals("String")) out.println "  @Size(max = ${it.size})"
            if (it.type.equals("Date")) out.println "  @Temporal(TemporalType.TIMESTAMP)"
            out.println "  private ${it.type} ${underscoreToCamelCase(it.name)};"
        }
        out.println ""
    }

    fields.each() {
        out.println ""
        if (it.foreign) {
            it.foreignKeys.each() { fk ->
                if (DasUtil.containsName(it.colName, fk.getColumnsRef())) {
                    out.println "  private ${underscoreToCamelCase(javaName(fk.getRefTableName(), true))} get${it.name.capitalize()}() {"
                    out.println "    return ${it.name};"
                    out.println "  }"
                    out.println ""
                    out.println "  public void set${it.name.capitalize()}(${underscoreToCamelCase(javaName(fk.getRefTableName(), true))} ${it.name}) {"
                    out.println "    this.${it.name} = ${it.name};"
                    out.println "  }"
                }
            }
        } else {
            out.println "  public ${it.type} get${it.name.capitalize()}() {"
            out.println "    return ${it.name};"
            out.println "  }"
            out.println ""
            out.println "  public void set${it.name.capitalize()}(${it.type} ${it.name}) {"
            out.println "    this.${it.name} = ${it.name};"
            out.println "  }"
        }
    }
    out.println ""
    out.println "  @Override"
    out.println "  public String toString() {"
    out.println "        return \"${packageName}.className[${primaryKeyField}=\" + ${primaryKeyField} + \"];\""
    out.println "  }"
    out.println ""
    out.println "}"
}

def calcFields(table) {
    DasUtil.getColumns(table).reduce([]) { fields, col ->
        def spec = Case.LOWER.apply(col.getDataType().getSpecification())
        def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
        def colName = (String) col.getName()
        def size = col.getDataType().getLength()
        def nullable = col.isNotNull()
        def foreign = DasUtil.isForeign(col)
        def foreignKeys = DasUtil.getForeignKeys(table)
        fields += [[
                           name       : javaName(col.getName(), false),
                           type       : typeStr,
                           annos      : "",
                           colName    : col.getName(),
                           size       : size,
                           primary    : DasUtil.isPrimary(col),
                           nullable   : nullable,
                           foreign    : foreign,
                           foreignKeys: foreignKeys
                   ]]
    }
}

def javaName(str, capitalize) {
    def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
            .collect { Case.LOWER.apply(it).capitalize() }
            .join("")
            .replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_")
    capitalize || s.length() == 1 ? s : Case.LOWER.apply(s[0]) + s[1..-1]
}

String underscoreToCamelCase(String underscore) {
    if (!underscore || underscore.isAllWhitespace()) {
        return ''
    }
    return underscore.replaceAll(/_\w/) { it[1].toUpperCase() }
}

在使用类的不同方法(com.intellij.database.util.DasUtil进行了几次测试(但失败)之后,我决定尝试执行以下查询,该查询返回与@OneToMany相关的所有表表的生成。

SELECT tableChilds.*,
       (CASE WHEN rowRepeat > 1 THEN tableName||'_LIST'||rowRepeat ELSE tableName||'_LIST' END) AS childList
  FROM (SELECT b.table_name tableName,
               b.column_name columnName,
               row_number() over (partition by b.table_name order by 1) rowRepeat
          FROM all_cons_columns b,
               all_cons_columns c,
               all_constraints a 
         WHERE b.constraint_name = a.constraint_name
           AND a.owner           = b.owner
           AND b.position        = c.position
           AND c.constraint_name = a.r_constraint_name
           AND c.owner           = a.r_owner
           AND a.constraint_type = 'R'
           AND a.owner           = 'OWNER'
           AND c.table_name      = 'MY_TABLE'
         ORDER BY 1
     ) tableChilds;

但是,我没有成功地从该脚本重用数据源与数据库的连接,也没有创建新的连接来运行此查询并解决我的问题。因此,是否有可能使用IntelliJ提供的类来映射这种类型的关联?或者考虑到我已经使用@Grab批注导入驱动程序,如何从该脚本创建与DB的新连接? JDBC吗?

我讨厌只为映射我的实体而不得不再次打开Netbeans,有什么想法可以解决这个问题?我使用最新版本的intellij idea(2019.2.2)。

jpa intellij-idea groovy one-to-many pojo
1个回答
0
投票

您是否找到了解决方案?我正在寻找同一件事。

© www.soinside.com 2019 - 2024. All rights reserved.