От 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 и передать его конструктору?

Я использую этот идентификатор и для других классов:

@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-й: в конструктор (на самом деле я использую это)

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 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>

Второй: неконечные поля и сеттеры в классе Id. Карта результатов будет:

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