简体   繁体   English

如何从另一个映射器在 myBatis 映射器中设置参数

[英]How to set argument in myBatis mapper from another mapper

I have some problems with mapping in myBatis.我在 myBatis 中映射有一些问题。

I have pojo class我有 pojo 课

public class Video {
    private int id;
    private String title;
    private Set<Person> actors;
    ...
    getters & setters
}

I'm have interface PersonMapper我有接口 PersonMapper

public interface PersonMapper {
@Select("${query}")
    Set<Person> getByFilmId(@Param("id") long id, @Param("query") PersonByFilmQueries query);

enum PersonByFilmQueries {

        ACTORS_BY_FILM(
                "select " +
                "   * " +
                "from " +
                "   actors a, " +
                "   film_actors fa " +
                "where " +
                "   fa.actor_id = a.id " +
                "and fa.film_id = #{id}"),
        ....
        WRITERS_BY_FILM(
                "select "+
                "* " +
                "from " +
                "writers w, " +
                "film_writers fw " +
                "where " +
                "fw.writer_id = w.id " +
                "and fw.film_id = #{id}");
        private String query;

        PersonByFilmQueries(String query) {
            this.query = query;
        }

        @Override
        public String toString() {
            return query;
        }
    }
}

I am try to reuse this select from another xml mapper (VideoMapper.xml).我尝试从另一个 xml 映射器 (VideoMapper.xml) 中重用这个选择。

<mapper namespace="ru.common.mapper.VideoMapper">
    <resultMap id="video" type="Video">
    <id property="id" column="id"/>
    <result property="title" column="title"/>
    </resultMap>
    <collection property="actors" javaType="HashSet" ofType="Person" column="id" 
    select="ru.common.mapper.PersonMapper.getByFilmId">
    </collection>
</resultMap> 

I'm trying to add a collection of Person to Video POJO.我正在尝试将 Person 集合添加到 Video POJO。 But I do not understand how to set the second argument in getByFilmId enum with sql.但我不明白如何使用 sql 在 getByFilmId 枚举中设置第二个参数。 Is there any easy way to do this?有什么简单的方法可以做到这一点吗? If I call this mapper from Java then there are no problems, everything works如果我从 Java 调用此映射器,则没有问题,一切正常

In general you can specify multiple parameters to the nested select for association or collection.通常,您可以为关联或集合的嵌套选择指定多个参数。

If the query parameters was simple String (and not an enum) you could add a column to the main query that return list of videos like this:如果query参数是简单的字符串(而不是枚举),您可以向主查询添加一列,返回视频列表,如下所示:

select id, title, ..., 'ACTORS_BY_FILM' query_type
from video

Then you modify the mapping for collection:然后修改集合的映射:

 <collection property="actors" javaType="HashSet" ofType="Person" column="{id=id,query=query_type}" 
select="ru.common.mapper.PersonMapper.getByFilmId">

This way columns id and query_type from the main query would be passed as parameters to nested select.这样,主查询中的列idquery_type将作为参数传递给嵌套选择。

In your case you need that mybatis invoke constructor on a passed string parameter and I don't think mybatis supports this.在您的情况下,您需要 mybatis 在传递的字符串参数上调用构造函数,我认为 mybatis 不支持这一点。

One way you can try to overcome this.您可以尝试克服此问题的一种方法。 I'm not sure it will work as you are already on the grey territory when you are using double substitution.我不确定它是否会起作用,因为当您使用双重替换时,您已经处于灰色地带。 I would say this is not an intended behaviour of mybatis.我会说这不是 mybatis 的预期行为。

But you can try.不过你可以试试。 So change the mapper method to accept string.因此更改映射器方法以接受字符串。

Then you can create a helper static method that converts a name of the query to the query text:然后,您可以创建一个辅助静态方法,将查询名称转换为查询文本:

 public class PersonByFilmQueryBuilder {

     public static String getQuery(String queryId) {
          return PersonByFilmQueries.valueOf(queryId);
     }
 }

Now you can use this static method in the OGNL expression in select like this:现在,您可以在 select 中的 OGNL 表达式中使用此静态方法,如下所示:

@Select("${@com.mycompany.myapp.PersonByFilmQueryBuilder@getQuery(query)}")
Set<Person> getByFilmId(@Param("id") long id, @Param("query") String query);

I'm not quite sure that in this phase of query generation mybatis does use full-blown OGNL expression.我不太确定在这个查询生成阶段,mybatis 是否使用了成熟的 OGNL 表达式。 If it does this will work.如果这样做,这将起作用。

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

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