Struts enforces MVC model. It suggests that every data access logic should be done in action objects or servlet that react as a "controller". So, building html tables from resultSet is bad practise since it brings data access logic to jsp pages, instead, we should do the data access logic in controller, do the OR mapping, and create Collection of beans for jsp pages to show. Coming from PHP&ASP background, this idea is quite interesting to me, but while implementing it, I found that the time spent on manual OR mapping is enourmous. How do you people overcome this? Or should I just get accutomed to it? Another thought:How about encapsulating data access logic in taglib? Any your thought is appreciated, and thanks in advance.
Well, you're certainly on the right track! Generally, I don't implement the data access logic in a taglib. (Well, I should admit: I sometimes roll a simple tag to do quick and dirty straight-to-the-database queries). When a request comes in, it invokes an Action. This Action should not contain any serious logic; all it does is make one or more calls to Java classes that contain the actual business logic (often JavaBeans, sometimes not). These classes act by operating on the object model (OM) that lies behind them. If the action is a query and the result is a simple list, it might be returned in a Collection and bound by the Action as a request attribute. In the JSP, you can use the logic:iterate tag to iterate through the result and generate the response. In more complicated cases, you probably want to access OM state from the JSP; in the simplest cases you might get away with accessing the business/OM layer directly (using tags like bean:write and logic:iterate) but if things get complicated use tag or JavaBean adapters between JSP and OM to keep the JSP simple and presentation-related logic out of the business/OM layer. One of the most time-consuming tasks is coding OM persistence, usually into a relational database (BTW: try not to mix it in with either the OM model or the business logic). Fortunately there are some powerful tools to help you; in the open source arena I'm pretty impressed with Castor, a JDO-like transparent persistence framework. Sun's Forte for Java also comes with a Transparent Persistence engine (previously JavaBlend), and there are many more (Toplink, CocoBase, etc). Even so, it will take more time to develop than you're used to with either PHP or ASP. But you will find that a layered design with well-delineated responsibilities is easier to understand, modify and maintain in the long run. - Peter
Thanks for your great response;-) You mentioned about Castor, the OSS JDO-like implementation. In fact, I have been investigating this tool for 2 weeks, great features, but I found certain uncertainty. If I use JDO, or some OR-mapping persistence tool in action classes and put them in Request scope attribute, then a serious problem would arise:when will the connection be closed? In my knowledge(which may be incorrect), both ResultSet & JDO objects won`t be accessible after the connection is closed. And since closing the connection is vital in a enviroment using connection pooling, we cannot ignore this problem. My solution is taglib. Start connection in doStartTag() and close it in doEndTag. Taglib don`t do the print() job, just organize beans(JDO objects) into Collection and then use <logic:iterate> to display them. But inevitably, again, I have my data access logic done in JSP page. Any idea?
Generally there are no live ResultSets (or Castor QueryResults) by the time I come to render my JSP. Instead, the results will either be request-bound Collections, or objects living in the object model. The queries are usually initiated by the controller: the Action calls the business layer, which in turn calls data access objects (DAO) to perform the queries. Castor tends to make these DAOs a good deal simpler! The sole exception is the quick-and-dirty database query tag I mentioned (in this case, a < query > tag that takes an OQL query, nested inside this are zero or more < bind > tags to bind query parameters and a normal Struts < iterate > tag to iterate over the results). With OQL you're querying the object model which makes this approach quite a bit cleaner than it is with raw SQL queries, still I don't normally use it except when trying something out or quickly hacking something together. Closing your connection in doEndTag is not enough. If an exception is thrown inside the tag body then the end tag will never execute. To avoid connection leaks you must add a safety net in Tag.release(); according to the JSP spec this method is guaranteed to be called. No idea how faithfully application servers implement this though. I guess this illustrates how hard it is to handle live connections well inside a JSP. Avoid it if you can, but if you must do it, by all means use tags. - Peter [This message has been edited by Peter den Haan (edited November 10, 2001).]
I'm glad that you're starting to discover the big wide world of layered architectures! I agree with Peter that there's a lot there to learn, but that you'll come to appreciate it in the long run. A good resource to start with is Martin Fowler's ISA (Information Systems Architecture) patterns on the web. He discusses the various architectures for building data access layers and provides source code. You can find them at http://www.martinfowler.com/isa Kyle ------------------ Kyle Brown, Author of Enterprise Java (tm) Programming with IBM Websphere See my homepage at http://members.aol.com/kgb1001001 for other WebSphere information.
You're not the only one who sees this as error-prone low-productivity grunt work. I have a tool (http://www.mousetech.com/EJBWizard.html) that I created to handle similar issues in constructing Enterprise JavaBeans. It has two very useful features: 1) It can query a database to get the descriptive information of existing tables, so you don't have to type them in manually 2) It is entirely template-driven, so all you need to do to generate files is create a template, define it to the master templates.xml file, and ensure that the generator has been loaded with all the dictionary definitions that will be substituted. The current release generates not only the EJB source and build files, but model JSPs for individual and table editing/viewing. Over the last several months, I've been slowly peeling apart the controller code from the view, and the next step will probably involve Struts. If you're interested in experimenting, download a copy. I can help you set up any custom templates you develop. Even if you don't use the generated EJB, you may still find it more productive than trying to do it all by hand.
Bjoke: A "Bully Joke". A Statement or action made with malicious intent - unless challenged. At which point it magically transforms into "I was just funnin'" or "What's the matter, can't take a joke?"