
Writing Complex Queries
Table of Contents [-]
Introduction #
This article is going to outline how to write more complex queries within Liferay, outside of the normal finders that Liferay's ServiceBuilder supports within the service.xml.
Using ServiceBuilder #
The first step requires creating a service.xml on which you will run ServiceBuilder (see Services, entities, and ServiceBuilder). The important step here is making sure that for the entity element you provide a fully qualified class name for the attribute "persistence-class". An example is:
<entity name="ExtBlogs" local-service="true" remote-service="false" persistence-class="com.ext.portlet.blogs.service.persistence.ExtBlogsPersistenceImpl">
What this will do is setup the appropriate spring.xml file to point to your custom persistence class, rather than having it point at the entity generated persistence class. But as the dtd states: "This class must implement the generated persistence interface or extend the generated persistence class."
Although you could simply write your complex query within the generated service layer classes (i.e. ServiceImpl.java), this breaks the separation of layers. Service layer classes should only contain business logic, whereas interactions with the database should live within the persistence layer.
Once you've created all your stubs classes by running ServiceBuilder on your service.xml, you will need to create your custom persistence class (the one you defined in your attribute above). In this particular case, we will need to create com.ext.portlet.blogs.service.persistence.ExtBlogsPersistenceImpl. (NOTE: creating a persistence Impl class is specific to 4.3. In previous versions, you will need to just create something like com.ext.portlet.blogs.service.persistence.ExtBlogsPersistence.) However, remember that we need to implement the interface or extend the generated persistence class, as defined by the dtd. In this particular case, we'll simply extend the generated persistence class, so our class declaration within the file should look something like:
public class CustomExtBlogsPersistenceImpl extends ExtBlogsPersistenceImpl {
You would then add your custom method to this class:
public List findByU_G(long userId, long groupId) { // add custom query here // this can be HQSL, JDBC call, etc. }
The next step is then to create a custom Util class and then add a method that will call your custom persistence class:
public class CustomExtBlogsUtil extends ExtBlogsUtil {
Then add your method to this class as well:
public List findByU_G(long userId, long groupId) { throws SystemException { CustomExtBlogsPersistenceImpl persistence = (CustomExtBlogsPersistenceImpl)getPersistence(); return persistence.findByU_G(userId, groupId); }
Now that the you have the persistence class and the Util class created, it's just a matter of calling the Util class from your service layer class:
public class ExtBlogsLocalServiceImpl extends ExtBlogsEntryLocalServiceBaseImpl { public List findByU_G(long userId, long groupId) throws PortalException, SystemException { return CustomExtBlogsUtil.findByU_G(userId, groupId); } }