Introduction:
Liferay Service Builder finder methods are use to
fetch the data based on columns.
Liferay Service Builder will generate finder methods
simply by configure the finder tag in service.xml file.
We have finder tag so that we can configure the
columns on which base we need to fetch the data from the table.
Go through the following articles before continue.
We need to defined finder tag in service.xml file
and this tag should be enclosed by entity tag.
Example:
<entity name="Student"
local-service="true" remote-service="true">
<!-- PK fields
-->
<column name="studentId"
type="long" primary="true"
/>
<column name="firstName"
type="String" />
<column name="lastName"
type="String" />
<column name="studentAge"
type="int" />
<column name="studentGender"
type="int" />
<column name="studentAddress"
type="String" />
<!-- Finder
methods -->
<finder name="Gender" return-type="Collection">
<finder-column
name="studentGender"/>
</finder>
</entity>
|
Inside finder tag we need defined columns names so
that SQL query will fetch the data based on defined columns.
Example
Finder
<finder name="Gender" return-type="Collection">
<finder-column
name="studentGender"/>
</finder>
Respective SQL Query
Select
* from Student where studentGender=?
|
Finder
on multiple Columns
<finder name="Gender_Age"
return-type="Collection">
<finder-column name="studentGender"/>
<finder-column name="studentAge"/>
</finder>
Respective SQL Query
Select
* from Student where studentGender=? AND student Age=?
|
Here all columns will be in Where clause and here
AND operator will be applies if the columns are more than one.
Finder
Tag and Its Attributes:
<finder
name CDATA #REQUIRED
return-type CDATA #REQUIRED
unique CDATA #IMPLIED
where CDATA #IMPLIED
db-index CDATA #IMPLIED
>
|
name:
Name attribute specify the name of the attribute and
after run the service builder respective service method will be created in
XXXUtil.java class and the methods use this attribute.
Method Syntax in XXXUtil.java
findBy[finder Name Attribute Value](--)
Example:
<finder name="Gender">
<finder-column name="studentGender"/>
</finder>
public List
findByGender(----){
}
|
return-type:
This attribute specify the data which is return by
the finder method.
It may be Collection or Entity Model Object
If the finder returns more objects then it will be
collection and in java method return type is java.util.List
If the finder is return only one value that is Entity
object Model Type.
Example:
Collection:
<finder
name="Gender_Age" return-type="Collection">
</finder>
public List findByGender_Age(--){
}
|
Single
Object
<finder name="StudentId"
return-type="Student">
<finder-column name="studentId"/>
</finder>
public Student findByStudentId(--){
}
|
unique:
If the unique value is true, then the finder must
return a unique entity and that is Entity mode object type.
Example
<finder name="StudentId"
return-type="Student"
unique="true">
<finder-column name="studentId"/>
</finder>
public Student findByStudentId(--){
}
|
where:
If any constant or static condition you want use in
where clause then we have to use where attribute
Example:
Assume in the student data we don’t want consider
the male gender. This is our specific condition.
<finder name="femaleStudents"
return-type="Collection" where="studentGender!=1">
<finder-column name="studentAge"/>
</finder>
|
In the above scenario it won’t consider male gender.
We can use all operators in where attribute bases on
data type (=, !=, <, <=, >, >=, or LIKE)
db-index:
If the db-index value is true, then the service will
automatically generate a
SQL index for this finder. The default value is
true.
finder-column
Tag
Finder column should be placed within finder tag and
it will specify the on which column base the data should be fetched.
Example:
<finder name="Gender"
return-type="Collection">
<finder-column name="studentGender"/>
</finder>
public List findByGender_Age(int studentGender){
}
|
These finder column is become method parameter in
XXXUtil.java for respective finder method.
Finder
Colum Attributes:
<!ATTLIST finder-column
name CDATA #REQUIRED
case-sensitive CDATA #IMPLIED
comparator CDATA #IMPLIED
arrayable-operator CDATA #IMPLIED
>
|
name:
Name specifies the column name for entity. Name should
match the any one of the available columns in entity. This name will be used in
method parameter name in the java method.
case-sensitive:
The attribute case-sensitive is a Boolean value and
is only used if the column is a String value
comparator
The attribute comparator takes in the values =, !=,
<, <=, >, >=, or LIKE and is used to compare this column.
<finder name="firstName"
return-type="Collection">
<finder-column name="firstName"
comparator="LIKE"/>
</finder>
|
In the above it will use like operator when it find
the records based on first name.
Greater
Than
<finder name="majorStudent"
return-type="Collection">
<finder-column name="studentAge"
comparator=">"/>
</finder>
Less
Than
<finder name="minorStudent"
return-type="Collection">
<finder-column name="studentAge"
comparator="<"/>
</finder>
|
arrayable-operator
The attribute arrayable-operator takes in the values
AND or OR and will generate an additional finder where this column's parameter
takes an array instead of a single value. Every value in this array will be
compared with the column using the comparator, and the conditions will be
combined with either an AND or OR operator.
Example:
A finder column with the = comparator and an arrayable-operator
of OR will act like an IN clause
<finder name="Age"
return-type="Collection">
<finder-column name="studentAge"
arrayable-operator="OR" />
</finder>
Respective Java Method
public
findByAge(int[] studentAges){
}
Select
* from Student where studentAge=value1 OR studentAge=value2
|
The
complete Example Snippet
<entity name="Student"
local-service="true" remote-service="true">
<!-- PK fields
-->
<column name="studentId"
type="long" primary="true"
/>
<column name="firstName"
type="String" />
<column name="lastName"
type="String" />
<column name="studentAge"
type="int" />
<column name="studentGender"
type="int" />
<column name="studentAddress"
type="String" />
<!-- Order
-->
<order by="asc">
<order-column name="studentId"
/>
</order>
<!-- Finder
methods -->
<finder name="Gender"
return-type="Collection">
<finder-column name="studentGender"/>
</finder>
<!-- Finder
methods -->
<finder name="Gender_Age" return-type="Collection">
<finder-column name="studentGender"/>
<finder-column name="studentAge"/>
</finder>
<finder name="byStudentId"
return-type="Student" unique="true"
db-index="true">
<finder-column name="studentId"/>
</finder>
<finder name="femaleStudents" return-type="Collection" where="studentGender!=1">
<finder-column name="studentAge"/>
</finder>
<finder name="firstNameLike" return-type="Collection">
<finder-column name="firstName" comparator="LIKE"/>
</finder>
<finder name="majorStudentGreaterThan" return-type="Collection">
<finder-column name="studentAge" comparator=">"/>
</finder>
<finder name="minorStudentLessThan" return-type="Collection">
<finder-column name="studentAge" comparator="<"/>
</finder>
<finder name="multipleAge" return-type="Collection">
<finder-column name="studentAge" arrayable-operator="OR" comparator="="/>
</finder>
</entity>
|
Return
Uniqu Object
<finder name="byStudentId"
return-type="Student" unique="true"
db-index="true">
<finder-column name="studentId"/>
</finder>
public static
com.meera.dbservice.model.Student findBybyStudentId(
long studentId)
throws
com.liferay.portal.kernel.exception.SystemException,
com.meera.dbservice.NoSuchStudentException
{
return getPersistence().findBybyStudentId(studentId);
}
|
Using
Where Attribute
<finder name="femaleStudents" return-type="Collection" where="studentGender!=1">
<finder-column name="studentAge"/>
</finder>
public static
java.util.List<com.meera.dbservice.model.Student> findByfemaleStudents(
int studentAge)
throws
com.liferay.portal.kernel.exception.SystemException {
return getPersistence().findByfemaleStudents(studentAge);
}
|
Like
Operator
<finder name="firstNameLike" return-type="Collection">
<finder-column name="firstName" comparator="LIKE"/>
</finder>
public static
java.util.List<com.meera.dbservice.model.Student> findByfirstNameLike(
java.lang.String
firstName)
throws
com.liferay.portal.kernel.exception.SystemException {
return getPersistence().findByfirstNameLike(firstName);
}
|
Arrayble
Operator
<finder name="multipleAge" return-type="Collection">
<finder-column name="studentAge" arrayable-operator="OR" comparator="="/>
</finder>
public static
java.util.List<com.meera.dbservice.model.Student> findBymulipleAges(
int[] studentAges)
throws
com.liferay.portal.kernel.exception.SystemException {
return getPersistence().findBymulipleAges(studentAges);
}
|
Note:
All the finder methods will be created in
XXXUtil.jav (StudentUtil.java) apart from
these methods there are many similar methods will be created and which will be useful
in pagination
Finder
on Multiple Columns
If we want find the records based on multiple
columns
<finder name="Gender_Age"
return-type="Collection">
<finder-column name="studentGender"/>
<finder-column name="studentAge"/>
</finder>
|
For above Configuration respective SQL query as
follows
Select
* from LS_Student Where studentGender=? AND StudentAge=?
|
For Above Finder Configuration respective Java
Method in XXXUtil(StudentUtil) as follows
public class StudentUtil{
public static
java.util.List<com.meera.dbservice.model.Student>
findByGender_Age(int studentGender, int studentAge)
throws
com.liferay.portal.kernel.exception.SystemException {
return getPersistence().findByGender_Age(studentGender,
studentAge);
}
}
|
Note:
When we use finder on multiple columns it will apply
the AND operator in SQL query.
When we call XXXUtil methods in JSP or Portlet
action class then we will get Exception
Example:
java.util.List<com.meera.dbservice.model.Student>
studentsList=
StudentUtil. findByGender_Age(1,20)
|
When we use above code in anywhere then we will get
Hibernate Exception
org.hibernate.HibernateException:
No Hibernate Session bound to thread
|
Solution:
We need to use these methods in XXXLocalServiceImpl
then we will call these methods using XXXLocalServiceUtil
Liferay
Service Builder finder Implementation
Steps:
- Define finder tag and finder columns in Entity Tag
- Run service Builder
- Implement Custom method in XXXLocalServiceImpl class
- Run service Builder
- Call Implemented method using XXXLocalServiceUtil
Define
finder tag and finder columns in Entity Tag
We need to define the finder tag and finder columns
with appropriate attributes that we desired and these tags should be available within
entity tag. We already know all this configuration should be defined in
service.xml file.
Example:
<entity name="Student"
local-service="true" remote-service="true">
<!-- PK fields
-->
<column name="studentId"
type="long" primary="true"
/>
<column name="firstName"
type="String" />
<column name="lastName"
type="String" />
<column name="studentAge"
type="int" />
<column name="studentGender"
type="int" />
<column name="studentAddress"
type="String" />
<!-- Finder
methods -->
<finder name="Gender_Age"
return-type="Collection">
<finder-column name="studentGender"/>
<finder-column name="studentAge"/>
</finder>
</entity>
|
Run
service Builder
Once we define the finder tag and its column we need
to run service builder then all finder java methods will be create in
respective entity XXXUtil java class.
Implement
Custom method in XXXLocalServiceImpl class
Whenever we get the requirement to write our custom
methods then we need to implement in respective entity local service
implementation class
XXXLocalServiceImpl
StudentLocalServiceImpl
|
Assume scenario we are not able to call finder methods
form StudentUtil so we will implement
custom method in StudentLocalServiceImpl.java
public java.util.List<com.meera.dbservice.model.Student>
findByGenderAndAge(int studentGender, int studentAge)
throws
com.liferay.portal.kernel.exception.SystemException {
return StudentUtil.findByGender_Age(studentGender,
studentAge);
}
|
Here we have implemented our custom method in
XXXLocalServiceImpl (StudentLocalServiceImpl.java) and inside the custom method
we have used XXXUtil methods.
Like this we can use XXXServiceUtil and XXXUtil methods
in XXXLolcalServiceImpl custom method implementation.
Note:
XXXLocalServiceImpl class available in basepackage.service.impl
path
Run
service Builder
Once we implement the custom method in
XXXServiceImpl then we need to run service builder using ant build-service
target from ant view in eclipse.
After run service builder respective method
signature will be created in XXXLocalServiceUtil class.
Note:
For every change in XXXLocalServiceImpl class we
need re run the service builder.
Call
Implemented method using XXXLocalServiceUtil
Now the method is available in XXXLocalSeriviceUtil
class so that we can call method anywhere.
Example:
Method
in StudentUtil.java
public class StudentUtil{
public static
java.util.List<com.meera.dbservice.model.Student>
findByGender_Age(
int studentGender, int studentAge)
throws
com.liferay.portal.kernel.exception.SystemException {
return getPersistence().findByGender_Age(studentGender,
studentAge);
}
}
|
Note:
We can’t call above method directly
Implement
the Custom method in StudentLocalServiceImpl.java
public class
StudentLocalServiceImpl extends
StudentLocalServiceBaseImpl
{
public
java.util.List<com.meera.dbservice.model.Student>
findByGenderAndAge(
int studentGender, int studentAge)
throws
com.liferay.portal.kernel.exception.SystemException {
return StudentUtil.findByGender_Age(studentGender,
studentAge);
}
}
|
Respective
method Signature in StudentLocalServieUtil.java
public static
java.util.List<com.meera.dbservice.model.Student>
findByGenderAndAge(
int studentGender, int studentAge)
throws
com.liferay.portal.kernel.exception.SystemException {
return getService().findByGenderAndAge(studentGender,
studentAge);
}
|
Note:
Method signature available after run the service builder
Using
custom method in JSP page or Portlet Action Class
java.util.List<Student>
studentsList=
StudentLocalServiceUtil. findByGenderAndAge(1,20)
|
Complete
code for Example
Cutome
Method Implemetation(StudentLocalServiceImpl.java)
public class
StudentLocalServiceImpl extends StudentLocalServiceBaseImpl {
public
java.util.List<com.meera.dbservice.model.Student> findByGenderAndAge(
int studentGender, int studentAge)
throws
com.liferay.portal.kernel.exception.SystemException {
return StudentUtil.findByGender_Age(studentGender,
studentAge);
}
public
java.util.List<com.meera.dbservice.model.Student>
usingArrableOperatorOnFindeCoumn(
int[] studentAges)
throws
com.liferay.portal.kernel.exception.SystemException {
return StudentUtil.findBymulipleAges(studentAges);
}
public
com.meera.dbservice.model.Student usingUniqueAttributeforFindertag(
long studentId)
throws
com.liferay.portal.kernel.exception.SystemException,
com.meera.dbservice.NoSuchStudentException
{
return StudentUtil.findBybyStudentId(studentId);
}
public
java.util.List<com.meera.dbservice.model.Student>
usingWhereAttrobuteInFinderTag(
int studentAge)
throws
com.liferay.portal.kernel.exception.SystemException {
return StudentUtil.findByfemaleStudents(studentAge);
}
public
java.util.List<com.meera.dbservice.model.Student>
usingLikeOperatorOnFinderColumn(
java.lang.String
firstName)
throws
com.liferay.portal.kernel.exception.SystemException {
return StudentUtil.findByfirstNameLike(firstName);
}
public
java.util.List<com.meera.dbservice.model.Student>
usingGreaterThanOnFinderCoulumn(
int studentAge)
throws
com.liferay.portal.kernel.exception.SystemException {
return StudentUtil.findBymajorStudentGreaterThan(studentAge);
}
public
java.util.List<com.meera.dbservice.model.Student>
usingLessThanOnFinderCoulumn(
int studentAge)
throws
com.liferay.portal.kernel.exception.SystemException {
return StudentUtil.findByminorStudentLessThan(studentAge);
}
}
|
Calling
method in JSP page (/html/jsps/finder_methods_usage.jsp)
<%@page import="com.liferay.portal.kernel.util.ListUtil"%>
<%@page import="com.meera.dbservice.model.Student"%>
<%@page import="java.util.List"%>
<%@page import=
"com.meera.dbservice.service.StudentLocalServiceUtil"%>
<%@ include
file="init.jsp"%>
<a href="<portlet:renderURL
/>">«Home</a>
<div class="separator"></div>
<h2>The following
method return only one Student Object
</h2><br/>
<b>StudentLocalServiceUtil.usingUniqueAttributeforFindertag(1)</b><br/>
<h2>The following
method is example for
Arrayble Operator and method take
array of values</h2><br/><br/>
<%
int[] ageArray =
{29,34,23};
%>
<b>int[] ageArray =
{29,34,23};</b><br/>
<b>StudentLocalServiceUtil.usingArrableOperatorOnFindeCoumn(ageArray)</b><br/>
<%="Number
studenr"+StudentLocalServiceUtil.usingArrableOperatorOnFindeCoumn(ageArray)
+"<br/>"%><br/>
<h2>The following
method is example for Like Operator</h2><br/><br/>
<b>StudentLocalServiceUtil.usingLikeOperatorOnFinderColumn("meera")</b><br/>
<%="Number of
Students using Like Operator:"+StudentLocalServiceUtil.
usingLikeOperatorOnFinderColumn("meera")+"<br/>"%>
<h2>The following
method is example for Greater then Operator</h2><br/>
<b>StudentLocalServiceUtil.usingGreaterThanOnFinderCoulumn(23)</b><br/>
<%="Number of
Students greater then Age 23:"+StudentLocalServiceUtil.
usingGreaterThanOnFinderCoulumn(23)+"<br/>"%><br/>
<h2>The following
method is example for Less then Operator</h2><br/>
<b>StudentLocalServiceUtil.usingLessThanOnFinderCoulumn(30)</b><br/>
<%="Number of
Students Less then Age 23:"+StudentLocalServiceUtil.usingLessThanOnFinderCoulumn(30)+"<br/>"%>
<h2>The following
method is example for
using Where
attribute in Finder tag and it always fetch Female Students</h2><br/><br/>
<b>StudentLocalServiceUtil.usingWhereAttrobuteInFinderTag(27)</b><br/>
<%="Number of
Female:"+StudentLocalServiceUtil.usingWhereAttrobuteInFinderTag(27)+
"<br/>"%><br/>
|
Download
Liferay Service Builder Finder Methods Portlet
Environment:
Liferay
IDE 2.x+Eclipse (Kepler) +Liferay Plugins SDK 6.2+Tomcat 7.x Liferay Portal
Bundle
Deployment
and its Working.
Download portlet you can source or war file to
deploy into liferay portal as your convenient.
Once portlet successfully deployed drag the portlet
in any desired page. Portlet is available in sample category.
In the portlet page you can click on Service Builder Finder Examples link
then you can see the search container with search inputs.
Note:
The portlet does not have any real functionality but
I just showed calling of finder methods in portlet page.
Portlet
Screens:
Default
Page
Service
Builder Finder Method Examples
Reference
Links
Author
0 comments :
Post a Comment