Spring data jpa懶加載

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

https://blog.csdn.net/u010504064/article/details/47832721

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章