简体   繁体   English

在 Mybatis (Mapper) 和 Java 中的属性 List 中分组结果

[英]Group result in List that is an attribute in Mybatis (Mapper) and Java

I have a question about Mappers in Mybatis.我有一个关于 Mybatis 中的 Mappers 的问题。 I have two classes like this:我有两个这样的课程:

public class A{
  private String A1;
  private String A2;
  private List<B> listB;
  //getters and setters
  .
  .
  .
  public static class B {
   private String B1;
   private String B2;
   //getters and setters
   .
   .
   .

  }

}

Then I have a mapper class like this:然后我有一个像这样的映射器 class :

@Mapper
public interface ABMapper{

@Select("select b1,b2 from b where b.a1 = #{a1}")
public List<B> getBs(@Param("a1") String a1);

@Select ("select a1,a2 from a limit 100")
@Results({
@Result(property="a1", value = "a1"),
@Result(property="a2", value = "a2"),
@Result(property="listB", column="a1", many = @Many(select = "getBs"))
})
public List<A> getAs();
}

This works fine, but I know that when getAs() executes, getBs runs as many times as items have (limit 100 is an example).这很好用,但我知道当getAs()执行时,getBs 运行的次数与项目的次数一样多(限制 100 是一个例子)。 I wonder that if exists a way to run a query like select a.a1,a.a2,b.b1,b.b2 from aa inner join bb on a.a1 = b.a1 and then Mybatis (and Java) could group elements in List<A> and the attribute B is not empty.我想知道是否存在一种方法来运行像select a.a1,a.a2,b.b1,b.b2 from aa inner join bb on a.a1 = b.a1然后 Mybatis(和 Java)可以分组List<A>中的元素并且属性 B 不为空。 Perhaps, it necessary to use hash and equals in class A and B, but I don't know.也许,有必要在 class A 和 B 中使用 hash 和 equals,但我不知道。

Thanks for your answers.感谢您的回答。

Mybatis can do that but only if you use xml mapping. Mybatis 可以做到这一点,但前提是你使用 xml 映射。 The limitation of annotations in java makes it impossible to map associations with join: java 中注释的限制使得 map 无法与 join 关联:

You will notice that join mapping is not supported via the Annotations API.您会注意到注释 API 不支持连接映射。 This is due to the limitation in Java Annotations that does not allow for circular references.这是由于 Java 注释中的限制不允许循环引用。

In this case the mapping might look like:在这种情况下,映射可能如下所示:

<resultMap id="bMap" type="B">
  <id property="b1" column="b1"/>
  <result property="b2" column="b2"/>
</resultMap>

<resultMap id="aMap" type="A">
    <id property="a1" column="a1"/>
    <result property="a2" column="a2"/>
    <collection property="listB" javaType="B" resultMap="bMap" columnPrefix="b_"/>
</resultMap>

<select id='getAs' resultMap='aMap'>
SELECT a.*, b.id B_id, b.b1 B_b1, b.b2 B_b2
FROM (
   select *
   from a
   LIMIT 100
  ) AS a
  LEFT JOIN AS b on a.a1 = b.a1
</select>

Some important notes:一些重要的注意事项:

  1. both A and B should have some identifying field(s) configured with id element. AB都应该有一些使用id元素配置的标识字段。 The value in this field would be used to identify object and do what you call grouping.此字段中的值将用于识别 object 并执行您所谓的分组。 For table a this seems to be a1 (as you used it as a join field) and I used it in the example.对于表a这似乎是a1 (因为您将其用作连接字段),我在示例中使用了它。
  2. autoMapping="true" in resultMap might be useful if there are many fields to be mapped如果要映射许多字段, resultMap中的autoMapping="true"可能会很有用
  3. you need to use left/right join to handle those records from table a that do not have anything in b .您需要使用左/右连接来处理表a中没有任何内容的记录b
  4. in order to LIMIT work correctly with join you need to do it on the select that gets records from a and not on the join result otherwise you may get less than 100 records in the result if more than 100 records from b are joined.为了LIMIT与 join 一起正常工作,您需要在 select 上执行此操作,该 select 从a而不是在连接结果中获取记录,否则如果来自b的 100 多条记录被连接,您可能会在结果中获得少于 100 条记录。
  5. it depends on the use case but usually if you use LIMIT you need to specify some order, otherwise records will be returned in unpredictable order.这取决于用例,但通常如果您使用LIMIT ,您需要指定一些顺序,否则记录将以不可预测的顺序返回。
  6. In the older versions of mybatis there was a bug that required that column prefixes in the query should be in upper case (may be this is fixed now, I'm not sure).在旧版本的 mybatis 中存在一个错误,要求查询中的列前缀应为大写(可能现在已修复,我不确定)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM