Hibernate Entity Mapping Sinhala Guide | Java ORM Tutorial
කට්ටියටම ආයුබෝවන්! Hibernate Entity Mapping Sinhala Guide එකට සාදරයෙන් පිළිගන්නවා!
අද අපි කතා කරන්න යන්නේ Java Development වලදී හරිම වැදගත් වෙන, ඒ වගේම ගොඩක් දෙනෙක්ට තියෙන පොඩි ගැටළුවක් විසඳගන්න පුළුවන් වෙන මාතෘකාවක් ගැන – ඒ තමයි Hibernate Entity Mapping.
ඕගොල්ලෝ Java application එකක් හදනකොට, Database එකක් එක්ක වැඩ කරන්න වෙන අවස්ථා ඕන තරම් තියෙනවා. සාමාන්යයෙන් SQL queries ලියලා, ResultSet handle කරලා, ඒ data ටික Java objects වලට convert කරලා තමයි අපි වැඩ කරන්නේ. ඒත් මේක හරිම වෙහෙසකර, ඒ වගේම වැරදි වෙන්න තියෙන ඉඩකඩත් වැඩියි, විශේෂයෙන්ම විශාල projects වලදී. මෙන්න මේකට තමයි ORM (Object-Relational Mapping) tools අපිට උදව් වෙන්නේ.
ORM කියන්නේ මොකක්ද? සරලවම කිව්වොත්, ඒකෙන් වෙන්නේ අපේ Java objects ටික database tables වලට convert කරන එකයි, ඒ වගේම database එකේ data ටික Java objects වලට convert කරන එකයි. මේ ක්රියාවලිය හරහා අපි SQL queries ලියනවා වෙනුවට Java objects එක්කම වැඩ කරන්න පුළුවන්. Hibernate කියන්නේ මේ ORM ලෝකේ ඉන්න ප්රබලම සහ ජනප්රියම Framework එකක්.
මේ tutorial එකෙන් අපි Hibernate Entity Mapping වල මූලිකම දේවල් ගැන සවිස්තරාත්මකව කතා කරනවා. විශේෂයෙන්ම, Java Class එකක් database table එකකට map කරන්නේ කොහොමද කියන එකයි අපේ ප්රධාන අවධානය. මේ සඳහා අපි @Entity, @Table, @Id, @GeneratedValue සහ @Column වැනි JPA (Java Persistence API) annotations ගැන ඉගෙන ගනිමු.
මේක අවසාන වෙනකොට, ඕගොල්ලන්ට පුළුවන් වෙයි තමන්ගේම Java application එකක් ඇතුළේ Hibernate Entity mapping implement කරන්න. ඉතින්, අපි පටන් ගමුද?
1. Hibernate සහ ORM (Object-Relational Mapping) කියන්නේ මොනවද?
මුලින්ම අපි බලමු ORM කියන්නේ මොකක්ද කියලා. ORM කියන්නේ Programming paradigm එකක්. මේකෙන් අපිට relational databases (වගු සහිත databases) සහ object-oriented programming languages (Java වගේ) අතර පාලමක් හදලා දෙනවා. සරලවම කිව්වොත්, අපේ Java objects ටික database tables වලටත්, database tables වල තියෙන data ටික Java objects වලටත් map කරන process එක තමයි ORM එකකින් කරන්නේ.
Hibernate කියන්නේ Java programming language එක සඳහා තියෙන open-source ORM Framework එකක්. Hibernate එකෙන් Java developers ලාට relational database එක්ක වැඩ කරන එක හුඟක් පහසු කරනවා. SQL queries ලියන එකෙන් ලැබෙන වෙහෙස අඩු කරනවා, ඒ වගේම object-oriented විදිහට database data එක්ක වැඩ කරන්න පුළුවන් කරනවා.
Hibernate පාවිච්චි කිරීමේ වාසි:
- Boilerplate Code අඩු කරනවා: SQL queries සහ JDBC code ලියන එක හුඟක් අඩු වෙනවා.
- Object-Oriented Programming (OOP) වලට සහය: Database data objects විදිහට handle කරන්න පුළුවන්.
- Database Independence: අපි පාවිච්චි කරන database එක මාරු කළොත්, අපේ code එකේ ලොකු වෙනස්කම් කරන්න ඕනේ නැහැ.
- Performance වැඩි කරනවා: Caching mechanisms වගේ දේවල් නිසා application performance වැඩි වෙනවා.
- Transaction Management: Database transactions පහසුවෙන් handle කරන්න පුළුවන්.
2. Java Class එකක් Entity එකක් විදිහට හඳුන්වා දීම: @Entity Annotation එක
Hibernate භාවිතයෙන් Java Class එකක් Database Table එකකට map කරන්න නම්, මුලින්ම ඒ Class එක Entity එකක් කියලා Hibernate වලට කියන්න ඕනේ. මේකට අපි javax.persistence.Entity annotation එක පාවිච්චි කරනවා.
@Entity annotation එක Class එකකට උඩින් ලියන්න ඕනේ. මේකෙන් Hibernate වලට කියනවා මේ Class එක Database Table එකක data නියෝජනය කරනවා කියලා.
import javax.persistence.Entity;
@Entity
public class Student {
// Class properties and methods
}
මේ Student Class එකට @Entity annotation එක දැම්මම, Hibernate ස්වයංක්රීයව (by default) මේ Class එකේ නමට සමාන Database Table එකක් එක්ක මේක map කරන්න උත්සාහ කරනවා. ඒ කියන්නේ, මේ උදාහරණය අනුව, Hibernate එක Student කියලා Table එකක් database එකේ හොයයි.
හැබැයි, සමහර වෙලාවට අපිට ඕනේ නැහැ Class එකේ නමම Table එකේ නම විදිහට පාවිච්චි කරන්න. සමහර වෙලාවට Table එකේ නම වෙනස් වෙන්න පුළුවන්, නැත්නම් නීති රීති අනුව Class එකේ නමට වඩා වෙනස් නමක් දෙන්න සිද්ධ වෙන්න පුළුවන්. මෙන්න මේ වගේ අවස්ථාවලට තමයි ඊළඟට එන @Table annotation එක වැදගත් වෙන්නේ.
3. Database Table නම Define කරමු: @Table Annotation එක
Class එකේ නම සහ Database Table එකේ නම වෙනස් නම්, නැත්නම් අපිට නිශ්චිතවම Table එකේ නම specify කරන්න ඕනේ නම්, අපිට javax.persistence.Table annotation එක පාවිච්චි කරන්න පුළුවන්.
@Table annotation එක @Entity annotation එකත් එක්කම Class එකට උඩින් ලියනවා. මේකේ name attribute එකෙන් අපිට ඕනේ Database Table එකේ නම දෙන්න පුළුවන්.
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "student_details") // 'student_details' කියන table එකට map වෙනවා
public class Student {
// Class properties and methods
}
දැන් මේ උදාහරණය අනුව, අපේ Student Class එක map වෙන්නේ student_details කියන Table එකටයි. @Table annotation එකට තව attributes කිහිපයකුත් තියෙනවා:
schema: සමහර databases වල tables organize කරන්නේ schema ඇතුළේ. මේ attribute එකෙන් අපිට schema එක specify කරන්න පුළුවන් (උදා:@Table(name = "users", schema = "public")).catalog: Database catalog එක specify කරන්න පුළුවන්.uniqueConstraints: Table එකට unique constraints add කරන්න මේක පාවිච්චි කරන්න පුළුවන් (උදා:@Table(name = "employees", uniqueConstraints = {@UniqueConstraint(columnNames = {"email_address"})})).
4. Primary Key එක Identify කරමු: @Id සහ @GeneratedValue
ඕනෑම Database Table එකක Primary Key එකක් අත්යවශ්යයි. Primary Key එකක් කියන්නේ Table එකේ තියෙන සෑම row (record) එකක්ම අනන්යව හඳුනාගන්න පුළුවන් field එකක් (column එකක්). Hibernate වලදීත්, අපි Entity එකකට Primary Key එකක් හඳුන්වා දෙන්න ඕනේ.
මේ සඳහා අපි javax.persistence.Id annotation එක පාවිච්චි කරනවා. මේක Class එකේ Primary Key එක නියෝජනය කරන field එකට උඩින් ලියන්න ඕනේ.
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Student {
@Id
private Long id; // This is the primary key
// Other fields
}
බොහෝ වෙලාවට Primary Key එකේ අගය ස්වයංක්රීයව generate වෙන්න ඕනේ. Database එකෙන්ම මේක handle කරන්න පුළුවන් (උදා: AUTO_INCREMENT). මේ සඳහා අපි javax.persistence.GeneratedValue annotation එක පාවිච්චි කරනවා.
@GeneratedValue annotation එකට strategy attribute එකක් තියෙනවා. මේකෙන් Key එක generate කරන විදිහ specify කරන්න පුළුවන්. බහුලව පාවිච්චි වෙන strategies තමයි:
GenerationType.AUTO: Database එකට ගැලපෙන හොඳම strategy එක Hibernate විසින් තෝරාගන්නවා.GenerationType.IDENTITY: Database වල Auto Increment columns වලට ගැලපෙනවා (උදා: MySQLAUTO_INCREMENT).GenerationType.SEQUENCE: Database sequences භාවිත කරනවා (උදා: PostgreSQLSERIAL).GenerationType.TABLE: Separate Table එකක් පාවිච්චි කරනවා ID generate කරන්න.
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
@Entity
@Table(name = "student_details")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // Database Auto-Increment එක පාවිච්චි කරනවා
private Long id;
private String name;
private String email;
// Getters and Setters
}
මේ විදිහට @Id සහ @GeneratedValue භාවිතයෙන් අපිට Primary Key එක හරි විදිහට map කරගන්න පුළුවන්.
5. Basic Field Mapping: @Column Annotation එක සහ වෙනත් දේවල්
Primary Key එකට අමතරව, Entity එකේ තියෙන අනිත් fields ටිකත් Database Table එකේ Columns වලට map කරන්න ඕනේ. මේකට අපි javax.persistence.Column annotation එක පාවිච්චි කරනවා. මේක Field එකට උඩින් ලියන්න ඕනේ.
@Column annotation එකේ ප්රධාන attributes කිහිපයක් තියෙනවා:
name: Column එකේ නම. Field එකේ නම සහ Column එකේ නම වෙනස් නම් මේක පාවිච්චි කරනවා. (Default එක තමයි Field එකේ නමම).nullable: මේ Column එකNULLවෙන්න පුළුවන්ද බැරිද කියලා specify කරනවා (Default එකtrue).length: String type Columns වල උපරිම දිග specify කරනවා (Default එක 255).unique: මේ Column එකේ values unique වෙන්න ඕනේද කියලා specify කරනවා (Default එකfalse).precisionසහscale: Floating point numbers (BigDecimal,double) වල නිරවද්යතාවය (precision) සහ දශමස්ථාන ගණන (scale) specify කරන්න.
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Column;
import javax.persistence.Table;
@Entity
@Table(name = "student_details")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "student_name", nullable = false, length = 100)
private String name;
@Column(name = "student_email", unique = true, nullable = false)
private String email;
@Column(name = "age")
private Integer studentAge;
// Default constructor
public Student() {
}
// Parameterized constructor
public Student(String name, String email, Integer studentAge) {
this.name = name;
this.email = email;
this.studentAge = studentAge;
}
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getStudentAge() {
return studentAge;
}
public void setStudentAge(Integer studentAge) {
this.studentAge = studentAge;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", studentAge=" + studentAge +
'}';
}
}
මේ උදාහරණයේදී අපි studentAge කියන field එකට @Column annotation එක දැම්මේ නැහැ. එහෙම නොදැම්මත් Hibernate එකෙන් default විදිහට field එකේ නම (studentAge) භාවිතයෙන් Column එකක් map කරනවා. හැබැයි අපි name සහ email fields වලට @Column එක දාලා තියෙන්නේ, database columns වලට student_name සහ student_email කියන නම් දීලා, ඒ වගේම nullable, length, unique constraints දාන්න අවශ්ය නිසා.
6. ප්රායෝගික උදාහරණයක්: Hibernate භාවිතයෙන් Data Save කරමු
දැන් අපි බලමු මේ Entity Class එකක් භාවිතයෙන් Database එකට data save කරන්නේ කොහොමද කියලා. මේකට Hibernate configuration එකක් සහ Main Class එකක් අවශ්ය වෙනවා.
a. Hibernate Configuration (hibernate.cfg.xml)
මේ file එක src/main/resources folder එක ඇතුළේ තියෙන්න ඕනේ. මේකෙන් database connection details සහ Hibernate settings define කරනවා.
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings (PostgreSQL) -->
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/testdb</property>
<property name="hibernate.connection.username">postgres</property&n>
<property name="hibernate.connection.password">password</property>
<!-- SQL dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<!-- Echo all executed SQL to stdout -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<!-- develop කරනකොට මේක පහසුයි. Production වලදී පාවිච්චි කරන්න එපා! -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- Mention annotated classes -->
<mapping class="com.yourcompany.entity.Student"/> <!-- ඔබේ package එකට අනුව මෙතන වෙනස් කරන්න -->
</session-factory>
</hibernate-configuration>
සැලකිය යුතුයි: jdbc:postgresql://localhost:5432/testdb, postgres, password වැනි තොරතුරු ඔබේ database එකට අනුව වෙනස් කරන්න. hibernate.hbm2ddl.auto property එක update විදිහට දැම්මම Hibernate එකෙන් අපි define කරපු entities වලට අනුව database schema එක update කරනවා. මේක Development වලදී විතරක් පාවිච්චි කරන්න! Production environment වලදී මේකෙන් අනවශ්ය විනාශයන් වෙන්න පුළුවන්.
b. Hibernate Utility Class (HibernateUtil.java)
Hibernate SessionFactory එක build කරගන්න utility class එකක් හදාගමු.
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
// Create Configuration object
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
// Build SessionFactory from configuration
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error creating SessionFactory: " + e.getMessage());
}
}
return sessionFactory;
}
public static void shutdown() {
if (sessionFactory != null) {
sessionFactory.close();
}
}
}
c. Main Application Class (App.java)
දැන් අපි Student Entity එකක් save කරලා බලමු.
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.yourcompany.entity.Student; // ඔබේ package එකට අනුව මෙතන වෙනස් කරන්න
public class App {
public static void main(String[] args) {
Transaction transaction = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
// Start a transaction
transaction = session.beginTransaction();
// Create a new Student object
Student student1 = new Student("Kamal Perera", "[email protected]", 22);
Student student2 = new Student("Nimal Fernando", "[email protected]", 24);
// Save the Student objects
session.save(student1);
session.save(student2);
// Commit transaction
transaction.commit();
System.out.println("Students saved successfully!");
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
} finally {
HibernateUtil.shutdown(); // Close the SessionFactory when done
}
}
}
මේ code එක run කළාට පස්සේ, ඔබේ database එකේ student_details Table එකට Kamal Perera සහ Nimal Fernando කියන students ලාගේ data ඇතුල් වෙලා තියෙන්න ඕනේ. Console එකේ Hibernate එකෙන් generate කරපු SQL queries ටිකත් බලාගන්න පුළුවන්.
අවසන් වශයෙන්
ඉතින්, අද අපි Hibernate Entity Mapping වල මූලිකම දේවල් ගැන ඉගෙන ගත්තා. අපි @Entity, @Table, @Id, @GeneratedValue, සහ @Column වැනි annotations භාවිතයෙන් Java Class එකක් database table එකකට map කරන්නේ කොහොමද කියලා විස්තරාත්මකව බැලුවා. ඒ වගේම, ප්රායෝගික උදාහරණයක් හරහා Hibernate භාවිතයෙන් data save කරන්නේ කොහොමද කියලත් අපි දැක්කා.
Hibernate කියන්නේ හරිම ප්රබල tool එකක්. මේකේ තව බොහෝ දේවල් තියෙනවා (relationships, caching, criteria queries වගේ). මේක තමයි ආරම්භය. දැන් ඕගොල්ලන්ට පුළුවන් තමන්ගේම applications වලට මේ concepts implement කරන්න පුරුදු වෙන්න.
මේ tutorial එක ඕගොල්ලන්ට ප්රයෝජනවත් වෙන්න ඇති කියලා හිතනවා. මොනවා හරි ප්රශ්න තියෙනවා නම්, නැත්නම් මේ සම්බන්ධයෙන් තව මොනවා හරි අලුත් දේවල් ඉගෙන ගන්න ඕනේ නම්, කමෙන්ට් සෙක්ෂන් එකේ අදහස් දක්වන්න! ඔයාගේ අත්දැකීම් අපිත් එක්ක බෙදාගන්න. ඉස්සරහට මේ වගේම තවත් වැදගත් ලිපි වලින් හම්බවෙමු!