LazyCollectionOption.EXTRA గురించి తెలుసుకోవడం
కానీ చాలా ఆసక్తి కలిగించేది LazyCollectionOption.EXTRA విలువ. మీరు దీన్ని @LazyCollection ఉల్లేఖన విలువగా పేర్కొంటే , హైబర్నేట్ సాధ్యమైనంత ఎక్కువ కాలం పాటు సేకరణ యొక్క మూలకాలను లోడ్ చేయడంలో ఆలస్యం చేస్తుంది.
మీరు సేకరణలోని మూలకాల సంఖ్యను పొందడానికి ప్రయత్నిస్తే:
User user = session.load(User.class, 1);
List<Comment> comments = user.getComments();
int count = commetns.size();
అప్పుడు ఈ కోడ్ మొత్తానికి, హైబర్నేట్ ఒక ప్రశ్నను మాత్రమే అమలు చేస్తుంది:
SELECT COUNT(id) FROM comment WHERE user_id = 1;
అయితే, మీరు సేకరణ నుండి ఒక వ్యాఖ్యను పొందాలనుకుంటే, ఉదాహరణకు సంఖ్య 3:
User user = session.load(User.class, 1);
List<Comment> comments = user.getComments();
Comment comment = commetns.get(3);
అప్పుడు ప్రశ్న తలెత్తుతుంది: అన్ని మూలకాలను మెమరీలోకి లోడ్ చేయకుండా మూలకం మూడవది అని హైబర్నేట్ ఎలా తెలుసుకోవాలి?
ఈ సమస్యను పరిష్కరించడానికి, వ్యాఖ్య పట్టికలో అదనపు కాలమ్ చేయడానికి ప్రతిపాదించబడింది, ఇది వ్యాఖ్యల సేకరణలో వ్యాఖ్య యొక్క ఆర్డినల్ సంఖ్యను నిల్వ చేస్తుంది. మరియు దీని కోసం మీకు ప్రత్యేక ఉల్లేఖన అవసరం - @OrderColumn .
ఆ పరిష్కారం ఎలా ఉంటుందో ఇక్కడ ఉంది:
@Entity
@Table(name=”user”)
class User {
@Column(name=”id”)
public Integer id;
@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.EXTRA)
@OrderColumn(name = "order_id")
public List<Comment> comments;
}
LazyCollectionOption.EXTRA యొక్క ప్రధాన ప్రయోజనం
LazyCollectionOption.EXTRA యొక్క బలమైన ప్రయోజనాన్ని మేము @ManyToMany ఉల్లేఖనతో పేర్కొన్నప్పుడు చూస్తాము . మనకు ఒక ఉద్యోగి, టాస్క్ ఉన్న మన పాత కేసును తీసుకుందాం మరియు మనం ఒక వినియోగదారుకు అనేక పనులను కేటాయించవచ్చు.
మా జావా తరగతులు ఇలా ఉన్నాయి:
ఉద్యోగి తరగతి :
@Entity
@Table(name=”employee”)
class Employee {
@Column(name=”id”)
public Integer id;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="employee_task",
joinColumns= @JoinColumn(name="employee_id", referencedColumnName="id"),
inverseJoinColumns= @JoinColumn(name="task_id", referencedColumnName="id") )
@LazyCollection(LazyCollectionOption.EXTRA)
private Set<EmployeeTask> tasks = new HashSet<EmployeeTask>();
}
మరియు ఎంప్లాయీ టాస్క్ క్లాస్ :
@Entity
@Table(name=”task”)
class EmployeeTask {
@Column(name=”id”)
public Integer id;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="employee_task",
joinColumns= @JoinColumn(name="task_id", referencedColumnName="id"),
inverseJoinColumns= @JoinColumn(name=" employee_id", referencedColumnName="id") )
@LazyCollection(LazyCollectionOption.EXTRA)
private Set<Employee> employees = new HashSet<Employee>();
}
మరియు డైరెక్టర్కి టాస్క్ని జోడించడానికి, మీరు ఈ కోడ్ వంటిది వ్రాయాలి:
Employee director = session.find(Employee.class, 4);
EmployeeTask task = session.find(EmployeeTask.class, 101);
task.employees.add(director);
session.update(task);
session.flush();
కాబట్టి, టాస్క్ క్లాస్లోని ఉద్యోగుల ఫీల్డ్ LazyCollectionOption.EXTRA ఉల్లేఖనాన్ని కలిగి ఉంటే, ఉద్యోగుల సేకరణ (టాస్క్ క్లాస్) మరియు టాస్క్ కలెక్షన్ (ఉద్యోగి తరగతి) డేటాబేస్ నుండి ఎప్పటికీ లోడ్ చేయబడవు .
ఈ కోడ్ అమలు చేయబడినప్పుడు, ఉద్యోగి_టాస్క్ సేవా పట్టికలో ఒక రికార్డ్ మాత్రమే చొప్పించబడుతుంది, ఇది మీకు గుర్తున్నట్లుగా, ఇలా కనిపిస్తుంది:
ఉద్యోగి_టాస్క్ టేబుల్ :ఉద్యోగ గుర్తింపు | టాస్క్_ఐడి |
---|---|
1 | 1 |
2 | 2 |
5 | 3 |
5 | 4 |
5 | 5 |
4 | 7 |
6 | 8 |
4 | 101 |
జోడించిన లైన్ ఆకుపచ్చ రంగులో హైలైట్ చేయబడింది. ఈ పంక్తిని జోడించడానికి, మీరు డేటాబేస్ నుండి సేకరణలను లోడ్ చేయవలసిన అవసరం లేదు - హైబర్నేట్ అది లేకుండా చేస్తుంది. LazyCollectionOption.EXTRA డేటాబేస్తో పనిని బాగా వేగవంతం చేసినప్పుడు ఇది సరిగ్గా జరుగుతుంది.
N+1 సమస్య
కానీ, వాస్తవానికి, ఈ మోడ్ కూడా ప్రతికూలతను కలిగి ఉంది. ఉదాహరణకు, LazyCollectionOption.EXTRA ఉల్లేఖనం N+1 సమస్యను సృష్టిస్తుంది .
మీరు మీ యూజర్ యొక్క అన్ని వ్యాఖ్యలను పరిశీలించాలని నిర్ణయించుకుంటే:
User user = session.load(User.class, 1);
List<Comment> comments = user.getComments();
for (Comment comment : comments) {
System.out.println(comment);
}
అప్పుడు హైబర్నేట్ ప్రతి వ్యాఖ్య వస్తువు కోసం ప్రత్యేక అభ్యర్థనను అమలు చేస్తుంది. మరియు అన్ని వ్యాఖ్యల గణనను పొందడానికి మరో అదనపు ప్రశ్న. ఇది కోడ్ను గణనీయంగా నెమ్మదిస్తుంది.
మీ వినియోగదారు 1000 వ్యాఖ్యలను కలిగి ఉన్నట్లయితే, హైబర్నేట్ ఈ కోడ్ని అమలు చేయడానికి డేటాబేస్కు 1001 ప్రశ్నలను చేస్తుంది, అయినప్పటికీ అది ఒకదానితో చేయగలదు. మీకు ఈ తరగతిలోని అన్ని వస్తువులు అవసరమని మీకు ముందే తెలిస్తే.
GO TO FULL VERSION