More Related Content
Similar to Spring jpa share
Similar to Spring jpa share (20)
Spring jpa share
- 9. 代码表示
注释类型:
• @OneToOne
• @ManyToOne
• @OneToMany
• @ManyToMany
@Entity
@Table(name = "`database`")
public class Database {
private Long id;
private Cluster cluster;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "`id`")
public Long getId() {
return id;
}
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "`cluster_id`", nullable = false)
public Cluster getCluster() {
return cluster;
}
}
- 12. N+1问题
在查询Cluster时,查到n条结果,
每个结果还会附加一次Database
查询。
@Entity
@Table(name = "`cluster`")
public class Cluster {
private Long id;
private List<Database> databases;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "`id`")
public Long getId() {
return id;
}
@OneToMany(fetch = FetchType.EAGER,
mappedBy = "`database_id`")
public List<Database> getDatabase() {
return databases;
}
}
select * from cluster;
+
select * from database where cluster_id = ?
select * from database where cluster_id = ?
…
- 13. 解决方案
1. 使用懒加载,用到
database的时候再去
查询。
@Entity
@Table(name = "`cluster`")
public class Cluster {
private Long id;
private List<Database> databases;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "`id`")
public Long getId() {
return id;
}
@OneToMany(fetch = FetchType.LAZY , mappedBy = "`database_id`")
public List<Database> getDatabase() {
return databases;
}
}
- 14. 解决方案
2. 使用Join的方式
public interface ClusterRepository extends CrudRepository<Cluster,Long> {
@Override
@Query(value = "select * from cluster left outer join database
on id = database.cluster_id", nativeQuery = true)
Iterable<Cluster> findAll();
}
- 15. 解决方案
3. 使用Join的方式(EntityGraph)
@Entity
@Table(name = "`cluster`")
@NamedEntityGraph(name = “cluster-entity-graph",
attributeNodes = {@NamedAttributeNode(“databases")})
public class Cluster {
private Long id;
private List<Database> databases;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "`id`")
public Long getId() {
return id;
}
@OneToMany(fetch = FetchType.LAZY , mappedBy
="`database_id`")
public List<Database> getDatabase() {
return databases;
}
}
select * from cluster left outer join database
on id = database.cluster_id
public interface ClusterRepository extends
CrudRepository<Cluster, Integer> {
@Override
@EntityGraph("cluster-entity-graph")
Iterable<Cluster> findAll();
}
- 16. EntityGraph的好处
可以在运行时调整取用实体的方式,更加灵活。
EntityGraph entityGraph = entityManager.getEntityGraph("user-entity-graph");
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.fetchgraph", entityGraph);
entityManager.find(User.class, 1,properties);
entityManager.find(User.class, 1,properties); Lazy方式
Join方式