Using JDBC in many ways is tedious and error prone. There are many emerging alternatives to the brute force method of coding JDBC. JDO and similar projects such as Hibernate are a great alternative to the old approach of using JDBC. JDO and the like are great for loading pojos, but they are not ideal when it comes to querying the database for lists of data. Inline views and unions are difficult to implement in a JDO like implementation, some things are best done in a straight JDBC solution. This is one way the ValueListHandler fits into the picture.
Even in solutions where a List of pojos are retrieved from a service the ValueListHandler still encourages consistency across all services. In this case you would implement your own implemention of a ValueListAdapter, that simply calls your business method and converts the results to a ValueList.
The property file mlavwilson.properties, is one of the configuration files for the ValueListHandler service tag libs. This property file contains some properties that customize the look and feel of the web components, and some properties that customize the behavior of the tags. I will come back to this later. Note: mlavwilson.properties are deprecated in nowaday. See configuration bean for more details.
Starting with release 0.1.1 I have let Spring manage and configure the ValueListService. This is a major change from pervious versions. See Beans and the ApplicationContext for details on how to use Spring in a web environment. Or take a look at the sample app: http://nighthawkds.homedns.org:8081/valuelist . Below is the config file from the sample war.
The above file configures the bean 'valueListHandler' which is the service. This bean has a map of adapters available to the ValueListHandler. Using Spring to manage the service allows the adapters to be configured in one place in a consistent manner. To see a config file for a real application see mlwfflm.
In the previous section we outlined how to add adapters/queries to the ValueListHandler. From the sample file snippet, you see an adapter named "nbaTeams" with a query that selects from the team table. Using this query, we will step through the process involved in requesting the data that this query returns.
The ValueListHandler is an interface, so you need an implementation to work with. The easiest way to use the ValueListHandler in a web environment is to let Spring get it for you:
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(pageContext.getServletContext()); ValueListHandler vlh = (ValueListHandler) context.getBean("valueListHandler", ValueListHandler.class);
Before the service can be called the ValueListInfo must be created. The ValueListInfo contains the following:
filters | A Map used to build and populate the query. |
sortColumns | The column(s) to sort the data by. |
sortDirections | The direction(s) to sort the data. |
pageNumber | The current page, set by the service if null. |
totalNumberOfEntries | This is set by the server after the call. |
numberPerPage | The number of rows per page. |
focusProperty | The name of the property used for a focusing of the specified value. |
focusValue | The value of the focusProperty. It search for a page and row, where is situated focus property with specified value. |
//Create the info object, sort by the team column. ValueListInfo info = new ValueListInfo("team", ValueListInfo.DESCENDING, parameters);
ValueList vList = vlh.getValueList("nbateams", info);
This method call returns a ValueList, which contains a list and the info that was passed into the service. The ValueList is also an Iterator! The ValueList is retrieved in the following way:
The ValueList can now be displayed. There are a few tags to assist in the web enviroment, they are discussed latter. There is also an implementation of JTable (coming soon) that displays the ValueList. But of course you are not limited to these two display implementations.
To display the ValueList in a jsp environment there are a few taglibs to assist you.
# | Name | Since | Description |
---|---|---|---|
1 | vlh:root | 0.1.3 | This tag is required as a parent element for all other vlh tags. |
2 | vlh:retrieve | 0.1.1 |
This tag calls the ValueListHandler and requests the ValueList and
gives it to the vlh:root tag.
NOTE: This tag should be used if you are not using the MVC push model. |
5 | vlh:row | 0.1.0 | This is an iterate tag. It Iterates over the ValueList. |
6-11 | vlh:column | 0.1.0 | This tag defines a column to display. |
1: <vlh:root value="list" url="?" includeParameters="*" > 2: <vlh:retrieve name="nbaPlayers" /> 3: 4: <table width="450" class="simple" cellspacing="0" cellpadding="0"> 5: <vlh:row bean="player"> 6: <vlh:column title="playerid" property="playerid" sortable="desc" /> 7: <vlh:column title="teamname" property="teamname" sortable="desc" /> 8: <vlh:column title="firstname" property="firstname" sortable="desc" /> 9: <vlh:column title="lastname" property="lastname" sortable="desc" /> 10: <vlh:column title="status" property="status" sortable="desc" /> 11: <vlh:column title="pos" property="pos" sortable="desc" /> 12: </vlh:row> 13: </table> 14: 15: </vlh:root>
For more details on displaying a ValueList in a web environment see valuelist.war.
DefaultDynaBeanAdapter | This ValueListAdapter returns a ValueList of DynaBean(s). This is useful for simple applications or demos. I would not recommend using this adapter for a real solution. |
---|---|
DefaultDynclassAdapter | This ValueListAdapter returns a ValueList of Dynclass(s). This is useful for simple applications or demos. I would not recommend using this adapter for a real solution. |
DefaultWrapperAdapter | This ValueListAdapter returns a ValueList of wrapped records from ResultSet. Using wrappers is recommended in cases, when your hibernate hql is too complex, and you cannot controll all composite joins for example. |
FileSystemAdapter | This ValueListAdapter returns a ValueList of FileInfo(s). This is useful for browsing a file system on the web. |
Hibernate20Adapter | This ValueListAdapter returns a ValueList of pojos delegating the data access to Hibernate. As well, Hibernate20Adapter can focus (look up a row of specified property using specified value). See valuelist.war examples. |
Almoust all adpaters (except FileSystemAdapter
) are
able to use so called validators of rows. See Hibernate20Adapter
where you can find simple usage.
Main aim of this section is to give a solution for so called "refresh button problem".
Ussually, when you work with an web application, sometimes you need redirect to 'view' and not to lose all information about sorting, focusing, paging on so on. Considere example: You like to delete a row of the table. If you do it with just a forwarding parameters via request, it is possible that after deleting row you will be forwarded back to the view jsp. But when an user press refresh button, it will be called delete method again due to fact, that all request parameters are still the same!
Basicly therefore was writen this service helper class that allow you to back up your actual state of viewed table to the session and retrieve it back when is it necesserally.
The ValueListHandlerHelper is a class, that require before any use to set any ValueListHandler implemntation. The easiest way to use the ValueListHandlerHelper in a web environment is to let Spring bean factory create it for you:
<bean id="valueListHelper" singleton="true" class="net.mlw.vlh.web.mvc.ValueListHandlerHelper"> <property name="valueListHandler"> <ref bean="valueListHandler"/> </property> </bean> <bean id="valueListHandler" singleton="true" class="net.mlw.vlh.DefaultValueListHandlerImpl"> <property name="config.adapters"> <map> ... and so on. </map> </property> </bean>
The next is to set up your controller to know that you would like to use a service's helper class instance.
class MyController .... { public void setValueListHelper(ValueListHandlerHelper valueListHandlerHelper) { this.valueListHelper = valueListHandlerHelper; } .. }
Now we will focus more on detail, how to backup information about the table. Considere an example: We have one table in jsp with the id="MyTable". A strut's controller for this table could look like this:
public ActionForward doDelete(ActionMapping mappings, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { ValueListInfo info = valueListHelper.getValueListInfo(request, "MyTable"); //modification of paging page after delete first row that is also last row in last page. info.setPagingPage(valueListHelper.getLastPageAfterDelete(info)); valueListHelper.backupInfoFor(request, info, "MyTable"); //redirect true return mappings.findForward("view"); }
If the request parameters
doesn't containt any information for the table with id 'MyTable',
it try to get an information from previously saved backup of the
state (ValueListInfo
) of the table from http's
session. Therefore is necessity after every action to backup
valuelist's info. As a unique key is used table's id 'MyTable'.
For more information how to use this class see
To see a good example of how the ValueList is used, take a look at the spring-config file for the Fantasy Sports Components. This config file has a query named playerRank. This query has left joins, inline views and a large amount of group bys. This solution is using the DefaultDynaBeanAdapter right out of the box.