2015-06-21 52 views
0

我必須創建一個具有某些給定屬性的實體的新記錄。如何處理JOOQ中的外鍵關係

更像是應對現有記錄,其中一些值被替換爲JOOQ。我可以爲單個表格做到這一點,但我正在爲相關實體找到正確的方法。

例如:主表是學生,我需要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))); 
         } 
       } 
      } 

但是現在我也想創建相關對象,如地址,愛好等相關表。

什麼是最好的方法來做到這一點?

回答

3

如果我理解正確,大部分代碼示例看起來相當不必要。要更新學生的姓名,你可以做更多的事情是這樣的:

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(); 

再添加其它的表,你應該能夠做到這一點,你添加的學生表的方式相同。如果你的數據庫中查找的東西沿着這些線路,其中一個學生都有一個地址,但可以有很多愛好:

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還是應該爲所擁有的該學生和學生的身份證號碼相同),那麼我認爲這不是一個jOOQ問題,可能更適合張貼在這裏:https://dba.stackexchange.com/?tags=database-design

+0

感謝您的及時回覆@Brent Douglas。我試圖實現這一點,工作得很好。但我的問題是,是否有辦法瞭解外鍵在JOOQ中的給定表中引用的表類型。就像我們在Hibernate中有相關的字段映射到參考表並使用Hibernate.initialise()加載的那樣? – msood

+1

@msood如果確實如此,我會很驚訝。我認爲jOOQ的重點在於它更像直接使用java,而不是完整的ORM。就個人而言,我認爲外鍵總是應該以

_id作爲後綴,所以public.student.hobby_id和public.student.favourite_hobby_id會指向愛好表(但這只是我個人的偏好),然後您可以將其隱藏在字段名稱之外,儘管我不會推薦它。國際海事組織,如果你可以設計你的應用程序而不需要那種魔法,你會變得更好。 –