Как я могу получить имя Детей в результате, если я ищу одного из их родителей, используя JPA в Java? - PullRequest
2 голосов
/ 02 марта 2020

Я думал использовать @JoinTable, чтобы иметь возможность отображать имя ребенка, когда я ищу по его родителю , но немного борюсь с ним.

Программа хранит детей и одного из их родителей (или обоих), и когда я ищу имя родителя, программа должна отображать имя ребенка (или детей).

Необходимы два интерфейса:

  • имя родителей и детей (имя родителя уникально, поэтому, если оно уже существует, мы просто вставляем имя ребенка (и его parent_id)
  • при поиске по имени родителя программа отображает его / ее ребенка (или детей).

  • Таблица РОДИТЕЛЕЙ:

ID (PK, NN, AI, int) 
          
NAME (NN, String)
      
  • Таблица KIDS:
ID (PK, NN, AI, int) 
          
NEV (NN, String)
           
PARENTS_ID (NN, int)

Программа должна использовать соединение FK и OneToMany, ManyToOne, которое использует поиск и сохраните .

Буду признателен за любые предложения о том, как лучше всего использовать код sh.

Parents. java

@Entity 
public class Parents {
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private long Id;
    @NotNull
    private String firstName;
    @NotNull
    private String lastName;
    @OneToMany(fetch = FetchType.LAZY, mappedBy="parents") 
    private List<Kids> kids;
    // constructor + getters & setters

Дети. java

@Entity
public class Kids {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long Id;
    @NotNull
    private String firstName;
    @NotNull
    private String lastName;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parents_id")
    @NotNull
    private Parents parents;

    public Kids() {
    }

    public Kids(String firstName, String lastName, Parents parents) {
        super();
        this.firstName = firstName;
        this.lastName = lastName;
        this.parents = parents;
    }
    // getters & setters

data. sql

INSERT INTO Parents (first_name, last_name) VALUES ('Viz','Elek');
INSERT INTO Parents (first_name, last_name) VALUES ('Locsolok','Anna');
INSERT INTO Parents (first_name, last_name) VALUES ('Kezmuves','Kelemen');
INSERT INTO Kids (first_name, last_name, parents_id) VALUES ('Nagy','Zolika', (SELECT id FROM Parents WHERE last_name = 'Elek'));
INSERT INTO Kids (first_name, last_name, parents_id) VALUES ('Cserkesz','Misike', (SELECT id FROM Parents WHERE last_name = 'Elek'));
INSERT INTO Kids (first_name, last_name, parents_id) VALUES ('Mézesb','Ödönke', (SELECT id FROM Parents WHERE last_name = 'Anna'));

KidsRepo. java

public interface KidsRepo extends CrudRepository<Kids, Long> {
   List<Kids> findKidsByParentId(Parents Id);
}

HomeController. java

@Controller
public class HomeController {
    KidsRepo kidsRepository;

    @Autowired
    public void setKidsRepository(KidsRepo kidsRepository) {
        this.kidsRepository = kidsRepository;
    }
}

KidsService. java

@Service
public class KidsService {
    KidsRepo kidsRepository;
    ParentsRepo parentsRepository;

    @Autowired
    public void setKidsRepository(KidsRepo kidsRepository) {
        this.kidsRepository = kidsRepository;
    }
    @Autowired
    public void setParentsRepository(ParentsRepo parentsRepository) {
        this.parentsRepository = parentsRepository;
    }
    public List<Kids> getKids(Parents id) {
        return kidsRepository.findKidsByParentId(id);
    }
}

Ответы [ 4 ]

2 голосов
/ 02 марта 2020

Чтобы получить список детей по их родительскому идентификатору, вы можете написать запрос в KidsRepo следующим образом:

@Query("select k from Kids k where k.parents.id = :parentId")
List<Kids> findKidsByParentId(Long parentId);
1 голос
/ 02 марта 2020

В реализации вашего домена не допускается наличие нескольких родителей, но только одного, поэтому у вас не может быть двух родителей на одного ребенка, и ваши требования не будут приняты. Для реализации нескольких родителей попробуйте изменить поле @ OneToMany в @ ManyToMany и поле сбора (от предложения topi c).

Для достижения цели и поиска имя всех детей по родителям, вы можете объединить имя метода JPA и Java 8 Stream API, реализуя в два этапа.

1 - Поместите этот метод в свой репозиторий:

// find All kids by parent id (_ to enter into id of the parents is not necessary)
List<Kids> findAllByParentsId(long parentId);

2 - В вашем сервисе используйте имя метода репозитория и соберите имена:

List<String> kidsName = kidsRepository.findAllByParentsId(42l).stream()
                 .map(Kids::getFirstName)
                 .collect(Collectors.toList());
1 голос
/ 02 марта 2020

Вы используете Spring Data .
Таким образом, вы можете создать свой собственный метод для этой цели:

public interface KidsRepository extends CrudRepository<Kids, Long> {
    List<Kids> findByParent_Id(Long id);
}

Кроме того, вам не нужно объявлять List<Kids> findAll() этот метод будет доступен по умолчанию для других распространенных операций CRUD.


ОБНОВЛЕНО:

The program stores kids and one of their parents (or both)

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

Ваш родительский объект не нужно даже знать о любых детях . Только дети должны хранить ссылку на своего родителя. Кроме того, некоторая часть кода должна быть изменена в соответствии с новыми данными.

Родительский класс:

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private String firstName;
    @NotNull
    private String lastName;
}

Родительский контроллер:

@Controller
@AllArgsConstructor
public class ParentController {
    private KidService kidService;
    private ParentService parentService;

    /**
     * The program stores kids and one of their parents (or both)
     * when I search the name of the parent the program should display the name of kid (or kids).
     */
    private String findParent(@PathVariable String parentName, Model model) {
        Parent parent = parentService.findParent(parentName);
        List<Kid> kids = kidService.findAllKidsForParent(parentName);

        model.addAttribute("parent", parent);
        model.addAttribute("children", kids);
        // render to appropriate view
        return "home";
    }
}

Родительский сервис:

@Service
@AllArgsConstructor
public class ParentService {
    private ParentRepository parentRepository;

    public Parent findParent(String parentName) {
        return parentRepository.findParentByFirstName(parentName);
    }
}

Родительский репо:

public interface ParentRepository extends JpaRepository<Parent, Long> {
    Parent findParentByFirstName(String firstName);
}

Ниже вы можете найти подробности для Kid .

Класс для детей:

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Kid {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private String firstName;
    @NotNull
    private String lastName;

    @NotNull
    @ManyToOne
    private Parent parent;
}

Услуги для детей:

@Service
@AllArgsConstructor
public class KidService {
    private KidRepository kidRepository;

    public List<Kid> findAllKidsForParent(String parentName) {
        return kidRepository.findAllByParent_FirstName(parentName);
    }
}

Репо для детей:

public interface KidRepository extends JpaRepository<Kid, Long> {
    List<Kid> findAllByParent_FirstName(String firstName);
}

Также я использую Lombok framework аннотации там

Несколько советов по поводу вашего кода:

  • пожалуйста, отформатируйте его. Если вы используете Intellij, вы можете использовать Ctrl + Alt + L
  • имя переменной из строчной буквы. id допустимо, а Id не
  • для Hibernate / JPA или других платформ, идентификаторы из чисел должны иметь типы объектов . Как Long, целое число . Не примитивные типы: long, int .
1 голос
/ 02 марта 2020

Создайте еще один репозиторий Crud, который извлекает родителей. Затем вы можете вызвать parent.getKids(), когда у вас есть объект класса Parent.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...