【问题标题】:native query join in spring data春季数据中的本机查询联接
【发布时间】:2016-12-04 16:29:29
【问题描述】:

我有课:

@Entity
public class User {
    @Id
    Long id;
    String name;

    @ManyToMany
    List<Mission> missions;
}

@Entity
public class Mission {
    @Id
    Long id;
    String name;

    @ManyToMany
    List<User> users;
}

public interface MissionRepository extends CrudRepository<Mission, Long> {
    @Query(nativeQuery = true, "select * from mission join user on id = user_id where name = ?1")
    public List<Mission> findByname(String name);
}

我想知道是否可以在 Spring Data JPA 中使用本机查询连接,以及查询结果是否正确映射到上述示例中的实体。

谁能给我一个完整的例子来使用它。 在我的情况下,我必须使用本机查询,但我不确定它是否有效。

【问题讨论】:

    标签: java spring spring-data spring-data-jpa


    【解决方案1】:

    您可以通过使用命名的本机查询和结果集映射来做到这一点 这是一个完整的例子

    任务实体

    package com.ntg.crm.internal.entites;
    
    import java.math.BigInteger;
    import java.util.List;
    
    import javax.persistence.Entity;
    import javax.persistence.EntityResult;
    import javax.persistence.FetchType;
    import javax.persistence.FieldResult;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.JoinTable;
    import javax.persistence.ManyToMany;
    import javax.persistence.NamedNativeQuery;
    import javax.persistence.SqlResultSetMapping;
    
    @SqlResultSetMapping(name = "Mission.findAllMissionsMapping", entities = @EntityResult(entityClass = Mission.class, fields = {
            @FieldResult(name = "name", column = "mname"), @FieldResult(name = "id", column = "mid")
    }))
    @NamedNativeQuery(name = "Mission.findAllMissions", query = "select m.id as mid,m.name as mname , info.id uid ,info.name uname from Mission m join user_info_missions um on m.id "
            + "= um.missions_id join user_Info info on info.id = um.user_id where info.name =:userName", resultSetMapping = "Mission.findAllMissionsMapping")
    
    @Entity
    public class Mission {
    
        public Mission() {
    
        }
    
        public Mission(BigInteger id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
    
        public Mission(BigInteger id, String name, List<User> users) {
            super();
            this.id = id;
            this.name = name;
            this.users = users;
        }
    
        @Id
        BigInteger id;
        String name;
    
        @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(name = "user_info_missions", joinColumns = @JoinColumn(name = "missions_id"), inverseJoinColumns = @JoinColumn(name = "user_id"))
        List<User> users;
    
        public BigInteger getId() {
            return id;
        }
    
        public void setId(BigInteger id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List<User> getUsers() {
            return users;
        }
    
        public void setUsers(List<User> users) {
            this.users = users;
        }
    
    }
    

    用户实体

    package com.ntg.crm.internal.entites;
    
    import java.util.List;
    
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.JoinTable;
    import javax.persistence.ManyToMany;
    import javax.persistence.Table;
    
    import com.fasterxml.jackson.annotation.JsonIgnore;
    
    @Entity
    @Table(name = "userInfo")
    public class User {
    
        @Id
        long id;
        String name;
    
        @ManyToMany(targetEntity = Mission.class)
        @JoinTable(name = "user_info_missions", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "missions_id"))
        @JsonIgnore
        List<Mission> missions;
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List<Mission> getMissions() {
            return missions;
        }
    
        public void setMissions(List<Mission> missions) {
            this.missions = missions;
        }
    
    }
    

    存储库功能

    public List<Mission> findAllMissions(@Param("userName") String userName);
    

    控制器功能

    @Autowired
        TestRepository testRepo;
    
        @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json", consumes = "application/json")
        @ResponseBody
        List<Mission> getall() {
            List<Mission> missions = testRepo.findAllMissions("Test");
            return missions;
        }
    

    这就是结果

    [
      {
        "id": 1,
        "name": "Mission 1",
        "users": [
          {
            "id": 1,
            "name": "Test"
          }
        ]
      },
      {
        "id": 2,
        "name": "Mission 2",
        "users": [
          {
            "id": 1,
            "name": "Test"
          }
        ]
      }
    ]
    

    【讨论】:

    • 感谢您的回答,但我想知道查询结果是否正确映射到实体任务。换句话说,我可以在这个请求之后获得用户列表吗?
    • 很好的例子!顺便说一句,您可以使用 Lombok 注释(如 @Data)来减少实体的 getter/setter 和其他样板。
    【解决方案2】:

    @middy62 你可以使用下面的查询。我已经使用您的示例来编写查询。希望它可以帮助某人。


    @Query(nativeQuery = true, value = "select m from Mission join m.user u where name =:name") public List<Mission> findByname(@Param("name") String name);

    请注意,当您在域实体模型上正确映射时,查询有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-25
      • 2014-05-24
      • 2016-01-30
      • 1970-01-01
      • 2023-03-25
      • 2017-12-17
      • 1970-01-01
      • 2021-07-31
      相关资源
      最近更新 更多