1 概述
在本节课程中,我们继续学习多表关系,学习一对多关系。
在本例中,我们使用商品分类和商品两个实体,一个商品分类对应多个商品。
同上一节一样,继续采用Spring Boot+Spring Data JPA。工程结构如下:
重点对象,两个实体。
2 实体
分类实体Classification.java
package com.wangshenghua.entity;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Classification implements Serializable {
private static final long serialVersionUID = -7378975775604019219L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private int pid;
@OneToMany(mappedBy = "classification", cascade = CascadeType.ALL)
private Set<Goods> goodes;
public Classification() {
}
public Classification(String name, int pid) {
super();
this.name = name;
this.pid = pid;
}
// Getter and Setter
}
一对多关系中,在一的一方,使用@OneToMany注释,多的一方作为一的一方属性,采用Set容器装。
1
2
@OneToMany(mappedBy = “classification”, cascade = CascadeType.ALL)
private Set goodes;
级联方式是所有,CascadeType.ALL,这意味着删除当前分类,当前分类相关的商品都将被删除。
级联关系使用时要多加小时,特别是在修改和删除时,影响大。
商品实体Goods.java
package com.wangshenghua.entity;
import java.io.Serializable;
import java.math.BigDecimal;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity
public class Goods implements Serializable {
private static final long serialVersionUID = 5060150518287868308L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String specifications;
private BigDecimal price;
private int quantity;
@ManyToOne
@JoinColumn(name = "classification_id")
private Classification classification;
public Goods() {
}
public Goods(String name, String specifications, BigDecimal price, int quantity) {
super();
this.name = name;
this.specifications = specifications;
this.price = price;
this.quantity = quantity;
}
// Getter and Setter
}
在分类往商品看,关系是一对多;从商品往分类看,关系是多对一。在商品实体中有分类属性:
@ManyToOne
@JoinColumn(name = “classification_id”)
private Classification classification;
@ManyToOne注释表示多对一,即多个当前实体对应一个Classification实体。
@JoinColumn表示指向一个外键, 这里指向一的一方分类实体,在当前实体的外键。
3 数据访问对象
Spring Data JPA对Hibernate抽象后,使用更简单,实现一个接口便具有很多功能。
package com.wangshenghua.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.wangshenghua.entity.Classification;
public interface ClassificationRepository extends JpaRepository<Classification, Integer> {
}
package com.wangshenghua.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.wangshenghua.entity.Goods;
public interface GoodsRepository extends JpaRepository<Goods, Integer> {
}
4 驱动类
package com.wangshenghua.config;
import java.math.BigDecimal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import com.wangshenghua.dao.ClassificationRepository;
import com.wangshenghua.dao.GoodsRepository;
import com.wangshenghua.entity.Classification;
import com.wangshenghua.entity.Goods;
@SpringBootApplication
@EnableJpaRepositories(basePackages = “com.wangshenghua.dao”)
@EntityScan(basePackages = “com.wangshenghua.entity”)
public class HibernateOneToManyMappingApplication implements CommandLineRunner {
@Autowired
private ClassificationRepository classificationRepository;
@Autowired
private GoodsRepository goodsRepository;
public static void main(String[] args) {
SpringApplication.run(HibernateOneToManyMappingApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// 清除表中已有数据
//classificationRepository.deleteAllInBatch();
//goodsRepository.deleteAllInBatch();
//新建分类
//Classification classify = new Classification("总分类",0);
//classificationRepository.save(classify);
//Classification subClassify = new Classification("服装",1);
//classificationRepository.save(subClassify);
// 新建商品
//Goods goods = new Goods("围巾","红色,1米5",new BigDecimal(200),300);
//goods.setClassification(subClassify);
Goods goods = new Goods("鞋子","43码黑色",new BigDecimal(388),100);
goods.setClassification(classificationRepository.getOne(2));
goodsRepository.save(goods);
}
}
5 配置文件application.properties
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=testdb
spring.datasource.password=testdb
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = update
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
6 pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.6.RELEASE
com.wangshenghua
hibernate-one-to-many-mapping
0.0.1-SNAPSHOT
hibernate-one-to-many-mapping
Demo project for Spring Boot
<properties>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
7 总结 多表关系,特别要注意理清表之间的关系。共用图形工具梳理表关系,如MySQL Workbench,梳理后可以直观地认识实体之间关系。
在Spring Data JPA创建表后,将表结构与 MySQL Workbench 建模图对比,看是否一致。
本节课程源码已经上传到github,可以前往下载。