java - 如何处理JOOQ中的外键关系

标签 java jooq

我必须为具有某些给定属性的实体创建新记录。

将更像是使用 JOOQ 替换一些值来处理现有记录。我可以为单个表执行此操作,但我正在寻找为相关实体执行此操作的正确方法。

例如:主表是Student,我需要一个10年级学生的新记录。我可以获取一个10年级学生的记录并更改名称并保存。

    Result<Record> result= context.select().from(Student.STUDENT).where(Student.STUDENT.GRADE.eq(studRecords.getGrade()))
                .fetch();
        StudentRecord appER=(StudentRecord ) result.get(0);
            Field<?>[] fields= Student.STUDENT.fields();
for (Field<?> field : fields)
            {
                //System.out.println(field.getName() + " = " +field.getType() + field.getDataType() + "  " + field.getBinding());
                DataType<Comparable> dt= (DataType<Comparable>) field.getDataType() ;
              //if(!dt.getSQLDataType().nullable()  && !dt.getSQLDataType().defaulted() && studRecords.getValue(field) ==null)
                if(studRecords.getValue(field) ==null)
              {  
                  if(studRecords.getTable().getPrimaryKey().getFields().contains(field)){
                      System.out.println("Primary key is null . New Record Adding");
                      continue;
                  }
                  if(t.getTable().getReferences().contains(field))
                      System.out.println("Foreign key");
                  Object obj=appER.getValue(field);
                    if(field.getType().equals(Integer.class))
                     {
                      studRecords.setValue((Field<Comparable>)field,(obj!=null?(Integer)obj :new Integer(0)));
                     }
                      if(field.getType().equals(Boolean.class)){
                          studRecords.setValue((Field<Comparable>)field,(obj!=null?(Boolean)obj :new Boolean(false)));
                      }
                      if(field.getType().equals(Byte.class)){
                          studRecords.setValue((Field<Comparable>)field,(obj!=null?(Byte)obj :new Byte((byte) 0)));
                      }
                      if(field.getType().getName().equals("java.lang.String")){
                          studRecords.setValue((Field<Comparable>)field,(obj!=null?(String)obj :new String("")));
                      }
                      if(field.getType().equals(Double.class)){
                          studRecords.setValue((Field<Comparable>)field,(obj!=null?(Double)obj :new Double(0.0)));
                      }
                      if(field.getType().equals(Long.class)){
                          studRecords.setValue((Field<Comparable>)field,(obj!=null?(Long)obj :new Long(0)));
                      }
              }
            }

但现在我还想创建相关对象,如地址、爱好等相关表。

最好的方法是什么?

最佳答案

如果我没有理解错的话,您的大部分代码示例看起来都没有必要。要更新学生姓名,您可以做更多类似的事情:

final List<StudentRecord> students = context.selectFrom(Student.STUDENT)
       .where(Student.STUDENT.GRADE.eq(10))
       .fetchInto(StudentRecord.class);
for (final StudentRecord student : students) {
    student.setName("some other name");
}
context.batchStore(students).execute();

重新添加其他表,应该可以按照添加student表的方式进行。如果您的数据库看起来像这样,一个学生有一个地址但可能有很多爱好:

create table address(
    id serial primary key,
    street text not null
    -- other fields, etc
); 
create table student(
    id serial primary key,
    name text not null,
    grade int not null,
    address_id not null references address(id)
    -- ...
);
create table hobby(
    id serial primary key,
    student_id not null references student(id),
    name text
    -- ...
); 

并且假设您在相同的模式中拥有它并且 jOOQ 已经在获取您的学生表,那么您的 hobbyaddress 表也将被获取。然后你可以像在常规 sql 中一样获取:

final Result<Record<Integer,String,String,String>> ret = context
        .select(Student.STUDENT.ID,
                Student.STUDENT.NAME,
                Address.ADDRESS.STREET,
                Hobby.HOBBY.NAME)
        .from(Student.STUDENT)
        .join(Hobby.HOBBY)
        .on(Student.STUDENT.ID.eq(Hobby.HOBBY.STUDENT_ID))
        .join(Address.ADDRESS)
        .on(Student.STUDENT.ADDRESS_ID.eq(Address.ADDRESS.ID))
        .where(Student.STUDENT.GRADE.eq(10))
        .orderBy(Student.STUDENT.NAME.asc())
        .fetch();
Integer lastStudentId = null;
for (final Record<Integer,String,String,String> val : ret) {
    final Integer studentId = val.getValue(Student.STUDENT.ID,);
    if (!studentId.equals(lastStudentId)) {
        System.out.println("Student " + val.getValue(Student.STUDENT.NAME)
                + " who lives on " + val.getValue(Address.ADDRESS.STREET)
                + " street has hobbies:"
        );
    }
    lastStudentId = studentId;
    System.out.println("\t" + val.getValue(Hobby.HOBBY.NAME));
}

如果您的问题更多是关于您的数据库的设计(即您的地址应该是个人的并且有自己的 pk 还是应该由学生拥有并与学生具有相同的 ID,诸如此类),那么我认为这不是一个 jOOQ 问题,可能更适合在这里发布:https://dba.stackexchange.com/?tags=database-design .

关于java - 如何处理JOOQ中的外键关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30964441/

相关文章:

java - JOOQ:不推荐使用 Condition 类型中的方法 and(Boolean)

java - 在java澄清中使用+=和三元运算符

java - 从 PHP 访问 java 应用程序

java - 在jooq的seek api中使用子查询

java - JOOQ 中的提交钩子(Hook)

java - postgres 'WITH' 子句与 jooq

gradle - 如何在 Gradle 中使用 jOOQ 代码生成?

java - 哈希码和等于实现

java - 使用注释指定哪些类/接口(interface)应该生成javadoc?

java - 从 JNI 函数抛出 Java 异常后是否调用 C++ 析构函数?