Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

map value #2865

Open
min1854 opened this issue Apr 15, 2023 · 6 comments
Open

map value #2865

min1854 opened this issue Apr 15, 2023 · 6 comments

Comments

@min1854
Copy link

min1854 commented Apr 15, 2023

Feature request

In daily query, only the key of the map can be defined. I hope that the value of the map can also be defined, which can be returned directly Map<Integer, Integer>

public interface NoticeMapper {

  @MapKey("status")
  @MapValue("count")
  Map<Integer, Integer> groupStatus();


}
<mapper namespace="org.apache.ibatis.submitted.mapkey_value.NoticeMapper">



  <resultMap id="groupStatusMap" type="hashmap">
    <result column="count" javaType="Integer" property="count"/>
    <result column="status" javaType="Integer" property="status"/>
  </resultMap>


  <select id="groupStatus" resultMap="groupStatusMap">
  select count(*) as count , status
    from notice group by status
  </select>



</mapper>

#2863

@isfong
Copy link

isfong commented Apr 25, 2023

Feature request

In daily query, only the key of the map can be defined. I hope that the value of the map can also be defined, which can be returned directly Map<Integer, Integer>

public interface NoticeMapper {

  @MapKey("status")
  Map<Integer, HashMap<Integer, Integer>> groupStatus();



}
<mapper namespace="org.apache.ibatis.submitted.mapkey_value.NoticeMapper">




  <select id="groupStatus" resultMap="hashMap">
  select count(*) as count , status
    from notice group by status
  </select>


</mapper>

#2863

Similarly, we want to support a collection of map value objects rather than a single example for jpa:

  @ElementCollection
  private Map<Long, Money> creditReservations;

@harawata
Copy link
Member

Hello @min1854 ,

Thank you for the idea and the PR.

I don't understand the @isfong 's request (please open a new issue if it's not exactly the same request), but the original request seems to be the same as #2672.

As I wrote in the issue, there are many similar but slightly different requests and, personally, I would expect users to use ResultHandler or Java's stream for this type of requirements.
However, if other committers are interested in supporting @MapValue, I would not object (I may add a few requests on #2863 if it's green-lit, though).

@min1854
Copy link
Author

min1854 commented Apr 26, 2023

Feature request
In daily query, only the key of the map can be defined. I hope that the value of the map can also be defined, which can be returned directly Map<Integer, Integer>

public interface NoticeMapper {

  @MapKey("status")
  Map<Integer, HashMap<Integer, Integer>> groupStatus();



}
<mapper namespace="org.apache.ibatis.submitted.mapkey_value.NoticeMapper">




  <select id="groupStatus" resultMap="hashMap">
  select count(*) as count , status
    from notice group by status
  </select>


</mapper>

#2863

Similarly, we want to support a collection of map value objects rather than a single example for jpa:

  @ElementCollection
  private Map<Long, Money> creditReservations;

I think this is difficult and requires a lot of consideration

@min1854
Copy link
Author

min1854 commented Apr 26, 2023

Hello @min1854 ,

Thank you for the idea and the PR.

I don't understand the @isfong 's request (please open a new issue if it's not exactly the same request), but the original request seems to be the same as #2672.

As I wrote in the issue, there are many similar but slightly different requests and, personally, I would expect users to use ResultHandler or Java's stream for this type of requirements. However, if other committers are interested in supporting @MapValue, I would not object (I may add a few requests on #2863 if it's green-lit, though).

Yes, the two requests are the same, but since the map keys are already available and values cannot be defined, one dto needs to be defined at a time. Using Java's stream and ResultHandler is not convenient and elegant in code

Whenever there are only two columns, I need to define an additional DTO instead of directly converting the results into a map, so encoding also requires repeating the additional definition of DTO

I think most people want to directly convert to a map when querying two columns, but when they find that 'MapKey' can only support keys and cannot define values, In the end, only DTO can be defined and converted to a map using 'Java's stream'. I often encounter this problem when using it

Mybatis is already able to convert to a map, but the results still need to be processed again, which feels very troublesome

So I hope to add the function of defining map value

@harawata
Copy link
Member

harawata commented Jul 13, 2023

@min1854 ,

Sorry for the belated reply. I was writing a reply, but forgot to post it.

I just wanted to let you know that if your @MapValue satisfies your requirement, custom DTO class won't be necessary even with the current version.

@Select("select status, count(*) cnt from ...")
List<Map<String, Object>> selectMaps();
Map<Integer, Integer> statCountMap = selectMaps().stream()
  .collect(Collectors.toMap(e -> (Integer) e.get("status"), e -> (Integer) e.get("cnt")));

Also, you can put the stream processing code in a default method of the mapper.

default Map<Integer, Integer> getStatCountMap() {
  return selectMaps().stream()
    .collect(Collectors.toMap(e -> (Integer) e.get("status"), e -> (Integer) e.get("cnt")));
}

@min1854
Copy link
Author

min1854 commented Jul 14, 2023

@min1854 ,

Sorry for the belated reply. I was writing a reply, but forgot to post it.

I just wanted to let you know that if your @MapValue satisfies your requirement, custom DTO class won't be necessary even with the current version.

@Select("select status, count(*) cnt from ...")
List<Map<String, Object>> selectMaps();
Map<Integer, Integer> statCountMap = selectMaps().stream()
  .collect(Collectors.toMap(e -> (Integer) e.get("status"), e -> (Integer) e.get("cnt")));

Also, you can put the stream processing code in a default method of the mapper.

default Map<Integer, Integer> getStatCountMap() {
  return selectMaps().stream()
    .collect(Collectors.toMap(e -> (Integer) e.get("status"), e -> (Integer) e.get("cnt")));
}

This is not elegant, In my opinion, this should be the work done by the framework.

I think the mapping work should be addressed by the framework

Maintaining duplicate default methods is also a hassle point

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants