MyBatis:通过一个查询中的注释进行收集

时间:2014-11-29 11:38:22

标签: java sql mybatis

我有一个xml映射器 - 一个选择和一个结果映射器。它没有问题。但我想使用注释。我的映射器:

  <resultMap id="readItemsRM" type="com.company.Item">
   <id property="id" column="Id"/>
    <result property="comment" column="Comment"/>
    <collection property="textItems" ofType="com.company.TextItem">
        <id property="id" column="TxId"/>
        <result property="name" column="TxName"/>
      </collection>
    </resultMap>

所以我确实喜欢这个

   @Results({
        @Result(id=true, property="id", column="Id"),
        @Result(property="comment", column="Comment"),
        ///,???        
    })
   public List<Item> select();

我无法理解如何通过注释映射我的集合而不再执行一次sql查询。正如我发现的所有示例都假设执行了一个以上的查询。请帮忙。

4 个答案:

答案 0 :(得分:9)

AFAIK,如果您使用带注释的映射,则无法使用JOIN

doc开始,关于@Many的使用情况,

  

到复杂类型的集合属性的映射。属性:   select,这是映射语句的完全限定名称(即   mapper方法),可以加载一组实例   适当的类型,fetchType,取代全局   此映射的配置参数lazyLoadingEnabled。 注意   您会注意到Annotations不支持连接映射   API。这是由于Java Annotations中的限制没有   允许循环引用。

如果您愿意,可以直接将ResultMap与注释一起使用:

@Select("SELECT QUERY")
@ResultMap("readItemsRM")
public List<Item> select();

答案 1 :(得分:2)

我发现你可以在MyBatis上使用Java注释实际进行一对多或一对一的连接

public class Master {
    private String nama;
    private Short usia;
    private List<Contoh> contohs;
}

public interface MasterMapper {

    @Select("SELECT master.nama, master.usia FROM test.master WHERE master.nama = #{nama}")
    @Results(value = {
         @Result(property="nama", column="nama"),
         @Result(property="usia", column="usia"),
         @Result(property="contohs", javaType=List.class, column="nama", 
         many=@Many(select="getContohs"))
    })
    Master selectUsingAnnotations(String nama);

    @Select("SELECT contoh.id, contoh.nama, contoh.alamat "
         + " FROM test.contoh WHERE contoh.nama = #{nama}")
    List<Contoh> getContohs(String nama);
}

link

中有更多详细信息

答案 2 :(得分:0)

使用ibatis注释的示例进行内部联接查询。

@Select("SELECT t1.column1, t1.column2, t2.column3, t2.column4 "
            + "FROM table1 AS t1 "
            + "INNER JOIN table2 AS t2 "
            + "ON (t1.column1 = t2.column3)  WHERE t1.column1=#{id}")
    @Results(value = {
            @Result(property = "val1", column = "column1"),
            @Result(property = "val2", column = "column2"),
            @Result(property = "val3", column = "column3"),
            @Result(property = "val4", column = "column4")})
    MyBean getInnerJoinResult(@Param("id") Integer id); 

答案 3 :(得分:-1)

我已经为我工作,喜欢@feco的链接,但是我的表结构有些不同,因此示例中的映射是从主表到列表的,让我们检查一下代码。

CREATE TABLE IF NOT EXISTS item_service (
  id int(11) NOT NULL AUTO_INCREMENT,
  description varchar(200) NOT NULL DEFAULT '0'
  service_id int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (id),
  CONSTRAINT fk1_item_service_service FOREIGN KEY (service_id) REFERENCES service (id),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS service (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(200) NOT NULL DEFAULT '0',
  PRIMARY KEY (id),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


package com.****;

import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

@Data
@Entity
@Table(name = "item_service")
public class Item {

    /*
        Each item has a service linked to the Service class.
        Each Service is not mandatory has items. But, the service could have many items asociated. it depends the JPA Aproach that you have.
        */ 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", updatable = false, nullable = false) //could be redundant, doesn matter for the example
    private Long id;
    @Column(name = "description"),
    private String description;

    @ManyToOne
    @JoinColumn(name = "service_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Service service;

    /*getters and setters*/
}

package com.***;

@Data
@Entity
@Table(name = "item_service")
public class Service {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column
    private String name;
    /*getters and setter*/

}

@Mapper
public interface ItemServiceMapper {

    @Select("SELECT * FROM item_service")
    @Results(value = {
            @Result(column = "service_id", property = "service", javaType = Service.class, one = @One(select = "getService")),
            @Result(column = "receipt_id", property = "receipt", javaType = Receipt.class, one = @One(select = "getReceipt")),
    })
    List<ItemService> findAllall();

    @Select("SELECT * FROM service WHERE id= #{id}")
    Service getService(@Param("id") Long id);

    @Select("SELECT * FROM service WHERE id= #{id}")
    Receipt getReceipt(@Param("id") Long id)
}