Thursday, October 25, 2012

Spring MVC හඳුනා ගනිමු...


Spring framework එකේ web component එක SpringMVC ලෙස හැඳින්වෙයි.

Robust web applications නිර්මාණය සඳහා එය පහසුකම් රැසක් ලබාදෙයි.

Spring MVC Framework එක නිර්මාණය කර ඇත්තේ එහි සෑම logic එකක්ම, සෑම function එකක්ම පහසුවෙන් configure කරගත හැකි ආකාරයෙනි.

එසේම Spring, Struts/JSF/WebWork/Tapestry වැනි අනෙකුත් ජනප්‍රිය web frameworks සමඟ පහසුවෙන් integrate කරගත හැක.

එයින් අදහස් වන්නේ අපට Spring වලට උපදෙස් දෙන්න පුළුවන් වෙනත් web framework එකක් භාවිතා කරන්න කියලා.

තවද Client ට view එක display කිරීම සඳහා JSP හෝ Servlet මත tightly couple වීමක් Spring හි නැත.

Velocity, Freemarker, Excel, PDF වැනි අනෙකුත් view technologies සමඟ integrate කිරීමට ඒ අනුව හැකියාව ලැබෙයි.
-----------------------------------------------------------


Spring Web MVC වලදී command object එක, එසේත් නැත්නම් form-backing object එක ලෙස ඕනෑම object එකක් භාවිතා කිරීමට හැකිය.

ඒ සඳහා framework specific interface එකක් හෝ base class එකක් implement කිරීම අවශ්‍ය නොවෙයි.

Spring හිදී data binding කිරීම highly flexible වේ.

Type mismatch වැනි දේ මෙහිදී සැලකෙන්නේ validation errors ලෙසය ; System errors ලෙස නොවේ.








Spring web MVC එකත් අනෙකුත් බොහෝ WEB MVC Frameworks මෙන් request-driven framework එකකි.

Central Servlet එකක් මත පදනම්ව ක්‍රියාත්මක වේ.

එය නියමිත controllers වෙතට requests, dispatch කරයි.[dispatch-පණිවිඩ යැවීම හෝ පණිවිඩකරු ]

Web application development, facilitate කරන අනෙකුත් functions ද මෙමඟින් ලබාදෙයි.

Spring හි DispatcherServlet එක Spring IOC Container සමඟ සම්පූර්ණයෙන්ම integrate වී ඇත.

එමනිසා එමඟින් Spring හි ඇති සෑම feature එකක්ම භාවිතා කිරීමට අවස්ථාව ලබාදෙයි.

Spring MVC 3.0 හි request process lifecycle එක පහත පරිදිය.

1. Client විසින් web container එක වෙත request එකක් (http request එකක් ලෙස) යවනු ලබයි.

2. මෙම request එක ලබාගනු ලබන්නේ DispatcherServlet (Front Controller) එක මඟිනි. ඉන්පසු එය request එකට අදාළ handler mappings සොයාගනු ලබයි.

3. Handler mappings වලට අනුව, request එක අදාළ controller එකට යවනු ලැබෙයි.

4. Controller එක request එක process කරයි. Model and View object  එකක්, Dispatcher Servlet එක වෙත return කරයි.

5. DispatcherServlet එක මඟින් view එක resolve කරයි.[ View resolver object එකක් මඟින් ]. Resolve වන්නේ JSP හෝ Freemarker හෝ Velocity ලෙස විය හැක.

6. ඉන්පසු selected view එක client වෙත display කරනු ලබයි.

Spring 3.0 features

1. Spring 3.0 web framework එක java 5, support කරයි. Annotations based configurations support කරයි. Generics, annotations, varargs වැනි java 5 features, Spring වලදී භාවිතා කළ හැක.


Spring 3.0 MVC Configuration

 Spring 3.0 MVC සඳහා entry point එක වෙන්නේ DispatcherServlet එකයි. DispatcherServlet යනු normal servlet class එකකි. එය HttpServlet, base class එකෙන් implement වෙයි. එය web.xml file එකේ සඳහන් කළ යුතුය.


<web-app>
<servlet>
<servlet-name>abc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>abc</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

</web-app>

 *.html සහිත ඕනෑම url එකක් Spring MVC front controller එක call කරනු ලබයි.



DispatcherServlet එක initialized වූ විට එය [servlet-name]-servlet.xml file එක සොයා ගනී. එය තිබිය යුත්තේ web application එකේ WEB-INF folder එක තුළය.

Web application context එක යනු Application Context එකේ extension එකකි.[ Web application එක සඳහා අවශ්‍ය extra features සහිතව ]

WebApplicationContext එකට themes resolve කළ හැක.....

                                                   ඉතිරිය ඉදිරියට.......................








Friday, July 27, 2012

10. Named Queries, Lazy loading සහ Cascade ගැන..


Named Queries

මෙම queries, define කර ඇත්තේ mapping xml file  එකේදීය. අවශ්‍ය විට මෙම නමින් call කළ හැකිය.Application code එක තුළ sql ලිවීම වළකී.

උදා:


<sql-query name = "empdetails">
   <return alias="emp" class="com.test.Employee"/>
      SELECT emp.EMP_ID AS {emp.empid},
                 emp.EMP_ADDRESS AS {emp.address},
                 emp.EMP_NAME AS {emp.name}
      FROM Employee EMP WHERE emp.NAME LIKE :name
</sql-query>

මෙම Named query එක call කරන්නේ කෙසේද ?



List people = session.getNamedQuery("empdetails")
    .setString("TomBrady", name)
    .setMaxResults(50)
    .list();

----------------------------------------------------------------------------------

Lazy loading

lazy=true මඟින් performance improve වෙයි.Collection එකක් associate වී ඇත්නම්, එහි elements load වන්නේ, ඒ සඳහා වෙනම call කළොත් පමණි.

Parent object එක load කරන විට child objects load කළයුතුද නැත්ද යන්න set කරන්නේ මෙමඟිනි.

Parent class එකේ mapping සිදුකරන විට මෙය ලබාදිය යුතුය.

lazy=true මඟින් අදහස් වන්නේ child objects load නොකළ යුතු බවයි.(default)

එය  load කිරීමට නම් වෙනම parent.getChild() call කළ යුතුය.

සමහර අවස්ථාවල parent object එක සමඟම child object එකත් load කිරීම අවශ්‍යය වෙයි.
 එවිට lazy=false දිය යුතුය.


---------------------------------------------------------------------

Cascade


1) cascade="none", (default) -:association., ignore කරන ලෙස දැන්වීමට

2) cascade="save-update" -: object එක save/update කරන විට, transaction commit කරන විට association , navigate කර persistent instances වලටත් අදාළ වෙනස්කම් කරන්න.


3) cascade="delete" -: object එක delete කරන විට association , navigate කර persistent instances, delete කරන්න.







9. Hibernate සහ Spring, integrate කරමු.



මෙහි ප්‍රධාන පියවර දෙකකි.
1. HibernateTemplate එක Spring හි declare කිරීම
2. එයට SessionFactory  එක සම්බන්ධ කිරීම


-----------------------------------------------



Spring වල ඇති HibernateTemplate, Hibernate session සඳහා වඩා abstract layer එකක් ලබාදෙයි.

HibernateTemplate හි ප්‍රධානම කාර්යය වන්නේ Hibernate sessions open කිරීම සහ close කිරීමේ වැඩ සරල කිරීම සහ Hibernate-specific exceptions, Spring ORM exceptions බවට පත් කිරීමයි.

[Hibernate 2 ට අදාළව නම් මෙය Checked Hibernate exception එක, Unchecked Hibernate Exception එකක් බවට පත් කිරීමයි.

HibernateTemplate එක Spring හි configure කරන ආකාරය පහත xml එකේ දැක්වෙයි.


<bean id="hibernateTemplate"

class="org.springframework.orm.hibernate3.HibernateTemplate">
 <property name="sessionFactory" ref="sessionFactory" />
</bean>




---------------------------------------------------------


Hibernate Session Object එකක් සඳහා reference එකක් ලබාගැනීමේ සම්මත ක්‍රමය වන්නේ Hibernate හි Session Factory Interface එකේ implementation එකක් හරහාය.

Hibernate sessions, open කිරීම, close කිරීම සහ manage කිරීම Session Factory හි වගකීමයි.

පළමු කාර්යය වන්නේ Hibernate Session Factory Bean එක Spring වල configure කිරීමයි. 


Classes, tables map කරන්නේ annotations මඟින් නම් මෙම Hibernate Session Factory instance එක ලබා දෙන්නේ AnnotationSessionFactory Bean එක මඟිනි.

Mappings සිදු කරන්නේ xml මඟින් නම් මෙය සිදු කරන්නේ LocalSessionFactoryBean මඟිනි.


<bean id="sessionFactory"

class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
 <property name="dataSource" ref="dataSource" />
 <property name="annotatedClasses">
  <list>
   <value>hibernate.Employee</value>
  </list>
 </property>
 <property name="hibernateProperties">
  <props>
   <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
   <prop key="show_sql">true</prop>
  </props>
 </property>
</bean>

-------------------------------------------------------------------



දැන් HibernateTemplate එක Declare කරලා අවසන්.
එලෙසම එය SessionFactory එකට සම්බන්ධ කර තියෙන්නේ.

දැන් අප සූදානම් Database එකට data persist කරන්නට සහ එයින් data retrieve කරන්නට.








8. SessionFacory,session සහ HibernateTemplate හි භාවිතය


SessionFacory



Application එක සඳහා session instances ලබා දෙන්නේ SessionFactory එක මඟිනි.

සාමාන්‍යයෙන් Application එකක් සඳහා පවතින්නේ එක SessionFactory එකකි.

Application එක Hibernate මඟින් databases කීපයක් access කරනවා නම්, එක් එක් database එක සඳහා වෙන වෙනම SessionFactory අවශ්‍යය වෙයි.

Many-To-Many Relation Mapping උදාහරණයේදී Session එක භාවිතයෙන් objects, save කරන ආකාරය සළකා බලමු.

packagge abc.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class SavingTest{

public static void main (String args[] ) {

SessionFactory sf =  HibernateUtil.getSessionFactory();
Session session = sf.openSession() ;
session.beginTransaction () ;

Meeting m1 = new Meeting ("HR Meeting") ;
Meeting m2 = new Meeting ("Finance Meeting");

Employee e1 = new Employee ("kamal","perera",20000);
Employee e2 = new Employee("nimal","silva",30000);

e1.getMeetings.add(m1) ;
e1.getMeetings.add(m2);
e2.getMeetings.add(m1);

session.save(e1);
session.save(e2);

session.getTransaction();
commit();
session.close();

}
}


-----------------------------------------

HibernateTemplate


HibernateTemplate යනු helper class එකකි.
එය hibernate data access code එක සරල කරයි.

එයින් session open කිරීම සහ close කිරීමද code එක execute වූ පසු transaction, commit හෝ rollback කිරීමද සිදුකරන නිසා ඒ සඳහා code ලිවිය යුතු නොවේ.

නමුත් Hibernate 4 version එකෙන් මෙය ඉවත් කර ඇත.









Thursday, July 26, 2012

7. Many-To-Many Relation Mapping


පහත දැක්වෙන්නේ Many-To-Many relationship එකක් map කරන ආකාරය.


Meeting සහ Employee classes දෙක අතර සම්බන්ධය Many-To-Many ලෙස ගනිමු.

එනම් එක Meeting එකක Employees ලා බොහෝ සිටිය හැක.
එක Employee කෙනෙක් බොහෝ Meeting ගණනකට සහභාගි විය හැක.


a)  package abc.hibernate;

import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.ManyToMany;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.CascadeType;





@Entity
@Table(name="employee")
public class Employee{

@Id
@GeneratedValue
@Column(name="emp_id")
private Long empId;

@Column(name="first_name")
private String firstName;

@Column(name="last_name")
private String lastName;

@Column(name="birth_date")
private Date birth_date;

@Column(name="salary")
private double salary;

@ManyToMany(cascade={CascadeType.ALL })
@JoinTable(name="employee_meeting",
                       joinColumns={@JoinColumn(name="emp_id")},
                       inverseJoinColumns={@JoinColumn(name="meeting_id")})
private Set<Meeting> meetings = new HashSet<Meeting>(); 

public Employee(){
}

public Employee(String firstname, String lastname, Date birthdate, double salary){
this.firstName = firstname;
this.lastName = lastname ;
this.birthDate = birthdate ;
this.salary = salary ;
}

//Getter and Setter methods

}




---------------------------------------------------------------------------------------------




b)   package abc.hibernate;


import java.util.Date;
import java.util.HashSet;
import java.util.Set;



import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.ManyToMany;


@Entity
@Table(name="meeting")
public class Meeting {


@Id
@Column(name="meeting_id")
@GeneratedValue
private Long meetingId ;


@Column(name="subject")
private String Subject;


@Column(name="meeting_date")
private Date meetingDate;


@ManyToMany(mappedBy="meetings")
private Set<Employee> employees = new HashSet<Employee>();


private Meeting(String subject){
this.subject= subject;
this.meeting_date = new Date();
}


//Getters and Setters


}







6.One-To-Many relation mapping


පහත දැක්වෙන්නේ One-To-Many relationship එකක් map කරන ආකාරය.


Department සහ Employee classes දෙක අතර සම්බන්ධය One-To-Many ලෙස ගනිමු.

එනම් එක Department එකක Employees ලා බොහෝ සිටිය හැක.
නමුත් එක Employee කෙනෙක් අයත් වන්නේ එක Department එකකට පමණි.

a)  package abc.hibernate;

import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.ManyToOne;
import javax.persistence.JoinColumn;

@Entity
@Table(name="employee")
public class Employee{

@Id
@GeneratedValue
@Column(name="emp_id")
private Long empId;

@Column(name="first_name")
private String firstName;

@Column(name="last_name")
private String lastName;

@Column(name="birth_date")
private Date birth_date;

@Column(name="salary")
private double salary;

@ManyToOne
@JoinColumn(name="deptment_id")
private Department Department;


public Employee(){
}

public Employee(String firstname, String lastname, Date birthdate, double salary){
this.firstName = firstname;
this.lastName = lastname ;
this.birthDate = birthdate ;
this.salary = salary ;
}

//Getter and Setter methods

}






@JoinColumn යනු Entity දෙකක් සම්බන්ධ කිරීමේදී map වෙන column එකයි.
----------------------------------------------------------------------------




b)   package abc.hibernate;

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.OneToMany;


@Entity
@Table(name="department")
public class Department{


@Id
@GeneratedValue
@Column(name="department_id")
private Long departmentId;




@Column(name="depat_name")
private String departmentName;




@OneToMany(mappedBy="department")
private Set<Employee> employee ;


//getters and setters


}



























































5. One-To-One relation mapping


Hibernate mappings වලදී table අතර relations, map කිරීම ඉතාම වැදගත් කාර්යයක්.

පහත දැක්වෙන්නේ One-To-One relationship එකක් map කරන ආකාරය


Employee සහ EmployeeDetail නම් class දෙක අතර සම්බන්ධය One-To-One ලෙස ගනිමු.

එනම් එක Employee කෙනෙකුට ඇත්තේ එක EmployeeDetail එකකි.
එලෙසම එක EmployeeDetail  එකක් සම්බන්ධ වන්නේ එක Employee කෙනෙක් සමඟ පමණි.


a) package abc.hibernate;

import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="employee")
public class Employee{

@Id
@GeneratedValue
@Column(name="emp_id")
private Long empId;

@Column(name="first_name")
private String firstName;

@Column(name="last_name")
private String lastName;

@Column(name="birth_date")
private Date birth_date;

@Column(name="salary")
private double salary;

@OneToOne ( mappedBy="employee" cascade=CascadeType.ALL)
private EmployeeDetail employeeDetail;


public Employee(){
}

public Employee(String firstname, String lastname, Date birthdate, double salary){
this.firstName = firstname;
this.lastName = lastname ;
this.birthDate = birthdate ;
this.salary = salary ;
}

//Getter and Setter methods

}




b)  package abc.hibernate; 

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;


@Entity
@Table(name="employeedetail")
public class EmployeeDetail{


@Id
@Column (name="employee_id", unique=true, nullable=false)
@GeneratedValue(generator ="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property",
                                                                                     value="employee"))
private Long employeeId;


@Column(name="street")
private String street;

@Column(name="city")
private String city;


@Column(name="state")
private String state;

@Column(name="country")
private String country;


@OneToOne
@PrimaryKeyJoinColumn
private Employee emploee ;

public EmployeeDetail(){
}


public EmployeeDetail (String street, String city, String state, String country ) {
this.street= street ;
this.city = city ;
this.state = state ;
this.country = country ;
}

//getters and setters

}




























Wednesday, July 25, 2012

4. Hibernate mappings, Annotations භාවිතයෙන්...



පහත දැක්වෙන Employee class එක simple POJO class එකක්.

මෙහිදී hibernate mapping සිදු කර තිබෙන්නේ annotations භාවිතයෙන්.



package abc.hibernate;

import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="employee")
public class Employee{

@Id
@GeneratedValue
private Long empId;

@Column(name="first_name")
private String firstName;

@Column(name="last_name")
private String lastName;

@Column(name="birth_date")
private Date birth_date;

@Column(name="salary")
private double salary;

public Employee(){
}

public Employee(String firstname, String lastname, Date birthdate, double salary){
this.firstName = firstname;
this.lastName = lastname ;
this.birthDate = birthdate ;
this.salary = salary ;
}

//Getter and Setter methods

}

ඉහත  annotations වල භාවිතය පහත පරිදිය.

@Entity -  මෙමඟින් class එක entity එකක් බව ( persistent POJO class එකක් බව ) ප්‍රකාශ වෙයි.

@Table(name="xxx") -  class එක  map වියයුතු table එකේ නම


@Id -  මෙමඟින් මේ entity එකේ identifier property එක ප්‍රකාශ කරයි.

@GeneratedValue - primary key එක auto generate විය යුතු බව

@Column(name="xxx") -  attribute එක  map වියයුතු column එකේ නම




one-to-one, one-to-many සහ many-to-many relationships ඇති tables, map කරන ආකාරය ඉදිරියට...









Tuesday, July 24, 2012

3. Hibernate, configuration කරන්නේ කොහොමද?


මේ සඳහා වෙනම configuration file එකක් ලිවීමට පුළුවන්.
(hibernate.cfg.xml)

xml file එකක් වෙනුවට properties file එකකිනුත් hibernate configurations ලබාදිය හැක.

නැත්නම් මේ configuration details , spring-config.xml වැනි configuration file එකකට ඇතුළත් කරන්නත් පුළුවන්.
(Hibernate සහ spring ,integrate කරන project එකකදී)

 hibernate.cfg.xml file එකක් පහත දැක්වෙයි.

<?xml version=‘1.0’ encoding=‘UTF-8’?>

<!DOCTYPE hibernate-configuration PUBLIC
“-//Hibernate/Hibernate Configuration DTD 3.0//EN”
“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”>

<hibernate-configuration>

<session-factory>

<!-- Database connection settings -->
               

<property name=“connection.driver_class”>com.mysql.jdbc.Driver
</property>

<property name=“connection.url”>jdbc:mysql://localhost/firsthibernate
</property>

<property name=“connection.username”>root</property>
  
               <property name=“connection.password”>root</property> 

    
<!--sql dialect-->

<property name=“dialect”>org.hibernate.dialect.MySQLDialect</property>

<!-- Echo all executed SQL to stdout -->
                   
                  <property name=“show_sql”>true</property>

                <property name="hibernate.connection.pool_size">10</property>  

                   <!-- mapping සිදු කරන්නේ annotations මඟින් නම් -->     
       
<mapping class="employee.Employee" />

<!-- mapping සිදු කරන්නේ xml මඟින් නම් -->

<mapping resource="employee.Employee.hbm.xml" />



</session-factory>

</hibernate-configuration>

දැන් මේ configuration details විස්තර සහිතව සළකා බලමු.



 පළමු properties හතරෙන් දැක්වෙන්නේ MySQL database connection එක සඳහා අවශ්‍යය 

configurationsවෙයි.


driver_class යනු කුමක්ද? DBMS එකට අදාළ JDBC driver class එකයි. 
උදා: com.mysql.jdbc.Driver, org.postgresql.Driver,  
oracle.jdbc.driver.OracleDriver

url එක මඟින් database path එක දිය යුතුය.username, password යනු database එකට connect වීම
සඳහා දිය යුතු username password වෙයි.

dialect යනු hibernate මඟින් generate කළයුතු specific sql variant එකයි. Database එකට අදාළ sql ,
generateකිරීම සඳහා මෙය ලබාදිය යුතුය. උදා: org.hibernate.dialect.MySQLDialect, 
org.hibernate.dialect.PostgreSQLDialect, org.hibernate.dialect.OracleDialect ,
org.hibernate.dialect.SQLServerDialect

show_sql යන්න true කර ඇත්නම් console window එකට සියළු sql command ලබාදෙයි.


pool_size යනු hibernate database connection pool එකේ ඇති උපරිම waiting connections 
ගණනයි.

අවසන mapping files ඇති තැන ලබා දී ඇත.

මීලඟ ලිපියෙන් hibernate mapping files ලියන අයුරු.


Hibernate ලිපි පෙළ

1. Hibernate කියන්නේ මොකක්ද? 

2. Hibernate භාවිතා කිරීමේ වාසි මොනවාද?
3. Hibernate, configuration කරන්නේ කොහොමද?