จาก JPA ถึง MyBatis: คีย์คอมโพสิต?

ฉันมีโมเดลโดเมนที่มีโครงสร้างก่อนหน้านี้สำหรับ JPA ดังนี้:

@Entity
@Table(name="TABLE")
public class MyClassImpl implements MyClass, Serializable {

   @Embeddable
   public static class ID {
   @Column( name = "COL_1", nullable = false)
   protected int id1;
   @Column( name = "COL_2", nullable = false)
   protected int id2;
   @Column( name = "COL_3", nullable = false, unique = true)
   protected String id3;

   ...

   }

   @EmbeddedId
   protected ID id;
   @Column(name = "COL_4")
   protected String otherData;
   ...

}

ตอนนี้ฉันกำลังย้ายไปที่ MyBatis และฉันมีข้อสงสัยเกี่ยวกับการทำแผนที่อะไรทำนองนั้น

ฉันรู้ว่าฉันสามารถสร้างผลลัพธ์ได้เช่น:

<resultMap id="myClassResultMap" type="MyClass">
   <association property="id" javaType="MyClass.ID">
      <id property="id1" column="COL_1" />
      <id property="id2" column="COL_2" />
      <id property="id3" column="COL_3" />
   </association>

   <result property="otherData" column="COL_4" />
   ...
</resultMap>

ฟิลด์ <id ... /> ใน association จะถูกนำมาใช้เป็นรหัสของคลาสหรือไม่ จะเป็นอย่างไรหากฉันต้องการทำเครื่องหมาย id เป็น final แล้วส่งต่อให้ Constructor?

ฉันใช้ ID นั้นสำหรับคลาสอื่นเช่นกัน:

@Entity
@Table(name = "OTHERTABLE")
public class MyOtherClassImpl implements MyOtherClass, Serializable {

   @Embeddable
   public static class ID {

      @Embedded
      MyClass.ID ref;

      @Column(name = "ID", nullable = false, unique = true)
      protected int id;

      //methods
   }

   @EmbeddedId
   protected ID id;
   @Column(name = "COL_5")
   protected String otherData;
   ...
}

เนื่องจากทั้งสองตารางแชร์คีย์หลัก 3 อัน

สามารถรักษาโครงสร้างดังกล่าวได้หรือไม่?


person matticala    schedule 24.05.2013    source แหล่งที่มา


คำตอบ (2)


ฉันพบวิธีแก้ไขปัญหานี้สองวิธี:

ที่ 1: เข้าสู่ Constructor (จริงๆ แล้วฉันใช้สิ่งนี้)

public class MyClassImpl implements MyClassWritable, Serializable {

   public class IdImpl implements MyClass.Id, Comparable<IdImpl> {
       private final int id1;
       private final int id2;
       private final String id3;

       private IdImpl(int id1, int id2, String id3) {
          this.id1 = id1;
          this.id2 = id2;
          this.id3 = id3;
       }

       // getters, compareTo, hashCode, equals and toString.
       // implementing Comparable to use MyClass.Id as indexes into Collections
   }

   private final Id id;
   ...
   private String other;

   public MyClassImpl(int id1, int id2, String id3) {
      this.id = new IdImpl(id1, id2, id3);
   }

   // methods
}

resultMap คือ:

<resultMap id="myClassResultMap" type="MyClass">
   <constructor>
      <idArg column="ID_COL_1" javaType="java.lang.Integer"/>
      <idArg column="ID_COL_2" javaType="java.lang.Integer"/>
      <idArg column="ID_COL_3" javaType="java.lang.String"/>
   </contructor>
   <result property="other" column="OTHER_COL" />
</resultMap>

ที่ 2: ฟิลด์ที่ไม่สิ้นสุดและตัวตั้งค่าในคลาส Id resultMap จะเป็น:

public class MyClassImpl implements MyClassWritable, Serializable {

   public class IdImpl implements MyClass.IdWritable, Comparable<IdImpl> {
       private int id1;
       private int id2;
       private String id3;

       private IdImpl() {
          super();
       }

       // SETTERS, getters, compareTo, hashCode, equals and toString.
       // implementing Comparable to use MyClass.Id as indexes into Collections
   }

   private final Id id;
   ...
   private String other;

   public MyClassImpl(int id1, int id2, String id3) {
      this.id = new IdImpl();
   }

   // methods
}

<resultMap id="myClassResultMap" type="MyClass">
   <id property="id.id1" column="ID_COL_1" javaType="java.lang.Integer"/>
   <id property="id.id2" column="ID_COL_2" javaType="java.lang.Integer"/>
   <id property="id.id3" column="ID_COL_3" javaType="java.lang.String"/>
   <result property="other" column="OTHER_COL" />
</resultMap>

ฉันยอมรับสิ่งแรกที่มีการเขียนสำเร็จรูปน้อยกว่าในขณะที่รักษาคลาส "อ่านอย่างเดียว" เมื่อส่งวัตถุไปยังเธรด คลาสคอนเทนเนอร์มีโครงสร้างดังนี้:

+ public interface MyClass // declares getters
+- public interface Id {...} // MyClass.Id declares getters for id's
|
+--+ public interface MyClassWritable extends MyClass // declares setters
   |
   +-- public class MyClassImpl implements MyClassWritable
person matticala    schedule 07.06.2013

หวังว่านี่จะช่วยผู้อื่นได้ ลอง:

<resultMap id="myClassResultMap" type="MyClass">
   <result property="id.id1" column="COL_1" />
   <result property="id.id2" column="COL_2" />
   <result property="id.id3" column="COL_3" />
   <result property="otherData" column="COL_4" />
   ...
</resultMap>
person Greşanu Emanuel - Vasile    schedule 29.06.2017