Spring data jpa懒加载
假设有两张表Person和Country,Person和Country是多对一的关系,我们定义好实体类然后自动生成数据表
配置文件中的配置信息:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/entity_demo?useSSL=false
ring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.test-on-borrow=false
spring.datasource.test-while-idle=true
spring.datasource.time-between-eviction-runs-millis=20000
# entity改变时自动更新表
spring.jpa.hibernate.ddl-auto=update
# 打印sql语句
spring.jpa.show-sql=true
Person实体类:
@Entity
@Table(name = "person")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String sex;
private Integer age;
private Integer salary;
// 在Many的一方使用立即加载
@ManyToOne(cascade = CascadeType.ALL,optional = false,fetch = FetchType.EAGER)
@JoinColumn(name = "country_id")
private Country country;
// get、set方法省略
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", salary=" + salary +
// ", country=" + country +
'}';
}
}
Country实体类:
@Entity
@Table(name = "country")
public class Country {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private Integer count;
// 在One的一方使用懒加载
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name = "country_id")
private List<Person> persons;
// get、set方法省略
@Override
public String toString() {
return "Country{" +
"id=" + id +
", name='" + name + '\'' +
", count=" + count +
", persons=" + persons +
'}';
}
}
启动项目之后就会自动生成对应的数据表
生成的表结构:
CREATE TABLE `country` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`count` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`age` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`salary` int(11) DEFAULT NULL,
`sex` varchar(255) DEFAULT NULL,
`country_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK80fgkxnj3itdo4jih9xi66r59` (`country_id`),
CONSTRAINT `FK80fgkxnj3itdo4jih9xi66r59` FOREIGN KEY (`country_id`) REFERENCES `country` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
业务需求:
查询Person数据时同时查出对应的Country数据;而查Country数据时,当使用到Person数据时才去查询Person数据
分析:
由于一个Country对应有多个Person,因此需要在Country中使用懒加载,而Person使用立即加载
方法:
在配置文件中加入配置,启用懒加载
# 启用懒加载
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
在Country实体类的persons字段上加上注解,标注其使用懒加载
// 在One的一方使用懒加载
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name = "country_id")
private List<Person> persons;
在Person实体类的country字段上加上注解,标注其使用立即加载
// 在Many的一方使用立即加载
@ManyToOne(cascade = CascadeType.ALL,optional = false,fetch = FetchType.EAGER)
@JoinColumn(name = "country_id")
private Country country;
注意,Person的toString方法中不要打印country,否则会报错:java.lang.StackOverFlowError,参考:https://blog.csdn.net/wuguidian1114/article/details/80657789
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", salary=" + salary +
// ", country=" + country +
'}';
}
参考文章:
https://blog.csdn.net/u010588262/article/details/76667283
https://blog.csdn.net/wuguidian1114/article/details/80657789