在 List 中分组结果是 Mybatis(Mapper)和 Java 中的一个属性
Group result in List that is an attribute in Mybatis (Mapper) and Java
我有一个关于 Mybatis 中的 Mappers 的问题。我有两个这样的 classes:
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
.
.
.
}
}
然后我有一个像这样的映射器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();
}
这很好用,但我知道当 getAs()
执行时,getBs 运行s 的次数与项目的次数一样多(例如限制为 100)。
我想知道是否存在一种方法 运行 像 select a.a1,a.a2,b.b1,b.b2 from a a inner join b b on a.a1 = b.a1
这样的查询,然后 Mybatis(和 Java)可以对 List<A>
中的元素进行分组并且属性 B 不为空。
也许,在class A 和B 中需要使用hash 和equals,但我不知道。
感谢您的回答。
Mybatis 可以做到这一点,但前提是你使用 xml 映射。 java 中注释的限制使得无法映射关联与 join:
You will notice that join mapping is not supported via the Annotations API. This is due to the limitation in Java Annotations that does not allow for circular references.
在这种情况下,映射可能如下所示:
<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>
一些重要说明:
A
和 B
都应该有一些标识字段配置有 id
元素。此字段中的值将用于标识对象并执行您所说的分组。对于 table a
,这似乎是 a1
(因为您将其用作连接字段),我在示例中使用了它。
如果要映射的字段很多,autoMapping="true"
in resultMap
可能会有用
- 您需要使用 left/right 连接来处理 table
a
中那些在 b
. 中没有任何内容的记录
- 为了
LIMIT
与 join 一起正常工作,您需要在从 a
获取记录的 select 上执行此操作,而不是在连接结果上执行此操作,否则您得到的可能少于如果来自 b
的超过 100 条记录被合并,则结果中有 100 条记录。
- 这取决于用例,但通常如果您使用
LIMIT
,您需要指定一些顺序,否则记录将以 unpredictable 顺序返回。
- 在旧版本的 mybatis 中有一个错误,要求查询中的列前缀应该是大写的(现在可能已经修复,我不确定)。
我有一个关于 Mybatis 中的 Mappers 的问题。我有两个这样的 classes:
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
.
.
.
}
}
然后我有一个像这样的映射器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();
}
这很好用,但我知道当 getAs()
执行时,getBs 运行s 的次数与项目的次数一样多(例如限制为 100)。
我想知道是否存在一种方法 运行 像 select a.a1,a.a2,b.b1,b.b2 from a a inner join b b on a.a1 = b.a1
这样的查询,然后 Mybatis(和 Java)可以对 List<A>
中的元素进行分组并且属性 B 不为空。
也许,在class A 和B 中需要使用hash 和equals,但我不知道。
感谢您的回答。
Mybatis 可以做到这一点,但前提是你使用 xml 映射。 java 中注释的限制使得无法映射关联与 join:
You will notice that join mapping is not supported via the Annotations API. This is due to the limitation in Java Annotations that does not allow for circular references.
在这种情况下,映射可能如下所示:
<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>
一些重要说明:
A
和B
都应该有一些标识字段配置有id
元素。此字段中的值将用于标识对象并执行您所说的分组。对于 tablea
,这似乎是a1
(因为您将其用作连接字段),我在示例中使用了它。
如果要映射的字段很多,autoMapping="true"
inresultMap
可能会有用- 您需要使用 left/right 连接来处理 table
a
中那些在b
. 中没有任何内容的记录
- 为了
LIMIT
与 join 一起正常工作,您需要在从a
获取记录的 select 上执行此操作,而不是在连接结果上执行此操作,否则您得到的可能少于如果来自b
的超过 100 条记录被合并,则结果中有 100 条记录。 - 这取决于用例,但通常如果您使用
LIMIT
,您需要指定一些顺序,否则记录将以 unpredictable 顺序返回。 - 在旧版本的 mybatis 中有一个错误,要求查询中的列前缀应该是大写的(现在可能已经修复,我不确定)。