Spring RESTful webservice Hibernate / JPA Crudrepository - 按电影标题获取用户

时间:2017-09-20 13:06:50

标签: java spring hibernate rest jpa

我对Spring Boot开发很新,我需要一些特殊情况的帮助。

我正在使用JPA / Hibernate Spring和CRUDrepository创建一个RESTful webservices。(Json格式)

所以我有两张这样的表:

用户:

    +----+-------------+---------+
    | id |  username   | age     | 
    +----+-------------+---------+
    |  1 |  James      | 21      |
    |  2 |  Bond       | 41      |
    |  3 |  David      | 17      |
    |  4 |  Alfred     | 33      |
    +----+-------------+---------+

电影:

    +----+----------+-----------+
    | id| movie     | userId
    +----+----------+-----------+
    |  1 |  movie1  | 3
    |  2 |  movie2  | 3
    |  3 |  movie3  | 1
    |  4 |  movie4  | 4
    |  5 |  movie5  | 4
    |  7 |  movie6  | 2
    |  8 |  movie7  | 2
    |  9 |  movie1  | 1
    +----+----------+-----------+

电影实体:

@Entity
public class Movie implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @Column
    private String title;

@Column
private int userId;

    protected Movie() {
        super();
    }

//constructors 
// getter setter

}

用户实体:

@Entity
public class User {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @Column
    private String username;

@Column
private int age;


    protected User() {
        super();
    }

//constructors 
// getter setter

}

电影资料库:

public interface MovieRepository extends CrudRepository<Movie, Integer> {

    List<Movie> findByTitle(String title);
}

用户存储库:

import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Integer> {

}

我的控制器:

@Controller
@RequestMapping(path="demo")
public class MainController {

    @Autowired
    private MovieRepository movieRepository;

    @Autowired
    private UserRepository userRepository;


    @GetMapping(path="/movie")
    public @ResponseBody Iterable<Movie> getAllMovies() {
        return movieRepository.findAll();
    }

    @GetMapping(path="/user")
    public @ResponseBody Iterable<User> getAllUser() {
        return userRepository.findAll();
    }
}

我可以将所有用户和所有电影作为json obejct结果。

现在我的问题是:如何获得一个json对象,每个用户都有一个singel电影?我想使用RequestParam。也许是这样的:

@GetMapping(path="/userbymovietitle")
    public @ResponseBody String getUserByMovies(@RequestParam("title") string title) {
         ....
    }

并且网址将是这样的:localhost:8080 / demo / userbymovietitle?title = movie1

然后响应应如下所示:

[
  { 
    id: 3
    username: David
    age: 17
  }
  { 
    id: 1
    username: James
    age: 21
  }
]

2 个答案:

答案 0 :(得分:1)

依赖于您可以使用@RequestParam或者您也可以使用。{  @PathVariable

使用第一个网址为:localhost:8080/demo/userbymovietitle?title=movie1,第二个网址为:localhost:8080/demo/userbymovietitle/movie1

并使用路径变量控制器变为

@GetMapping(path="/userbymovietitle/{title}")
    public @ResponseBody String getUserByMovies(@@PathVariable("title") string title) {

无论如何,问题是你的userId ....

你必须在这两个表之间创建一个关系。例如,如果一个用户可以拥有多部电影,并且许多用户也可以看到一部电影,那么就有很多很多关系。 因此,在电影实体中,您必须将列userId替换为:

@ManyToMany
private Set<Users> users = new HashSet<>();

或者在这种情况下(因为它是多对多的关系)你可以把这个实现放在用户体内。 所以在用户实体内添加:

@ManyToMany
    private Set<Movie> movies = new HashSet<>();

我刚刚在网上进行了快速搜索,但请阅读此http://www.tech-recipes.com/rx/56738/one-to-one-one-to-many-table-relationships-in-sql-server/或类似的解释类之间关系的内容。

无论如何,当您以这种方式进行修改时,您可以提取具有特定标题的用户。 Ť

答案 1 :(得分:0)

您应该使用JPA的实体关系功能。

很容易将其称为ManyToMany关系 - 用户出现在许多电影中,而电影有许多用户 - 但ManyToMany只能使用单独的映射表来实现。

您没有这样的映射表 - 相反,每个电影都拥有一个映射到一个用户。因此,我认为您正在描述OneToMany实体关系。

我认为它看起来有点像这样(你可能需要添加无聊的东西,比如getter,setter,public no-arg constructor):

@Entity
public class User {
    @Id
    private long id;

    @OneToMany(mappedBy="user")
    private List<Movie> movies;
}

@Entity
public class Movie {
    @Id
    private long id;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="userId")
    private User user;
}

是的,我们已删除private int userId。我们现在更喜欢getUser().getId()

Spring Data JPA的查询推导提供了一些通过相关实体查找实体的方法。这有两种方式:

public interface MovieRepository extends JpaRepository<Movie, Integer> {
    List<Movie> findByUserId(long id);
    List<Movie> findByUser(User user);
}

您也可以通过示例找到:

final User example = new User();
example.setId(1);
movieRepository.findAll(Example.of(example));

端点可能看起来有点像这样:

@RequestMapping("/{userId}")
public List<User> findByUser(@PathVariable String userId) {
    return movieRepository.findByUser(userId);
}

注意:我已将所有这些盲人写下来,因此可能无法逐字记录。但它应该非常接近。