Below is a class of mine that is a bit primitive but does the job. There's
probably plenty wrong (like using integer constants instead of type safe enum)
with it as I'm a bit of an amateur. With queries I reckon the usual rules of
MVC go out the window & you design for
1 - performance
2 - minimum lines of code.
3 - simpicity - You can put junior programmers to work on this sort of code.
..DL = Data List object. It has no GUI code but needs a method for each
combination of parameters. It has no SQL but uses the data objects created by
classes that have the SQL.
=========
I think that once a system has many queries the database design must be stable
so it's not so bad if the GUI is bound to the DB design. (OO heresy!)
If u have a web only interface an alternative is to build the SQL in your
ActionForm & have a generalised system that runs the SQL & returns a
List/Collection of type you specify. Some such thing must exist. You just put
the collection in the request for the JSP to display.
thanks,
Keith.
package com.biff.biffapp1.db;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Collections;
import java.io.Serializable;
import org.apache.log4j.Logger;
import com.biff.utils.Biff1AppException;
import com.biff.utils.ZUtils;
/**
* Data List Object
*
**/
public class UserDL extends Object implements Serializable {
private static final
Logger logger = Logger.getLogger(UserDL.class.getName());
public static final int SELECT_ALL = 60;
public static final int SELECT_INACTIVE = 61;
public static final int SELECT_ACTIVE = 62;
public static final int SORT_USER_NAME = 50;
public static final int SORT_ACTIVE_USER_NAME = 51;
public static final int SORT_USER_ID = 52;
public static final int SORT_ACTIVE_USER_ID = 53;
public static final int SORT_SIGNON_COUNT = 54;
public static final int SORT_LAST_SIGNON = 55;
// holds data for table.
private ArrayList userList = new ArrayList(50); // what init size?
private int selectionType = 0;
private int sortType = 0;
/*
* Constructor - build date from default query.
*/
public UserDL() {
this.selectionType = UserDL.SELECT_ALL;
this.sortType = UserDL.SORT_USER_NAME;
constructorCode();
}
/*
* Constructor -
*/
public UserDL(int selectionType, int sortType) {
this.selectionType = selectionType;
this.sortType = sortType;
constructorCode();
}
/*
*/
public void constructorCode(){
//logger.debug("constructorCode: start. selectionType="+ selectionType
// +" sortType="+
sortType);
Iterator iii = UserDB.getInstance().getArrayList().iterator();
while (iii.hasNext()) {
UserDO ddd = (UserDO)iii.next();
boolean includeIt = false;
switch (selectionType) {
case UserDL.SELECT_ALL :
includeIt = true;
break;
case UserDL.SELECT_INACTIVE :
if (ddd.getRowStatus().equals("D")) includeIt = true;
break;
case UserDL.SELECT_ACTIVE :
if (ddd.getRowStatus().equals("A")) includeIt = true;
break;
default :
throw new Biff1AppException(
"constructorCode: unknown selectionType: "
+ selectionType);
}
if (includeIt) userList.add(ddd);
}
if (userList.size() == 0) {
logger.warn("constructorCode: no data loaded");
}
Collections.sort(userList, new UserDLComparator(sortType));
//logger.debug("constructorCode: data has been loaded from
DB");
}
/*
*/
public ArrayList getData() {
return userList;
}
/*
* Make an iterator available for the data.
*/
public Iterator getIterator() {
return userList.iterator();
}
class UserDLComparator implements Comparator {
private int sortType;
private String key1;
private String key2;
private UserDO k1;
private UserDO k2;
UserDLComparator(int sortType) {
this.sortType = sortType;
}
/**
* interface Comparator
*/
public int compare(Object o1, Object o2) {
k1 = (UserDO)o1;
k2 = (UserDO)o2;
switch (sortType) {
case UserDL.SORT_USER_NAME :
key1 = k1.getSurname() + k1.getFirstName();
key2 = k2.getSurname() + k2.getFirstName();
break;
case UserDL.SORT_ACTIVE_USER_NAME :
key1 = k1.getRowStatus() + k1.getSurname() +
k1.getFirstName();
key2 = k2.getRowStatus() + k2.getSurname() +
k2.getFirstName();
break;
case UserDL.SORT_USER_ID :
key1 = k1.getUserID();
key2 = k2.getUserID();
break;
case UserDL.SORT_ACTIVE_USER_ID :
key1 = k1.getRowStatus() + k1.getUserID();
key2 = k2.getRowStatus() + k2.getUserID();
break;
case UserDL.SORT_SIGNON_COUNT :
key1 = ZUtils.intToString(k1.getSignonCount(),
8);
key2 = ZUtils.intToString(k2.getSignonCount(),
8);
break;
case UserDL.SORT_LAST_SIGNON :
key1 = k1.getLastSignonDatetime();
key2 = k2.getLastSignonDatetime();
break;
default :
logger.warn("warning unknown sortType=" +
sortType);
//key1 = key2 = "";
key1 = k1.getUserID();
key2 = k2.getUserID();
}
return key1.compareTo(key2);
}
/**
* interface Comparator. true only if the specified object is also a
* comparator and it imposes the same ordering as this comparator.
*/
public boolean equals(Object o1) {
//logger.debug("equals called!");
return (o1 instanceof UserDLComparator
&& this.compare(this, o1) == 0);
}
} //end class UserDLComparator
} // end
--- "Siggelkow, Bill" <[EMAIL PROTECTED]> wrote:
> Heather,
> In my opinion, the approach you are taking is not separating out your logic
> appropriately. In fact, it sounds like your are binding your persistence
> layer (database columns) all the way up to the presentation layer (your
> action forms). A better approach is to separate the model (data) from the
> view (presentation). Let your action classes (controller) marshall data from
> the database to the action forms. The BeanUtils classes can ease this
> activity.
>
> Typically what I have are the following:
>
> ActionForms (or DynaActionForms) that represent the form fields
> Actions that get the forms and then create business objects from these forms.
> At this point I may pass that business object to a Service layer (like a
> Manager object)
> The manager object interacts with a DAO (data access object) that performs
> the actual JDBC stuff.
>
> It really is a question of appropriate assigment of responsibilities.
>
> I suggest you read throught the Struts User Guide as well as check out some
> of the new Struts books that are available.
>
> -----Original Message-----
> From: Heather Buch [mailto:[EMAIL PROTECTED]]
> Sent: Friday, January 10, 2003 4:24 AM
> To: [EMAIL PROTECTED]
> Subject: turning form parameters into queries
>
>
> Hi all,
>
> Finding a good method to create SQL queries out of html form parameters
> is something I've struggled with for some time now. Is there a good or
> recommended way of doing this? For that matter, is there a "best
> practice" for making SQL queries in struts?
>
> I use a mysql database backend for my struts application. In the
> browser, the user selects some choices from an html form. My Action
> classes collect the information that the user has chosen out of my form
> bean, pretty standard.
>
> The Action class then sends that info back to a corresponding
> BusinessLogic class (BusinessLogic classes reside in a package that does
> not know about struts or servlets, but correspond roughly one
> BusinessLogic class to one Action class).
>
> The BusinessLogic class needs to take those form parameters and create a
> list of "QueryParam" objects, which are then sent to a "SQLMaker" class
> where they are used to build constraints (the stuff after "WHERE" in the
> query) for SQL queries.
>
> In my BusinessLogic classes, I have this method which gets called by my
> Action class:
>
> public void setQueryParams(String querytype, String fieldname, List
> parameters)
>
>
> The "QueryParam" class is basically just a bean that I iterate through
> when I build the constraint part of the query. It contains these fields:
>
> protected List _values = null;
> protected int _datatype = -1;
> protected String _colname = null;
> protected String _tablename = null;
> protected String _singlevalue = null;
>
> xThere are a couple of problems with this.
>
> First, every BusinessLogic class (and there are many because they
> correspond to Action classes) has the information about the form fields,
> and the database struture info that maps to it, hard-coded. Instead of
> being able to create this method once and for all in a superclass of my
> BusinessLogic classes, I have to rewrite this method for every
> BusinessLogic class, because the subclassed BusinessLogic class knows
> about the Action class that calls its "setQueryParams", and therefore
> what html form fields that Action class will use and how they will be
> mapped. That also means that every time I change a form field name, I
> have to make the change in my BusinessLogic class as well.
>
> Which classes should know what? It seems that either my form bean needs
> to know enough to be able to name form fields after database columns, or
> my business logic classes need to know the name of the html form fields,
> and how they map to database column information, to make the constraints.
>
> Would it make sense to cache a copy of the database struture in the
> struts application, and add all the form field mappings to that? Or is
> there a rule for writing html form fields to go into a database (like,
> "html form fields must be named after database columns").
>
> Somewhere the mapping from form field to database column name, and then
> the addition of other information needed to make the QueryParam (and
> therefore the query), needs to be done, (and it would be nice if the
> method could only appear once in the application), but I'm not sure I
> know where.
>
>
> Thanks,
>
> Heather M. Buch
>
>
>
>
> --
> To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
>
> --
> To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
>
=====
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Search the archive:-
http://www.mail-archive.com/struts-user%40jakarta.apache.org/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Keith Bacon - Looking for struts work - South-East UK.
phone UK 07960 011275
__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>