Data driven struts application
95% of my struts web apps follow this flow: 1. User selection in a JSP 2. Action class performs a SQL query 3. Return ActionForward to a new JSP that renders the query ResultSet What is the best practice to show SQL query results (ResultSet) to the user? (I mean how communication between view and controller should be when I do extensive use of ResulSets) Actually, we are including the ResultSet in the request :(, and processing it in the JSP (using a scriptlet). But I dont like this aproach very much, so I wonder if it would be better to: + solution 1. Use a RowSetDynaClass instead of the ResultSet. + solution 2. Use a JavaBean with getters and setters (maybe as database column names) and include a JavaBean collection in the request as a Value Object (?) + solution 3. I don't know... :( Thank you very much, Guido. PD. Is it better to use a collection of JavaBeans or use just one JavaBean whose properties return a collection?? - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
Using a ResultSet directly is generally seen as bad practice. At a minimum you should probably use the ResultSetDynaClass then next in line would be a RowSetDynaClass, then JavaBeans. As for the JavaBean properties question, it would be easier to return a Collection of JavaBeans where each bean represented each row in the resultset. ~Robert Guido wrote: 95% of my struts web apps follow this flow: 1. User selection in a JSP 2. Action class performs a SQL query 3. Return ActionForward to a new JSP that renders the query ResultSet What is the best practice to show SQL query results (ResultSet) to the user? (I mean how communication between view and controller should be when I do extensive use of ResulSets) Actually, we are including the ResultSet in the request :(, and processing it in the JSP (using a scriptlet). But I dont like this aproach very much, so I wonder if it would be better to: + solution 1. Use a RowSetDynaClass instead of the ResultSet. + solution 2. Use a JavaBean with getters and setters (maybe as database column names) and include a JavaBean collection in the request as a Value Object (?) + solution 3. I don't know... :( Thank you very much, Guido. PD. Is it better to use a collection of JavaBeans or use just one JavaBean whose properties return a collection?? - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
Both solution 1 and 2 are far better than using a ResultSet in a jsp. I usually use a Collection of JavaBeans. David From: Guido [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Subject: Data driven struts application Date: Fri, 14 Mar 2003 16:24:08 +0100 95% of my struts web apps follow this flow: 1. User selection in a JSP 2. Action class performs a SQL query 3. Return ActionForward to a new JSP that renders the query ResultSet What is the best practice to show SQL query results (ResultSet) to the user? (I mean how communication between view and controller should be when I do extensive use of ResulSets) Actually, we are including the ResultSet in the request :(, and processing it in the JSP (using a scriptlet). But I dont like this aproach very much, so I wonder if it would be better to: + solution 1. Use a RowSetDynaClass instead of the ResultSet. + solution 2. Use a JavaBean with getters and setters (maybe as database column names) and include a JavaBean collection in the request as a Value Object (?) + solution 3. I don't know... :( Thank you very much, Guido. PD. Is it better to use a collection of JavaBeans or use just one JavaBean whose properties return a collection?? - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] _ The new MSN 8: smart spam protection and 2 months FREE* http://join.msn.com/?page=features/junkmail - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
I spent some time thinking over this very topic. I finally went with the following approach: * I used JDBC (NO Entity Beans got bitten bably there in the past) to query the data base and then created value objects which i then inserted into Form beans. * For read only data access i used an optimised SQL statement (plse see below) which returns only enough data to render the current screen to the client. As the user pages through the results i use the paging start index to control the SQL select statement so that i only ever fetch enough data for the next screen. So if the user pages from page 1 to 20, and i display 10 records per page i don't need to process from record 1 to 200 to get the data i need, nor do i need to keep my connection open. I always get back my data in blocks of 10 records. select [$ColumnNames], counter from ( select [$ColumnNames], rownum as counter from (select [$ColumnNames] from my_table where [$WhereClause])) where counter between [Start Index] and [End Index] The SQL could be optimised a little more Im not an SQL guru!!! I could also implement a caching mechanism to increase performance a little more. Any ways thats my two cents From: Robert McIntosh [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Subject: Re: Data driven struts application Date: Fri, 14 Mar 2003 09:38:50 -0600 Using a ResultSet directly is generally seen as bad practice. At a minimum you should probably use the ResultSetDynaClass then next in line would be a RowSetDynaClass, then JavaBeans. As for the JavaBean properties question, it would be easier to return a Collection of JavaBeans where each bean represented each row in the resultset. ~Robert Guido wrote: 95% of my struts web apps follow this flow: 1. User selection in a JSP 2. Action class performs a SQL query 3. Return ActionForward to a new JSP that renders the query ResultSet What is the best practice to show SQL query results (ResultSet) to the user? (I mean how communication between view and controller should be when I do extensive use of ResulSets) Actually, we are including the ResultSet in the request :(, and processing it in the JSP (using a scriptlet). But I dont like this aproach very much, so I wonder if it would be better to: + solution 1. Use a RowSetDynaClass instead of the ResultSet. + solution 2. Use a JavaBean with getters and setters (maybe as database column names) and include a JavaBean collection in the request as a Value Object (?) + solution 3. I don't know... :( Thank you very much, Guido. PD. Is it better to use a collection of JavaBeans or use just one JavaBean whose properties return a collection?? - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] _ The new MSN 8: smart spam protection and 2 months FREE* http://join.msn.com/?page=features/junkmail - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
Yep, I agree with David. Your code will invariably be more usable and be more presentation layer friendly if you always return a Collection of some type. The Collection would contain beans of the object type you're working with. Further if you're using for example an ArrayList to populate a List, and later you decide you want to change it to something else for say performance reasons or what ever, you don't go busting the whole presentation layer because of it, since the presentation layer is working with a Collection and knows about nothing else. It is *sometimes* better to be as generic as possible with the underlying layers of your code, than hooking your presentation code in so tight that maintenance of the app is greatly affected. On Friday, March 14, 2003, at 10:57 AM, David Graham wrote: Both solution 1 and 2 are far better than using a ResultSet in a jsp. I usually use a Collection of JavaBeans. David From: Guido [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Subject: Data driven struts application Date: Fri, 14 Mar 2003 16:24:08 +0100 95% of my struts web apps follow this flow: 1. User selection in a JSP 2. Action class performs a SQL query 3. Return ActionForward to a new JSP that renders the query ResultSet What is the best practice to show SQL query results (ResultSet) to the user? (I mean how communication between view and controller should be when I do extensive use of ResulSets) Actually, we are including the ResultSet in the request :(, and processing it in the JSP (using a scriptlet). But I dont like this aproach very much, so I wonder if it would be better to: + solution 1. Use a RowSetDynaClass instead of the ResultSet. + solution 2. Use a JavaBean with getters and setters (maybe as database column names) and include a JavaBean collection in the request as a Value Object (?) + solution 3. I don't know... :( Thank you very much, Guido. PD. Is it better to use a collection of JavaBeans or use just one JavaBean whose properties return a collection?? - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] _ The new MSN 8: smart spam protection and 2 months FREE* http://join.msn.com/?page=features/junkmail - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
On Fri, 14 Mar 2003, Robert McIntosh wrote: Date: Fri, 14 Mar 2003 09:38:50 -0600 From: Robert McIntosh [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Subject: Re: Data driven struts application Using a ResultSet directly is generally seen as bad practice. At a minimum you should probably use the ResultSetDynaClass then next in line would be a RowSetDynaClass, then JavaBeans. As for the JavaBean properties question, it would be easier to return a Collection of JavaBeans where each bean represented each row in the resultset. Note that using ResultSetDynaClass doesn't get you out of leaving the underlying ResultSet open (and the connection allocated from your connection pool), so it is still not the best choice for making data available to the view tier. It's primary value is exposing ResultSet data as DynaBeans for processing inside the business tier. For maximum efficiency, no data copying is done -- it essentially synthesizes a DynaBean for the current row (have a look at the sources if you want to see the world's strangest Iterator implementation :-). RowSetDynaClass, on the other hand, is quite useful for making data available to the view tier. It makes a copy of the data, so the underlying result set can be immediately closed, and the connection returned to the connection pool. And, because it again exposes DynaBeans, all the standard Struts tags can deal with it just like a collection of standard JavaBeans. The only downside is that the copying can be computationaly and/or memory-wise expensive, so be sure you don't try things like performing a million row query and then trying to make a RowSetDynaClass out of it. ~Robert Craig McClanahan - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
I agree, but I am in doubt: 1. How to transform a ResultSet into a JavaBean (I think bean accesors don't have to be named as database columns...) without reinvent the wheel? 2. If I don't know how many columns the query returns (i.e. if the query is 'select * from ORACLE_VIEW') I supose I can use a DynaBean. Are there any other technique? Thank you again, Guido. Robert S. Sfeir wrote: Yep, I agree with David. Your code will invariably be more usable and be more presentation layer friendly if you always return a Collection of some type. The Collection would contain beans of the object type you're working with. Further if you're using for example an ArrayList to populate a List, and later you decide you want to change it to something else for say performance reasons or what ever, you don't go busting the whole presentation layer because of it, since the presentation layer is working with a Collection and knows about nothing else. It is *sometimes* better to be as generic as possible with the underlying layers of your code, than hooking your presentation code in so tight that maintenance of the app is greatly affected. On Friday, March 14, 2003, at 10:57 AM, David Graham wrote: Both solution 1 and 2 are far better than using a ResultSet in a jsp. I usually use a Collection of JavaBeans. David From: Guido [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Subject: Data driven struts application Date: Fri, 14 Mar 2003 16:24:08 +0100 95% of my struts web apps follow this flow: 1. User selection in a JSP 2. Action class performs a SQL query 3. Return ActionForward to a new JSP that renders the query ResultSet What is the best practice to show SQL query results (ResultSet) to the user? (I mean how communication between view and controller should be when I do extensive use of ResulSets) Actually, we are including the ResultSet in the request :(, and processing it in the JSP (using a scriptlet). But I dont like this aproach very much, so I wonder if it would be better to: + solution 1. Use a RowSetDynaClass instead of the ResultSet. + solution 2. Use a JavaBean with getters and setters (maybe as database column names) and include a JavaBean collection in the request as a Value Object (?) + solution 3. I don't know... :( Thank you very much, Guido. PD. Is it better to use a collection of JavaBeans or use just one JavaBean whose properties return a collection?? - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] _ The new MSN 8: smart spam protection and 2 months FREE* http://join.msn.com/?page=features/junkmail - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
On Fri, 14 Mar 2003, Pat Quinn wrote: Date: Fri, 14 Mar 2003 16:05:34 + From: Pat Quinn [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Re: Data driven struts application I spent some time thinking over this very topic. I finally went with the following approach: * I used JDBC (NO Entity Beans got bitten bably there in the past) to query the data base and then created value objects which i then inserted into Form beans. This is pretty much what RowSetDynaClass does for you, without the need to create classes for your value objects. * For read only data access i used an optimised SQL statement (plse see below) which returns only enough data to render the current screen to the client. This is almost always a really smart strategy -- not only should you limit which columns are retrieved to only those that meet the requirements, you should (more importantly) limit the number of rows that is retrieved, as Pat points out below. Two possible concerns are that you'll be tying the persistence tier and the view tier together, because (for example) the page author has to know about the column names in the database, and the business logic has to be tweaked every time the page author needs a new column added. To mitigate these problems, I suggest using two strategies: * Store the actual SQL query sources into properties files, so that it can be modified easily without touching the business logic classes. (This can also be a lifesaver if you have to support more than one database, where the SQL query syntax has to change slightly.) * Use the column aliasing capability of SQL (the as modifier) to convert the database column names into simple names that the page author can expect, and document (for him or her) only those names. For example, a query might say something like: select customer-account-number as account, external-display-name as name from customers where ...; and the page author will see properties named account and name, no matter what the database actually uses. As the user pages through the results i use the paging start index to control the SQL select statement so that i only ever fetch enough data for the next screen. So if the user pages from page 1 to 20, and i display 10 records per page i don't need to process from record 1 to 200 to get the data i need, nor do i need to keep my connection open. I always get back my data in blocks of 10 records. select [$ColumnNames], counter from ( select [$ColumnNames], rownum as counter from (select [$ColumnNames] from my_table where [$WhereClause])) where counter between [Start Index] and [End Index] The SQL could be optimised a little more Im not an SQL guru!!! I could also implement a caching mechanism to increase performance a little more. Any ways thats my two cents Craig McClanahan - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
I agree Craig, I'm actually storing my SQL in a properties file, and i use a singleton object to load cache it i didn't want to go into too much detail!!! Cheers for your other point with regards column names From: Craig R. McClanahan [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Subject: Re: Data driven struts application Date: Fri, 14 Mar 2003 08:24:58 -0800 (PST) On Fri, 14 Mar 2003, Pat Quinn wrote: Date: Fri, 14 Mar 2003 16:05:34 + From: Pat Quinn [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Re: Data driven struts application I spent some time thinking over this very topic. I finally went with the following approach: * I used JDBC (NO Entity Beans got bitten bably there in the past) to query the data base and then created value objects which i then inserted into Form beans. This is pretty much what RowSetDynaClass does for you, without the need to create classes for your value objects. * For read only data access i used an optimised SQL statement (plse see below) which returns only enough data to render the current screen to the client. This is almost always a really smart strategy -- not only should you limit which columns are retrieved to only those that meet the requirements, you should (more importantly) limit the number of rows that is retrieved, as Pat points out below. Two possible concerns are that you'll be tying the persistence tier and the view tier together, because (for example) the page author has to know about the column names in the database, and the business logic has to be tweaked every time the page author needs a new column added. To mitigate these problems, I suggest using two strategies: * Store the actual SQL query sources into properties files, so that it can be modified easily without touching the business logic classes. (This can also be a lifesaver if you have to support more than one database, where the SQL query syntax has to change slightly.) * Use the column aliasing capability of SQL (the as modifier) to convert the database column names into simple names that the page author can expect, and document (for him or her) only those names. For example, a query might say something like: select customer-account-number as account, external-display-name as name from customers where ...; and the page author will see properties named account and name, no matter what the database actually uses. As the user pages through the results i use the paging start index to control the SQL select statement so that i only ever fetch enough data for the next screen. So if the user pages from page 1 to 20, and i display 10 records per page i don't need to process from record 1 to 200 to get the data i need, nor do i need to keep my connection open. I always get back my data in blocks of 10 records. select [$ColumnNames], counter from ( select [$ColumnNames], rownum as counter from (select [$ColumnNames] from my_table where [$WhereClause])) where counter between [Start Index] and [End Index] The SQL could be optimised a little more Im not an SQL guru!!! I could also implement a caching mechanism to increase performance a little more. Any ways thats my two cents Craig McClanahan - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] _ Help STOP SPAM with the new MSN 8 and get 2 months FREE* http://join.msn.com/?page=features/junkmail - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
I apologize if this has already been beaten to death, but I am still struggling with the implications of dyna-stuff on traditional OOD in struts applications. See interspersed. Craig R. McClanahan wrote: This is pretty much what RowSetDynaClass does for you, without the need to create classes for your value objects. Yes, but then you no longer have encapsulation at the business object level. If you short-circuit the persistence = business objects = view path, then either the view or the persistence layer is going to have to absorb both data abstraction and business logic. Unless what you mean is to use the RowSetDynaClass to populate your BOs...? Or...maybe there is a class of applications where persistence really can effectively absorb both data abstraction and business logic? * For read only data access i used an optimised SQL statement (plse see below) which returns only enough data to render the current screen to the client. This is almost always a really smart strategy -- not only should you limit which columns are retrieved to only those that meet the requirements, you should (more importantly) limit the number of rows that is retrieved, as Pat points out below. Two possible concerns are that you'll be tying the persistence tier and the view tier together, because (for example) the page author has to know about the column names in the database, and the business logic has to be tweaked every time the page author needs a new column added. To mitigate these problems, I suggest using two strategies: * Store the actual SQL query sources into properties files, so that it can be modified easily without touching the business logic classes. (This can also be a lifesaver if you have to support more than one database, where the SQL query syntax has to change slightly.) * Use the column aliasing capability of SQL (the as modifier) to convert the database column names into simple names that the page author can expect, and document (for him or her) only those names. For example, a query might say something like: select customer-account-number as account, external-display-name as name from customers where ...; and the page author will see properties named account and name, no matter what the database actually uses. But isn't this effectively still binding the view tier to the persistence tier? How do you handle derived fields? Using SQL to encapsulate business logic can lead to a maintenance nightmare. First come views, then stored procedures, then more database dependency than you ever wanted I can see how simple CRUD apps can be assembled VERY quickly using dyna-stuff tied directly to a SQL data model, with the model really just being the data model (with techniques like the above used to loosen the coupling a bit); but this brings back some *BAD* memories for me -- instant 2-tier applications using advanced data binding technologies having to be rewritten entirely when they needed to scale (either in terms of load or complexity). Am I just once bitten, twice shy here? Am I missing the point? Craig McClanahan - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: Data driven struts application
An approach that I've used is to use the javax.servlet.jsp.jstl.sql ResultSupport and Result objects. I create a Result object from the ResultSet object in this line: lResult = ResultSupport.toResult(lResultSet); I then pass the Result to the jsp: aRequest.setAttribute(departments, lResult); And display it using the jstl taqs as follows: c:forEach var=department begin=0 items=${departments.rows} department namec:out value=${department.name}//name descriptionc:out value=${department.description}//description phonec:out value=${department.phone}//phone faxc:out value=${department.fax}//fax /department /c:forEach This allows me to close the Connection and keep the data alive (I think), so is this a good approach? Paul -Original Message- From: Craig R. McClanahan [mailto:[EMAIL PROTECTED] Sent: 14 March 2003 11:16 To: Struts Users Mailing List Subject: Re: Data driven struts application On Fri, 14 Mar 2003, Robert McIntosh wrote: Date: Fri, 14 Mar 2003 09:38:50 -0600 From: Robert McIntosh [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Subject: Re: Data driven struts application Using a ResultSet directly is generally seen as bad practice. At a minimum you should probably use the ResultSetDynaClass then next in line would be a RowSetDynaClass, then JavaBeans. As for the JavaBean properties question, it would be easier to return a Collection of JavaBeans where each bean represented each row in the resultset. Note that using ResultSetDynaClass doesn't get you out of leaving the underlying ResultSet open (and the connection allocated from your connection pool), so it is still not the best choice for making data available to the view tier. It's primary value is exposing ResultSet data as DynaBeans for processing inside the business tier. For maximum efficiency, no data copying is done -- it essentially synthesizes a DynaBean for the current row (have a look at the sources if you want to see the world's strangest Iterator implementation :-). RowSetDynaClass, on the other hand, is quite useful for making data available to the view tier. It makes a copy of the data, so the underlying result set can be immediately closed, and the connection returned to the connection pool. And, because it again exposes DynaBeans, all the standard Struts tags can deal with it just like a collection of standard JavaBeans. The only downside is that the copying can be computationaly and/or memory-wise expensive, so be sure you don't try things like performing a million row query and then trying to make a RowSetDynaClass out of it. ~Robert Craig McClanahan - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
I agree with those that say Dynabeans are not a good practice. It's hard to unit test, or reuse, for example in JSTL or Model 1. It has a CVS hot spot. etc. etc. Best stick with unit tested POJO (and a bean that has a DAO helper, as in my other posts). .V Phil Steitz wrote: I apologize if this has already been beaten to death, but I am still struggling with the implications of dyna-stuff on traditional OOD in struts applications. See interspersed. Craig R. McClanahan wrote: This is pretty much what RowSetDynaClass does for you, without the need to create classes for your value objects. Yes, but then you no longer have encapsulation at the business object level. If you short-circuit the persistence = business objects = view path, then either the view or the persistence layer is going to have to absorb both data abstraction and business logic. Unless what you mean is to use the RowSetDynaClass to populate your BOs...? Or...maybe there is a class of applications where persistence really can effectively absorb both data abstraction and business logic? * For read only data access i used an optimised SQL statement (plse see below) which returns only enough data to render the current screen to the client. This is almost always a really smart strategy -- not only should you limit which columns are retrieved to only those that meet the requirements, you should (more importantly) limit the number of rows that is retrieved, as Pat points out below. Two possible concerns are that you'll be tying the persistence tier and the view tier together, because (for example) the page author has to know about the column names in the database, and the business logic has to be tweaked every time the page author needs a new column added. To mitigate these problems, I suggest using two strategies: * Store the actual SQL query sources into properties files, so that it can be modified easily without touching the business logic classes. (This can also be a lifesaver if you have to support more than one database, where the SQL query syntax has to change slightly.) * Use the column aliasing capability of SQL (the as modifier) to convert the database column names into simple names that the page author can expect, and document (for him or her) only those names. For example, a query might say something like: select customer-account-number as account, external-display-name as name from customers where ...; and the page author will see properties named account and name, no matter what the database actually uses. But isn't this effectively still binding the view tier to the persistence tier? How do you handle derived fields? Using SQL to encapsulate business logic can lead to a maintenance nightmare. First come views, then stored procedures, then more database dependency than you ever wanted I can see how simple CRUD apps can be assembled VERY quickly using dyna-stuff tied directly to a SQL data model, with the model really just being the data model (with techniques like the above used to loosen the coupling a bit); but this brings back some *BAD* memories for me -- instant 2-tier applications using advanced data binding technologies having to be rewritten entirely when they needed to scale (either in terms of load or complexity). Am I just once bitten, twice shy here? Am I missing the point? Craig McClanahan - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
On Fri, 14 Mar 2003, Phil Steitz wrote: Date: Fri, 14 Mar 2003 10:17:59 -0700 From: Phil Steitz [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Subject: Re: Data driven struts application I apologize if this has already been beaten to death, but I am still struggling with the implications of dyna-stuff on traditional OOD in struts applications. See interspersed. Craig R. McClanahan wrote: This is pretty much what RowSetDynaClass does for you, without the need to create classes for your value objects. Yes, but then you no longer have encapsulation at the business object level. If you short-circuit the persistence = business objects = view path, then either the view or the persistence layer is going to have to absorb both data abstraction and business logic. This is certainly a valid concern at the point where you're talking about data that can be *updated* by a web application. However, it's reasonable to pay attention to the fact that well over 80% of the SQL statements executed by a typical webapp are SELECTs that are only grabbing data to be rendered in the UI. Forcing people to create BOs for all of that stuff seems like it doesn't add a ton of value add. Unless what you mean is to use the RowSetDynaClass to populate your BOs...? That's certainly feasible as well, although it probably adds an extra layer without much benefit -- the population code has to know about the persistence tier pretty intimately already. Or...maybe there is a class of applications where persistence really can effectively absorb both data abstraction and business logic? * For read only data access i used an optimised SQL statement (plse see below) which returns only enough data to render the current screen to the client. This is almost always a really smart strategy -- not only should you limit which columns are retrieved to only those that meet the requirements, you should (more importantly) limit the number of rows that is retrieved, as Pat points out below. Two possible concerns are that you'll be tying the persistence tier and the view tier together, because (for example) the page author has to know about the column names in the database, and the business logic has to be tweaked every time the page author needs a new column added. To mitigate these problems, I suggest using two strategies: * Store the actual SQL query sources into properties files, so that it can be modified easily without touching the business logic classes. (This can also be a lifesaver if you have to support more than one database, where the SQL query syntax has to change slightly.) * Use the column aliasing capability of SQL (the as modifier) to convert the database column names into simple names that the page author can expect, and document (for him or her) only those names. For example, a query might say something like: select customer-account-number as account, external-display-name as name from customers where ...; and the page author will see properties named account and name, no matter what the database actually uses. But isn't this effectively still binding the view tier to the persistence tier? How do you handle derived fields? Using SQL to encapsulate business logic can lead to a maintenance nightmare. First come views, then stored procedures, then more database dependency than you ever wanted Yes, it is tying the tiers together. Now, assume we did the right O-O design and created value objects in between. Isn't the design of those value objects (specifically, which properties you expose) just as tied to the persistence tier? And isn't the set of properties available to the view tier just as tied to the set of properties available through the value objects, whether it's exposed as a bean or a JDBC row? A very typical thing that happens when you're adding features to an existing app is that you need to make some additional dynamic data avalable. Using value objects, you have to modify the VO class *and* the SQL code that populates it. Using RowSetDynaClass, you get to bypass part of that work, and only update the SQL query. Note that I am *not* advocating doing the query itself in the view tier (i.e. the JSP page). What you want is that the page author sees a collection of beans representing the results of the query, passed as a request attribute. In fact, if you're using the Struts tags to iterate over the collection and extract properties from it, the page author cannot even *tell* whether it's really dynabeans or not (in other words, the back end developer can change the implementation choice without affecting the front end pages). That's the way it should be. (In fact, if you follow my previous suggestion and isolate your SQL queries into a properties file, you can often accomodate
RE: Data driven struts application
On Fri, 14 Mar 2003, Paul Pattison wrote: Date: Fri, 14 Mar 2003 12:28:04 -0500 From: Paul Pattison [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Subject: RE: Data driven struts application An approach that I've used is to use the javax.servlet.jsp.jstl.sql ResultSupport and Result objects. I create a Result object from the ResultSet object in this line: lResult = ResultSupport.toResult(lResultSet); I then pass the Result to the jsp: aRequest.setAttribute(departments, lResult); And display it using the jstl taqs as follows: c:forEach var=department begin=0 items=${departments.rows} department namec:out value=${department.name}//name descriptionc:out value=${department.description}//description phonec:out value=${department.phone}//phone faxc:out value=${department.fax}//fax /department /c:forEach This allows me to close the Connection and keep the data alive (I think), so is this a good approach? Yep ... it has the same benefit as RowSetDynaClass does (as long as you're running on a Servlet 2.3 / JSP 1.2 platform that JSTL required), plus it's easier to use JSTL tags (or EL expressions in JSP 2.0) to access the properties. Paul Craig - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
Thanks, Craig. I understand a lot better now, but I am still struggling a bit. What you seem to be saying is that for read-only access we can safely skip the value/business object encapsulation; but for updates, we should use real BOs. This asymmetry troubles me; though I see the appeal in terms of developer productivity. I still see the risk of becoming persistence-implementation dependent, however, even with externalized SQL and field name normalization using AS. I see how the Dynamic model easily accomodates adding new fields to views, etc; but what happens when you decide to re-engineer the data model or to bring in a new datasource altogether? Or when you need to add derived fields? Consider the following example. Suppose that I am developing an online banking site, enabling customers to do both inquiries and updates on their accounts. The account info is stored in an RDBMS and I use Dyna-stuff to hit the store directly (using a model-free BO) with SQL queries, quickly generating a flexible infrastructure for account data retrieval. For updates (only?) I develop a traditional middle tier, with BOs and VOs modelling the domain and encapsulating the business logic. All is well and good until my company acquires another bank that has a legacy back end. If my update BOs and VOs are cleanly defined, I will not have much of a problem engineering connectors to the new system so that the new accounts can look no different from the others; but I will be SOL for account retrieval (unless, once again, I am missing something). This example may seem contrived; but this kind of thing does happen. One more point on the adding fields topic. I understand and agree with the basic point that if you use VOs, you need to keep them in synch with the model and you also need to keep the view in synch with them and that takes time. It also forces some analysis to be done, adds compile-time type checking, enhances readability of code and makes it easier to keep track of what data elements are being used in what way by what functions (so that implications of changes to the underlying data can be understood and fully tested). Call me a geezer; but somehow I prefer UML to SQL for design documentation. If the only artifacts expressing the design of the read-only view are SQL properties files, how do you keep these consistent with the model expressed in the BOs/VOs for updates? I guess the best strategy depends on the expected lifetime and required extensibility of the application. Thanks again for the explanation. -Phil - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Data driven struts application
On Fri, 14 Mar 2003, Phil Steitz wrote: Date: Fri, 14 Mar 2003 14:17:38 -0700 From: Phil Steitz [EMAIL PROTECTED] Reply-To: Struts Users Mailing List [EMAIL PROTECTED] To: Struts Users Mailing List [EMAIL PROTECTED] Subject: Re: Data driven struts application Thanks, Craig. I understand a lot better now, but I am still struggling a bit. What you seem to be saying is that for read-only access we can safely skip the value/business object encapsulation; but for updates, we should use real BOs. This asymmetry troubles me; though I see the appeal in terms of developer productivity. I still see the risk of becoming persistence-implementation dependent, however, even with externalized SQL and field name normalization using AS. I see how the Dynamic model easily accomodates adding new fields to views, etc; but what happens when you decide to re-engineer the data model or to bring in a new datasource altogether? Or when you need to add derived fields? There's no question that you risk misbehaving ... but remember two things that are critically important about my suggestion: The page author has no clue that the ResultSetDynaClass instance you passed was delivered directly from the JDBC query ... to him/her, it just looks like a List of beans. The business tier is still responsible for *creating* that List of objects, and placing it in an appropriate request parameter. The business tier author can change that implementation to use real VOs, or pull the data from EJBs or an LDAP directory server instead, with zero impact on the page author or the code in the page. Therefore, I would contend that my solution is no more tied to the persistence tier than VO-based solutions are (i.e. you have to agree on the property names). Consider the following example. Suppose that I am developing an online banking site, enabling customers to do both inquiries and updates on their accounts. The account info is stored in an RDBMS and I use Dyna-stuff to hit the store directly (using a model-free BO) with SQL queries, quickly generating a flexible infrastructure for account data retrieval. For updates (only?) I develop a traditional middle tier, with BOs and VOs modelling the domain and encapsulating the business logic. All is well and good until my company acquires another bank that has a legacy back end. If my update BOs and VOs are cleanly defined, I will not have much of a problem engineering connectors to the new system so that the new accounts can look no different from the others; but I will be SOL for account retrieval (unless, once again, I am missing something). This example may seem contrived; but this kind of thing does happen. My bank has a similar application (shudder ... they even used Struts to build it ... :-). The app provides a combination of data I can modify (change my profile, transfer money back and forth, etc.) and a whole bunch of read-only data (all the current transactions, the account balances on all the other accounts, and so on). The quantity of modifiable data is a very small percentage of the total amount of dynamic data that is present. And, any effort to build VOs that support modification of all that other data would be overkill (for this app, although you might be able to use it elsewhere). Even if you adopt my suggestion to use RowSetDynaClass, you should hide that actual logic behind a DAO of some sort, so that the Action calling it doesn't know where the data came from either. One more point on the adding fields topic. I understand and agree with the basic point that if you use VOs, you need to keep them in synch with the model and you also need to keep the view in synch with them and that takes time. It also forces some analysis to be done, adds compile-time type checking, enhances readability of code and makes it easier to keep track of what data elements are being used in what way by what functions (so that implications of changes to the underlying data can be understood and fully tested). Call me a geezer; but somehow I prefer UML to SQL for design documentation. If the only artifacts expressing the design of the read-only view are SQL properties files, how do you keep these consistent with the model expressed in the BOs/VOs for updates? If all of us were this disciplined, there would be a lot fewer software bugs in the world :-). Unfortunately, there's lots of people who do things quick and dirty -- I'm trying to help them without giving up totally on MVC principles :-). I guess the best strategy depends on the expected lifetime and required extensibility of the application. Yep. Thanks again for the explanation. -Phil Craig - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED