Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added BD-Diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,39 @@
# java-filmorate
Template repository for Filmorate project.

## BD-structure
![](/BD-Diagram.png)

Получение списка фильмов по рейтингу:
```
SELECT f.film_id,
COUNT(l.user_id)
FROM film AS f
INNER JOIN likes AS l ON f.film_id = l.film_id
GROUP BY f.film_id
ORDER BY COUNT(l.user_id) DESC;
```

Получение списка друзей пользователя:
```
SELECT u.user_id,
fr.friend_id
FROM user AS u
INNER JOIN friends AS fr ON u.user_id = fr.user_id
GROUP BY u.user_id;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GROUP BY вернет одну строку, соответсвенно и одного друга

```

Получение списка названий фильмов в жанре COMEDY по продолжительности:
```
SELECT f.name,
f.duration
FROM film AS f
JOIN film_genre AS fg ON f.film_id = fg.film_id
JION genre AS g ON fg.genre_id = g.genre_id
WHERE g.name = 'COMEDY'
GROUP BY g.name
ORDER BY f.duration;
```



15 changes: 15 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@
<artifactId>logbook-spring-boot-starter</artifactId>
<version>3.7.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.1.1.Final</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
Expand All @@ -55,6 +65,11 @@
<artifactId>expressly</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.29.0-GA</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.web.bind.annotation.*;
import ru.yandex.practicum.filmorate.exception.DuplicatedDataException;
import ru.yandex.practicum.filmorate.exception.NotFoundException;
import ru.yandex.practicum.filmorate.model.Friendship;
import ru.yandex.practicum.filmorate.model.User;
import ru.yandex.practicum.filmorate.service.UserService;

Expand Down Expand Up @@ -55,10 +56,11 @@ public Collection<String> getCommonFriends(@PathVariable int id,
return userService.getCommonFriends(id, friendId);
}

@PutMapping("/{id}/friends/{friendId}")
@PutMapping("/{id}/friends/{friendId}/status/{status}")
public void addFriend(@PathVariable int id,
@PathVariable int friendId) throws NotFoundException {
userService.addFriend(id, friendId);
@PathVariable int friendId,
@PathVariable Friendship status) throws NotFoundException {
userService.addFriend(id, friendId, status);
log.debug("Друг успешно добавлен.");
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ru.yandex.practicum.filmorate.model;

public enum AgeRating {
G,
PG,
PG_13,
R,
NC_17
}
6 changes: 6 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/model/Film.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import org.hibernate.validator.constraints.Length;

import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;

@Data
@Slf4j
Expand All @@ -33,6 +35,10 @@ public class Film {

private Integer id;

private Set<Genre> genres = new HashSet<>();

private AgeRating ageRating;

public Film() {

}
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/model/Friends.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ru.yandex.practicum.filmorate.model;

import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import lombok.Data;

import java.util.Objects;

@Data
@Entity
public class Friends {
private int userId;
private int friendId;
@Enumerated(EnumType.STRING)
private Friendship friendship;

public Friends(int userId, int friendId, Friendship friendship) {
this.userId = userId;
this.friendId = friendId;
this.friendship = friendship;

}

@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Friends that = (Friends) o;
return userId == that.userId && friendId == that.friendId;
}

@Override
public int hashCode() {
return Objects.hash(userId, friendId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.yandex.practicum.filmorate.model;

public enum Friendship {
CONFIRMED,
NOT_CONFIRMED,
DENIED
}
10 changes: 10 additions & 0 deletions src/main/java/ru/yandex/practicum/filmorate/model/Genre.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ru.yandex.practicum.filmorate.model;

public enum Genre {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Использование enum для жанров ограничивает гибкость приложения. Например, если в будущем потребуется добавить новый жанр, это придётся делать через изменение кода enum, что приведёт к необходимости перекомпиляции.
Еще как вариант можно создать отдельный класс Genre с полями id и name, которые будут соответствовать полям в таблице genres в БД. Это позволит управлять жанрами динамически без изменения исходного кода.
Также в классе Film необходимо добавить коллекцию, которая будет хранить уникальные значения жанров, т.к их может быть несколько

Copy link
Copy Markdown
Owner Author

@NadezhdaTA NadezhdaTA Mar 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

решила пока не переделывать enum, тоже почитала про него и его совместимость с sql и думаю попробовать, хотя очень вероятно, что при создании таблиц и переделаю в объект с полями (как ты говоришь)
вообще хочу сделать таблицы с помощью herbinate, подключила зависимости, попробовала на Friends - вроде работает

ACTION_MOVIE,
COMEDY,
DRAMA,
CARTOON,
THRILLER,
DOCUMENTARY
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import org.springframework.validation.annotation.Validated;
import ru.yandex.practicum.filmorate.exception.DuplicatedDataException;
import ru.yandex.practicum.filmorate.exception.NotFoundException;
import ru.yandex.practicum.filmorate.model.Friends;
import ru.yandex.practicum.filmorate.model.Friendship;
import ru.yandex.practicum.filmorate.model.User;
import ru.yandex.practicum.filmorate.storage.InMemoryUserStorage;
import ru.yandex.practicum.filmorate.storage.UserStorage;
Expand Down Expand Up @@ -44,22 +46,28 @@ public Collection<User> getUsersList() {
}


public void addFriend(int userId, int friendId) throws NotFoundException {
public void addFriend(int userId, int friendId, Friendship friendStatus) throws NotFoundException {
User user = getUserById(userId);
User friend = getUserById(friendId);
userStorage.addFriend(user, friend);
Friends userFriend = new Friends(userId, friendId, friendStatus);
Friends friendFriend = new Friends(friendId, userId, Friendship.CONFIRMED);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

при добавлении в друзья сразу создаются две связи, одна из которых со статусом CONFIRMED, даже если вторая сторона ещё не принимала заявку

userStorage.addFriend(user, friend, userFriend, friendFriend);
}

public Collection<String> getFriendsList(int id) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

метод возвращает список имен друзей, а не самих пользователей(или их идентификаторы), что затрудняет идентификацию. Может возникнуть путаница, т.к имена могут повторяться. Но если ранее замечаний не было, то ок)

  • возможно стоит добавить признак дружбы (confirmed)

return userStorage.getFriendsList(id).stream()
.map(Friends::getFriendId)
.map(this::getUserById)
.map(User::getName)
.collect(Collectors.toList());
}

public Collection<String> getCommonFriends(int userId, int friendId) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

метод также возвращает список имен. если ранее не было замечаний, то ок

Collection<User> friendsList = userStorage.getFriendsList(friendId);
var friendsList = userStorage.getFriendsList(friendId);
return userStorage.getFriendsList(userId).stream()
.filter(friendsList::contains)
.map(Friends::getFriendId)
.map(this::getUserById)
.map(User::getName)
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public Film updateFilm(Film newFilm) {
oldFilm.setDescription(newFilm.getDescription());
oldFilm.setReleaseDate(newFilm.getReleaseDate());
oldFilm.setDuration(newFilm.getDuration());
oldFilm.setAgeRating((newFilm.getAgeRating()));
oldFilm.setGenres(newFilm.getGenres());

films.put(oldFilm.getId(), newFilm);
return oldFilm;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import ru.yandex.practicum.filmorate.model.Friends;
import ru.yandex.practicum.filmorate.model.User;

import java.util.*;
Expand All @@ -12,7 +13,7 @@ public class InMemoryUserStorage implements UserStorage {
private int nextUserId = 1;

private final Map<Integer, User> users = new HashMap<>();
private final Map<Integer, Set<User>> userFriends = new HashMap<>();
private final Map<Integer, Set<Friends>> userFriends = new HashMap<>();

@Override
public User createUser(User user) {
Expand Down Expand Up @@ -45,13 +46,14 @@ public Optional<User> getUserById(int id) {
}

@Override
public void addFriend(User user, User friend) {
userFriends.computeIfAbsent(user.getId(), u -> new HashSet<>()).add(friend);
userFriends.computeIfAbsent(friend.getId(), f -> new HashSet<>()).add(user);
public void addFriend(User user, User friend, Friends userFriend, Friends friendFriend) {
userFriends.computeIfAbsent(user.getId(), u -> new HashSet<>()).add(userFriend);
userFriends.computeIfAbsent(friend.getId(), f -> new HashSet<>()).add(friendFriend);

}

@Override
public Collection<User> getFriendsList(int id) {
public Collection<Friends> getFriendsList(int id) {
return userFriends.get(id);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ru.yandex.practicum.filmorate.storage;

import ru.yandex.practicum.filmorate.model.Friends;
import ru.yandex.practicum.filmorate.model.User;

import java.util.Collection;
Expand All @@ -17,9 +18,9 @@ public interface UserStorage {

Optional<User> getUserById(int id);

void addFriend(User user, User friend);
void addFriend(User user, User friend, Friends userFriend, Friends friendFriend);

Collection<User> getFriendsList(int id);
Collection<Friends> getFriendsList(int id);

void deleteFriend(User user, User friend);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import ru.yandex.practicum.filmorate.exception.DuplicatedDataException;
import ru.yandex.practicum.filmorate.exception.NotFoundException;
import ru.yandex.practicum.filmorate.model.Film;
import ru.yandex.practicum.filmorate.model.Friends;
import ru.yandex.practicum.filmorate.model.Friendship;
import ru.yandex.practicum.filmorate.model.User;
import ru.yandex.practicum.filmorate.service.FilmService;
import ru.yandex.practicum.filmorate.service.UserService;
Expand Down Expand Up @@ -226,14 +228,16 @@ void getFriendsListTest() throws NotFoundException {
userController.createUser(user);
User user1 = userController.createUser(new User("name@l", "login"));
User user2 = userController.createUser(new User("name@lm", "logins"));
Friends friends1 = new Friends(user.getId(), user1.getId(), Friendship.NOT_CONFIRMED);
Friends friends2 = new Friends(user.getId(), user2.getId(), Friendship.CONFIRMED);

userController.addFriend(user.getId(), user1.getId());
userController.addFriend(user.getId(), user2.getId());
userController.addFriend(user.getId(), user1.getId(), friends1.getFriendship());
userController.addFriend(user.getId(), user2.getId(), friends2.getFriendship());
assertEquals(2, userController.getUsersFriends(user.getId()).size());

userController.deleteFriend(user.getId(), 2);

assertEquals(1, userController.getUsersFriends(user.getId()).size());
assertEquals(2, userController.getUsersFriends(user.getId()).size());

}

Expand Down