#java #spring #hibernate #jpa
#java #spring #переход в спящий режим #jpa
Вопрос:
Я не могу найти чистый и простой способ разбиения на страницы при использовании отношения «многие ко многим» с дополнительным столбцом.
Моя модель выглядит так:
У меня есть пользователь и модель продукта. Каждый пользователь может использовать n продуктов. Каждое потребление будет сохранено в дополнительной таблице, потому что я хочу сохранить дополнительную информацию, такую как дата и т.д. Я реализовал модель следующим образом, и она работает, но я хочу получать данные о потреблении пользователем в виде страницы, а не извлекать весь набор. Каков был бы наилучший способ реализовать это?
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(
mappedBy = "user",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<Consumption> consumptionList = new ArrayList<>(); // never set this attribute
public List<Consumption> getConsumptionList() {
return consumptionList;
}
public void addConsumption(Product product) {
Consumption consumption = new Consumption(this, product);
consumptionList.add(consumption);
product.getConsumptionList().add(consumption);
}
public void removeConsumption(Consumption consumption) {
consumption.getProduct().getConsumptionList().remove(consumption);
consumptionList.remove(consumption);
consumption.setUser(null);
consumption.setProduct(null);
}
}
—
@Entity
@NaturalIdCache
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(
mappedBy = "product",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<Consumption> consumptionList = new ArrayList<>();
public List<Consumption> getConsumptionList() {
return consumptionList;
}
}
Это мой класс для хранения потребляемых данных.
@Entity
public class Consumption {
@EmbeddedId
private UserProductId id;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("userId")
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("productId")
private Product product;
public Consumption(User user, Product product) {
this.user = user;
this.product = product;
this.id = new UserProductId(user.getId(), product.getId());
}
}
И это мой составной первичный ключ, который.
@Embeddable
public class UserProductId implements Serializable {
@Column(name = "user_id")
private Long userId;
@Column(name = "product_id")
private Long productId;
private UserProductId() {
}
public UserProductId(Long userId, Long productId) {
this.userId = userId;
this.productId = productId;
}
}
Я хотел бы иметь возможность вызывать такой метод, как «getConsumptionList (страница страницы)», который затем возвращает постраничный.
Я надеюсь, вы сможете мне помочь!
Заранее благодарю вас!
Комментарии:
1. Разве
getConsumptionList()
метод не должен содержатьPageable
объект в качестве параметра и возвращатьPage
как вpublic Page<Consumption> getConsumptionList(Pageable pageable)
?2. Тогда мне пришлось бы самому реализовать разбивку на страницы в классе model, верно? Невозможно просто реализовать метод интерфейса в репозитории pagingandsorting?
Ответ №1:
Что ж, при использовании Spring Boot вы могли бы использовать репозиторий:
@Repository
public interface ConsumptionRepo extends JpaRepository<Consumption, Long>{
List<Consumption> findByUser(User user, Pageable pageable);
}
Тогда вы можете просто вызвать это
ConsumptionRepo.findByUser(user, PageRequest.of(page, size);
Ответ №2:
Я, наконец, нашел решение своей проблемы благодаря @mtshaikh idea:
Просто реализуйте Paginationservice:
public Page<Consumption> getConsumptionListPaginated(Pageable pageable) {
int pageSize = pageable.getPageSize();
int currentPage = pageable.getPageNumber();
int startItem = currentPage * pageSize;
List<Consumption> list;
if (consumptionList.size() < startItem) {
list = Collections.emptyList();
} else {
int toIndex = Math.min(startItem pageSize, consumptionList.size());
list = consumptionList.subList(startItem, toIndex);
}
return new PageImpl<>(list, PageRequest.of(currentPage, pageSize), consumptionList.size());
}
Комментарии:
1. Но, тем не менее, он перечисляет все, а затем отправляет подсписок. Нам нужно запретить им вызывать alll