将数据添加到数据库(相关表)Spring Boot

时间:2018-12-16 20:54:16

标签: java hibernate spring-boot

我的英语不好,但是我想描述我的问题。 我是春季新人。我在向数据库中添加数据时遇到了一些问题。我必须表Pc和Pc特性。它们由ID关联。在不真实的表中添加数据很容易,但是如何在相关表中添加数据呢?我应该在控制器中写些什么?下面有一些课程。

个人电脑课程:

.mdb

PcChars类:

@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;
}

PcCharactsController:

@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;
}

Characteristics.ftl:

@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";
}

3 个答案:

答案 0 :(得分:1)

您正在使用的Spring部分称为Spring数据,这是一个库,可让您在Spring应用程序中使用JPA。 JPA是一种称为ORM(对象关系映射)的框架规范。

为简单起见,在您的代码中,不再使用关系方法,而是使用对象方法。放在类的字段上的注释用于定义它们与数据库表和字段之间的映射。

因此,您不必再分别插入两个实体。您需要创建一个PC实例,然后创建一个PcChars实例,最后将chars添加到pc的chars列表中,如下所示:

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

以及当您使用存储库来保存修改时:

pcRepo.save(myPc);

JPA实现将自动为您完成工作:

  • 在PC表中插入与您的PC实例相对应的行
  • 在PC_CHARS表中插入与您的PC字符对应的行
  • 使用新插入的PC实例ID的ID设置PC_CHARS.PC_ID,以便在它们之间创建引用。

不确定,但是我认为将字符添加到pc实例时ORM也会这样做:

myChars.setPc(myPc);

为了使两个实例之间的界限互惠。

请注意,我根据您的架构使用了任意字段名称。

答案 1 :(得分:1)

由于您没有使用任何modelAttribute来将输入值直接绑定到POJO,因此可以使用简单的HttpServletRequest来获取输入属性,使用它们来创建要存储和存储的对象使用休眠

@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";
}

答案 2 :(得分:1)

我强烈建议您在使用@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);

如果您使用的是Spring Boot数据存储库,它将正确保存如下所示

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

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

使用保存的休眠实体管理器:

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

EntityManager entitymanager = emfactory.createEntityManager();

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

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

有关休眠关系的详细信息,请查看我的帖子:https://medium.com/@mstrYoda/hibernate-deep-dive-relations-lazy-loading-n-1-problem-common-mistakes-aff1fa390446