我对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
}
]
答案 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);
}
注意:我已将所有这些盲人写下来,因此可能无法逐字记录。但它应该非常接近。