добавить данные в базу данных (связанные таблицы) Spring Boot - PullRequest
0 голосов
/ 16 декабря 2018

Я плохо знаю английский, но пытаюсь описать свою проблему.Я новичок весной.И у меня есть некоторые проблемы с добавлением данных в мою базу данных. Мне нужно составить таблицу характеристик ПК и ПК.Они связаны по Id.Легко добавить данные в нереализованную таблицу, но как я могу добавить данные в связанную таблицу?Что я должен написать в моем контроллере?Ниже приведены некоторые классы.

Класс Pc:

@Entity
@Table(name = "pc")
public class Pc {

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

private String name;
private int price;

public Pc(){}

public Pc(String name, int price) {
    this.name = name;
    this.price = price;
}

@OneToMany
@JoinColumn(name = "pc_id")
private List<PcChars> chars = new ArrayList<>();

public List<PcChars> getChars() {
    return chars;
}

public void setChars(List<PcChars> chars) {
    this.chars = chars;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getPrice() {
    return price;
}

public void setPrice(int price) {
    this.price = price;
}

Класс PcChars:

@Entity
@Table(name = "pcChars")
public class PcChars {

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


private String name;
private String value;



public PcChars(){}

public PcChars(String name, String value) {
    this.name = name;
    this.value = value;
}

@ManyToOne
private Pc pc;



public Pc getPc() {
    return pc;
}

public void setPc(Pc pc) {
    this.pc = pc;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getValue() {
    return value;
}

public void setValue(String value) {
    this.value = value;
}

PcCharactsController:

@Controller
public class PcCharactsController {

final private PcRepo pcRepo;
final private PcCharRepo pcCharRepo;

public PcCharactsController(PcRepo pcRepo, PcCharRepo pcCharRepo) {
    this.pcRepo = pcRepo;
    this.pcCharRepo = pcCharRepo;
}

//Pc characteristics list
@GetMapping("pc/{id}/")
public String pcCharList(@PathVariable int id, Model model) throws Exception{

    Pc pc = pcRepo.findById(id).orElseThrow(() -> new Exception("PostId " + 
id + " not found"));
    List<PcChars> pcChars = pc.getChars();
    model.addAttribute("model", pc.getName());
    model.addAttribute("pcChars", pcChars);
    return "charList";
}

//add characteristic
@PostMapping("pc/{id}/")
public String addCharact(){

    return "charList";
}

Characteristics.ftl:

<html>
<head>
<title>Ho</title>
</head>
   <body>
    <div>
       <form method="post" action="/pc/${id}/">
          <input type="text" name="name">
          <input type="text" value="value">
          <input type="hidden" name="pc_id" value="${id}">
          <button type="submit">Add</button>
       </form>
    </div>
  </body>
</html>

Ответы [ 3 ]

0 голосов
/ 17 декабря 2018

Поскольку вы не используете никаких modelAttribute для привязки входных значений непосредственно к POJO, вы можете использовать простые HttpServletRequest для получения входных атрибутов, используйте их для создания объекта, который вы хотите сохранить, и сохраните его с помощью Hibernate

@PostMapping("pc/{id}/")
public String addCharact(HttpServletRequest req){
  String name = req.getParameter("name");
  String value = req.getParameter("value");
  String id = req.getParameter("id");
  PcChars pcchars = new PcChars(name,value,id); // create the corresponding constructor
  SessionFactory sessionFactory;
  Session session = sessionFactory.openSession();
  Transaction tx = null;
    try{
        tx = session.getTransaction();
        tx.begin();
        session.save(pcchars);
        tx.commit();
    }
    catch (HibernateException e) {
        if (tx!=null) tx.rollback();
        e.printStackTrace();
    } finally {
        session.close();
    }
  return "charList";
}
0 голосов
/ 17 декабря 2018

Я настоятельно рекомендую вам передать ответственность за отношения с дочерними элементами при использовании отношения @OneToMany.

Измените свой родительский класс, как показано ниже:

@OneToMany(cascade = CascadeType.ALL, mappedBy="pc")
@BatchSize(size = 10)
private List<PcChars> chars = new ArrayList<>();

public void addPcChar(PcChar pcChar) {
    this.chars.add(pcChar);
    pcChar.setPc(this);
}

На дочернем классе:

@ManyToOne
@JoinColumn(name = "pc_id")
private Pc pc;

Теперь вы можете сохранить своего родителя с ребенком, как показано ниже:

Pc pc = new Pc();
PcChar pcChar = new PcChar();
pc.addPcChar(pcChar);

Если вы используете хранилище данных с весенней загрузкой, оно сохраняет его правильно, как показано ниже

// assume your repository like below
public interface PcRepository extends CrudRepository<Pc, Integer> {}

// in your service or whatever in some place
pcRepository.save(pc);

С сохранением менеджера сущностей hibernate:

EntityManagerFactory emfactory = 
Persistence.createEntityManagerFactory("Hibernate");

EntityManager entitymanager = emfactory.createEntityManager();

entitymanager.getTransaction().begin();
entitymanager.persist(pc);
entitymanager.getTransaction().commit();

entitymanager.close();
emfactory.close();

Для получения подробной информации о взаимоотношениях hibernate посмотрите на мой пост: https://medium.com/@mstrYoda/hibernate-deep-dive-relations-lazy-loading-n-1-problem-common-mistakes-aff1fa390446

0 голосов
/ 17 декабря 2018

Часть Spring, которую вы используете, называется Spring data - библиотека, которая позволяет вам использовать JPA в вашем приложении Spring.JPA - это спецификация для фреймворков, называемая ORM (объектно-реляционное отображение).

Для простоты в вашем коде вы больше не используете реляционный подход, а объектный подход.Аннотации, которые вы помещаете в поля ваших классов, используются для определения отображений между ними и таблицами и полями вашей базы данных.

Таким образом, вам больше не нужно вставлять обе сущности по отдельности.Вам нужно создать экземпляр Pc, затем создать экземпляр PcChars и, наконец, добавить символы в список символов компьютера, например:

Pc myPc = new Pc();
PcChars myChars = new PcChars();
myPc.getChars().add(myChars);

И когда вы будете использовать свой репозиторий для сохранениямодификации с этим:

pcRepo.save(myPc);

Реализация JPA автоматически сделает всю работу за вас:

  • Вставка строки, соответствующей вашему экземпляру ПК, в таблицу ПК
  • Вставка строки, соответствующей вашим символам ПК, в таблицу PC_CHARS
  • Устанавливает PC_CHARS.PC_ID с идентификатором только что вставленного идентификатора экземпляра ПК, чтобы создать ссылку между ними.

Не уверен, но я думаю, что ORM также делает это, когда вы добавляете свои символы в экземпляр pc:

myChars.setPc(myPc);

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

Обратите внимание, что я использовал произвольные имена полей в соответствии с вашей схемой.

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