我的英语不好,但是我想描述我的问题。 我是春季新人。我在向数据库中添加数据时遇到了一些问题。我必须表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";
}
答案 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实例时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