如何处理JOOQ中的外键关系
How to handle foreign keys relation in JOOQ
我必须为具有某些给定属性的实体创建新记录。
将更像是使用 JOOQ
替换一些值来处理现有记录。我可以为单个 table 执行此操作,但我正在寻找为相关实体执行此操作的正确方法。
例如:主要table是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)));
}
}
}
但现在我还想创建相关的对象,如地址、相关的爱好 tables。
最好的方法是什么?
如果我没有理解错的话,你的大部分代码示例看起来都没有必要。要更新学生姓名,您可以做更多类似的事情:
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();
要添加其他 table,您应该可以像添加学生 table 一样进行操作。如果你的数据库看起来像这样,一个学生有一个地址但可能有很多爱好:
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 已经在接你的学生 table,你的 hobby
和 address
table 也将被选择向上。然后你可以像在常规 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.
我必须为具有某些给定属性的实体创建新记录。
将更像是使用 JOOQ
替换一些值来处理现有记录。我可以为单个 table 执行此操作,但我正在寻找为相关实体执行此操作的正确方法。
例如:主要table是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)));
}
}
}
但现在我还想创建相关的对象,如地址、相关的爱好 tables。
最好的方法是什么?
如果我没有理解错的话,你的大部分代码示例看起来都没有必要。要更新学生姓名,您可以做更多类似的事情:
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();
要添加其他 table,您应该可以像添加学生 table 一样进行操作。如果你的数据库看起来像这样,一个学生有一个地址但可能有很多爱好:
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 已经在接你的学生 table,你的 hobby
和 address
table 也将被选择向上。然后你可以像在常规 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.