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]>

Reply via email to