Re: Scratch RowSets
Oleg V Alexeev wrote: TH Though, if stay on this road, larger project swill have to start TH assembling their struts-config.xml from smaller files, as some TH people do with their Applicaton Resource now. ;-) My first idea was to split struts-config to 'standart' part and bean-factory part with my definirions. But it is needed to insert references to bean templates into action tags and it was main reason to build all in one. So long as we can still use a package format within struts-config, that shouldn't be a problem, since people could split them up for team development and concaternate them back again as part of the build. (By package format, I mean that we can repeat the struts-config node and all it's children as many times as needed, and still create a single ActionMapping database. I do that now and can also include David's form-validatation nodes in the same file, so that all package's programtic settings are all together.) -- Ted Husted, Husted dot Com, Fairport NY USA. -- Custom Software ~ Technical Services. -- Tel 716 737-3463. -- http://www.husted.com/about/struts/
Re[2]: Scratch RowSets
Hello Ted, Friday, June 08, 2001, 8:01:31 PM, you wrote: TH Oleg V Alexeev wrote: TH Though, if stay on this road, larger project swill have to start TH assembling their struts-config.xml from smaller files, as some TH people do with their Applicaton Resource now. ;-) My first idea was to split struts-config to 'standart' part and bean-factory part with my definirions. But it is needed to insert references to bean templates into action tags and it was main reason to build all in one. TH So long as we can still use a package format within struts-config, TH that shouldn't be a problem, since people could split them up for team TH development and concaternate them back again as part of the build. TH (By package format, I mean that we can repeat the struts-config node TH and all it's children as many times as needed, and still create a single TH ActionMapping database. I do that now and can also include David's TH form-validatation nodes in the same file, so that all package's TH programtic settings are all together.) So I can place several struts-config sections to the config file and all stuff will be parsed. Is it right? Are there any differences between file with one big section and file with several sections in case of whole content of such files is identical? -- Best regards, Olegmailto:[EMAIL PROTECTED]
Re: Scratch RowSets
Oleg V Alexeev wrote: So I can place several struts-config sections to the config file and all stuff will be parsed. Is it right? Yes. Are there any differences between file with one big section and file with several sections in case of whole content of such files is identical? A configuration file using the package format will be longer, but they are functionally equivalent. I'm also doing things like /account/Form.java /account/Insert.java rather than /accountForm.java /accountInsert.java so that the application is divided into coherent sub-packages. So it then becomes natural for me to arrange the configuration files that way. And as mentioned I can also interlace David's Validator nodes in there too. -T.
Re: Scratch RowSets
Just as an aside, Oleg: When I use RowSets as value object beans, the type is determined by the JDBC metadata. I've been putting some wrappers around that so the properties have ordinary getters and setters. I see that BeanFactory includes code to create tables, but what about reading tables to create beans? Oleg V Alexeev wrote: Hello Ted, Thank for good stub. Now I am trying to implement such approach in my extension to struts - BeanFactoryServlet.
Re[2]: Scratch RowSets
Hello Ted, Saturday, June 09, 2001, 12:55:04 AM, you wrote: TH Just as an aside, Oleg: TH When I use RowSets as value object beans, the type is determined by the TH JDBC metadata. I've been putting some wrappers around that so the TH properties have ordinary getters and setters. TH I see that BeanFactory includes code to create tables, but what about TH reading tables to create beans? Some confusion... There are SQL scripts to create sample database - are you talk about it? If yes then my answer is below. Each factory must implement create method to generate bean. There are abstract class org.apache.struts.factory.jdbc.JDBCFactory - base class for all jdbc related factories. Its create method uses first parameter from bean template as SQL query to create PreparedStatement and call method processResult( ResultSet...). This method is abstract and every derived class must implement it and JDBCArrayFactory, for example, walk throw result set and for each row create bean of target type and call populateFrom( ResultSet ) for every bean - this method do all work to fill new bean with values from current row. -- Best regards, Olegmailto:[EMAIL PROTECTED]
Re[2]: Scratch RowSets
Hello Ted, Good idea. Thank you. Saturday, June 09, 2001, 12:38:37 AM, you wrote: TH Oleg V Alexeev wrote: So I can place several struts-config sections to the config file and all stuff will be parsed. Is it right? TH Yes. TH Are there any differences between file with one big section and file with several sections in case of whole content of such files is identical? TH A configuration file using the package format will be longer, but they TH are functionally equivalent. -- Best regards, Olegmailto:[EMAIL PROTECTED]
Re: Scratch RowSets
Ted Husted wrote: Now, the next step is to create a RowSet from scratch to insert a new record to a new table. Given this, there doesn't seem to be any reason to have a seperate value object bean for a data set that is coming from or going to a persistent store. In case anyone is interested, all I did was select a record that wasn't there (primary key=0), and, bingo-bango, CachedRowSet created an empty but valid RowSet, ready to receive new rows. So, now instead of duplicating the data in my own set of properties, I'm using the CachedRowSet's storage locations directly through a thin wrapper with conventional mutators and accessors. This reduces the overhead of redundant storage, retains all the flexibility of a standard value object, is compatible with existing code bases, and can also leverage the type casting built into RowSets. [ DBMS ] - [ RowSet ] - [ ActionForm - RowSet ] - [ DBMS ] - [ RowSet ] - [ JSP or ActionForm ] And, of course, a RowSet can be treated just like a ResultSet in a JSP, but without the overhead of an open connection. A full treatment will follow, but here are some snippets. ResultValue.java // a RowSet Iterator wrapper subclassed as a // value object wrapper around a CachedRowSet (whew!) /** * Return the account */ public String getAccount() { try { return values.getString(account); } catch (SQLException sqle) { return null; } } // .. more property wrappers /** * Bulk mutator for data transfer from another object */ public void set( String bid, String lot, String amount, String account, String precedence, String bidType, String bidFrom, String pickup ) throws SQLException { values.updateString(bid_key,bid); values.updateString(lot,lot); values.updateString(amount,amount); values.updateString(account,account); values.updateString(bidder_key,precedence); values.updateString(bidType,bidType); values.updateString(bidFrom,bidFrom); values.updateString(pickup,pickup); } /** * Convenience constructor to set internal RowSet */ public ResultValue(RowSet values) { super(values); } Result.java // encapsulates instance of ResultValue with other // helper properties and serves as a data access object public int insert() throws SQLException { ResultValue resultValue = (ResultValue) getRows(); // MySQL can't insert via a RowSet, so use a Statement instead return Statements.bidInsert( resultValue.getLot(), resultValue.getAmount(), resultValue.getAccount(), resultValue.getPrecedence(), resultValue.getBidType(), resultValue.getBidFrom(), resultValue.getPickup() ); } Access.java (an Action) // selects appropriate classes and // methods for given request task // -- INSERT -- if (task.equals(insert)) { // Instantiate blank RowSet result = thisResult.select(); // key=0 resultValue = (ResultValue) thisResult.getRows(); // Create new row in empty set resultValue.moveToInsertRow(); // Transfer data resultValue.set( thisForm.getBid(), thisForm.getLot(), thisForm.getAmount(), thisForm.getAccount(), thisForm.getPrecedence(), thisForm.getBidType(), thisForm.getBidFrom(), thisForm.getPickup() ); // Execute insert command for this Result object result = thisResult.insert(); // Analyze outcome if (result==0) { message = error.database.error; } else { message = record.inserted; } } When retrieving multiple rows, the Result object (a proper JavaBean) can be inserted in the request, along with it's RowSet. I wrote a quick Iterator wrapper for RowSets so it could be used by the iterate tag. Front to back This gives you a pattern like: // Search.perform // Select command if (task.equals(lot)) command = Commands.BID_SEARCH_LOT; if (task.equals(account)) command = Commands.BID_SEARCH_ACCOUNT; // Ready result Result thisResult = new Result(key,task,command); // Retrieve data set thisResult.execute(); // Queue for view request.setAttribute(result,thisResult); // Result.execute public void execute() throws SQLException { rows = new
Re[2]: Scratch RowSets
Hello Ted, Thank for good stub. Now I am trying to implement such approach in my extension to struts - BeanFactoryServlet. Thursday, June 07, 2001, 3:38:30 PM, you wrote: TH Ted Husted wrote: TH skipped -- Best regards, Olegmailto:[EMAIL PROTECTED]
Re: Re[2]: Scratch RowSets
Hi all RowSet-interested, after Contacts.setCommand(SELECT name, telephone from Contacts); put Contacts.setTableName(Contacts); in the example jsp mentioned below. Otherwise you won't be able to save. Wolfgang At 08:42 6-7-2001 +0400: Hello Steve, Thank you, good paper. Thursday, June 07, 2001, 12:31:52 AM, you wrote: SS Take a look at sun's CachedRowSet now available in early release. SS http://www.javaworld.com/javaworld/jw-02-2001/jw-0202-cachedrow.html SS S- -- Best regards, Olegmailto:[EMAIL PROTECTED]
RE: Scratch RowSets
Hi Ted, I remember playing with cached rowsets sometime ago. It is probably useful to standardize your tags/code etc. based on the cached rowset rather than create your own data-structure - but I found that particularly the update/delete/insert into the rowset doesnt work properly for all but the simplest tables. I am currently implementing my own web-app(struts-based) that could handle more cases - one thing with this is that the user can specify the update/insert/delete in an xml file to configure my rowset - since I think it is not possible to anticipate in all cases what statements they would want to use. This also allows them to fire off multiple statements (for data-integrity reasons or something else) in a transaction for each of the actions update/insert/delete ... Pratima -Original Message- From: Ted Husted [mailto:[EMAIL PROTECTED]] Sent: Thursday, June 07, 2001 4:39 AM To: [EMAIL PROTECTED] Subject: Re: Scratch RowSets Ted Husted wrote: Now, the next step is to create a RowSet from scratch to insert a new record to a new table. Given this, there doesn't seem to be any reason to have a seperate value object bean for a data set that is coming from or going to a persistent store. In case anyone is interested, all I did was select a record that wasn't there (primary key=0), and, bingo-bango, CachedRowSet created an empty but valid RowSet, ready to receive new rows. So, now instead of duplicating the data in my own set of properties, I'm using the CachedRowSet's storage locations directly through a thin wrapper with conventional mutators and accessors. This reduces the overhead of redundant storage, retains all the flexibility of a standard value object, is compatible with existing code bases, and can also leverage the type casting built into RowSets. [ DBMS ] - [ RowSet ] - [ ActionForm - RowSet ] - [ DBMS ] - [ RowSet ] - [ JSP or ActionForm ] And, of course, a RowSet can be treated just like a ResultSet in a JSP, but without the overhead of an open connection. A full treatment will follow, but here are some snippets. ResultValue.java // a RowSet Iterator wrapper subclassed as a // value object wrapper around a CachedRowSet (whew!) /** * Return the account */ public String getAccount() { try { return values.getString(account); } catch (SQLException sqle) { return null; } } // .. more property wrappers /** * Bulk mutator for data transfer from another object */ public void set( String bid, String lot, String amount, String account, String precedence, String bidType, String bidFrom, String pickup ) throws SQLException { values.updateString(bid_key,bid); values.updateString(lot,lot); values.updateString(amount,amount); values.updateString(account,account); values.updateString(bidder_key,precedence); values.updateString(bidType,bidType); values.updateString(bidFrom,bidFrom); values.updateString(pickup,pickup); } /** * Convenience constructor to set internal RowSet */ public ResultValue(RowSet values) { super(values); } Result.java // encapsulates instance of ResultValue with other // helper properties and serves as a data access object public int insert() throws SQLException { ResultValue resultValue = (ResultValue) getRows(); // MySQL can't insert via a RowSet, so use a Statement instead return Statements.bidInsert( resultValue.getLot(), resultValue.getAmount(), resultValue.getAccount(), resultValue.getPrecedence(), resultValue.getBidType(), resultValue.getBidFrom(), resultValue.getPickup() ); } Access.java (an Action) // selects appropriate classes and // methods for given request task // -- INSERT -- if (task.equals(insert)) { // Instantiate blank RowSet result = thisResult.select(); // key=0 resultValue = (ResultValue) thisResult.getRows(); // Create new row in empty set resultValue.moveToInsertRow(); // Transfer data resultValue.set( thisForm.getBid(), thisForm.getLot(), thisForm.getAmount(), thisForm.getAccount(), thisForm.getPrecedence(), thisForm.getBidType(), thisForm.getBidFrom(), thisForm.getPickup() ); // Execute insert command for this Result object result = thisResult.insert(); // Analyze outcome if (result==0) { message = error.database.error
Re: Scratch RowSets
I've seen the same problem with updating via the CachedRowSet, but had been blaming MySQL's lack of transaction support (with the default tables at least). As a workaround, I'm using PreparedStatements for update/insert/delete but drawing the data from the RowSets to avoid defining another structure. Have had no problems whatsoever with selects at least. There are plans to increase support within Struts for RowSets in the 1.1. timeframe. (Who knows, maybe we can do a FastCachedRowSet that can cope with inserts!) In the meantime, I'm wrapping the Rowsets in standard beans and Iterators so I can use what we got now with what we got now. Hopefully I can just drop the wrappers later and use the raw Rowsets. Obviously, I'm extremely interested in your work, and would love to see it. Speaking of configuration issues, I've also played with the idea of loading SQL commands from a resource, so they could be changed and reloaded without restarting the application. It would also be easier to optimize command sets for different DBMS packages. Just wondering if anyone else has implemented a SQL command resource. Gogineni, Pratima wrote: Hi Ted, I remember playing with cached rowsets sometime ago. It is probably useful to standardize your tags/code etc. based on the cached rowset rather than create your own data-structure - but I found that particularly the update/delete/insert into the rowset doesnt work properly for all but the simplest tables. I am currently implementing my own web-app(struts-based) that could handle more cases - one thing with this is that the user can specify the update/insert/delete in an xml file to configure my rowset - since I think it is not possible to anticipate in all cases what statements they would want to use. This also allows them to fire off multiple statements (for data-integrity reasons or something else) in a transaction for each of the actions update/insert/delete ... Pratima
Re[2]: Scratch RowSets
Hello Ted, Thursday, June 07, 2001, 9:52:24 PM, you wrote: TH Speaking of configuration issues, I've also played with the idea of TH loading SQL commands from a resource, so they could be changed and TH reloaded without restarting the application. It would also be easier to TH optimize command sets for different DBMS packages. Just wondering if TH anyone else has implemented a SQL command resource. I already implement this as part of my bean generation framework. It contains JDBC bean factories (for single row, for all rows from result set, for window from the result set) and bean-templates (may be wrong term, of course) in which SQL queries can be defined. At bean creation process factory uses attributes, properties and parameters from request (all needed for this bean=template) and conserves result in session or request scope to display with jsp page. -- Best regards, Olegmailto:[EMAIL PROTECTED]
Scratch RowSets
The documentation for the Early Release of CachedRowSets mentions that Because both a CachedRowSet object and its metadata can be created from scratch, a component that acts as a factory for rowsets can use this capability to create a rowset containing data from non-SQL data sources. has anyone here tried this yet? The idea being I would like to transfer incoming properties from an ActionForm into a scratch RowSet, and use that as the value object. (Perhaps within a wrapper or a facade so business logic methods can be added.) There will be expanded support for RowSets in 1.1, and I wanted to get started on some support utilities / design patterns before looking at what other modifications will be needed. I put together a quick Iterate wrapper that works fine with a returned RowSet, but also need to create a new RowSet from scratch to close the loop. I guess the thing to try is to create a MetaDataRowSet object and pass that to a new RowSet (instead of making the SQL call), and then see if I can insert a row. -- Ted Husted, Husted dot Com, Fairport NY USA. -- Custom Software ~ Technical Services. -- Tel 716 737-3463. -- http://www.husted.com/about/struts/
Re: Scratch RowSets
Hello Ted, One question here... For example I want to use rowset in iterate tag - but database connection must be opened before iterate using and closed after it in this case. Is it right? If yes, then how it works in MVC framework? In Action - rows are retrieved from database and as attribute passed via session or request to the forwarded jsp page - I mainly use this approach to display data from database. I try to use rowset after closing of the connection to the database but exception was raised and I mark this way as error... What method are you use to work with rowsets in iterate tag? Open connection, make rowset, iterate, close rowset and connection? Or another way exists? Wednesday, June 06, 2001, 4:09:03 PM, you wrote: TH The documentation for the Early Release of CachedRowSets mentions that TH Because both a CachedRowSet object and its metadata can be created from TH scratch, a component TH that acts as a factory for rowsets can use this capability to create a TH rowset containing data from TH non-SQL data sources. TH has anyone here tried this yet? TH The idea being I would like to transfer incoming properties from an TH ActionForm into a scratch RowSet, and use that as the value object. TH (Perhaps within a wrapper or a facade so business logic methods can be TH added.) TH There will be expanded support for RowSets in 1.1, and I wanted to get TH started on some support utilities / design patterns before looking at TH what other modifications will be needed. TH I put together a quick Iterate wrapper that works fine with a returned TH RowSet, but also need to create a new RowSet from scratch to close the TH loop. I guess the thing to try is to create a MetaDataRowSet object and TH pass that to a new RowSet (instead of making the SQL call), and then see TH if I can insert a row. TH -- Ted Husted, Husted dot Com, Fairport NY USA. TH -- Custom Software ~ Technical Services. TH -- Tel 716 737-3463. TH -- http://www.husted.com/about/struts/ -- Best regards, Olegmailto:[EMAIL PROTECTED]
RE: Scratch RowSets
Title: RE: Scratch RowSets Take a look at sun's CachedRowSet now available in early release. http://www.javaworld.com/javaworld/jw-02-2001/jw-0202-cachedrow.html S- -Original Message- From: Oleg V Alexeev [mailto:[EMAIL PROTECTED]] Sent: Wednesday, June 06, 2001 3:55 PM To: Ted Husted Subject: Re: Scratch RowSets Hello Ted, One question here... For example I want to use rowset in iterate tag - but database connection must be opened before iterate using and closed after it in this case. Is it right? If yes, then how it works in MVC framework? In Action - rows are retrieved from database and as attribute passed via session or request to the forwarded jsp page - I mainly use this approach to display data from database. I try to use rowset after closing of the connection to the database but exception was raised and I mark this way as error... What method are you use to work with rowsets in iterate tag? Open connection, make rowset, iterate, close rowset and connection? Or another way exists? Wednesday, June 06, 2001, 4:09:03 PM, you wrote: TH The documentation for the Early Release of CachedRowSets mentions that TH Because both a CachedRowSet object and its metadata can be created from TH scratch, a component TH that acts as a factory for rowsets can use this capability to create a TH rowset containing data from TH non-SQL data sources. TH has anyone here tried this yet? TH The idea being I would like to transfer incoming properties from an TH ActionForm into a scratch RowSet, and use that as the value object. TH (Perhaps within a wrapper or a facade so business logic methods can be TH added.) TH There will be expanded support for RowSets in 1.1, and I wanted to get TH started on some support utilities / design patterns before looking at TH what other modifications will be needed. TH I put together a quick Iterate wrapper that works fine with a returned TH RowSet, but also need to create a new RowSet from scratch to close the TH loop. I guess the thing to try is to create a MetaDataRowSet object and TH pass that to a new RowSet (instead of making the SQL call), and then see TH if I can insert a row. TH -- Ted Husted, Husted dot Com, Fairport NY USA. TH -- Custom Software ~ Technical Services. TH -- Tel 716 737-3463. TH -- http://www.husted.com/about/struts/ -- Best regards, Oleg mailto:[EMAIL PROTECTED]
Re: Scratch RowSets
Good reference, Steve. So, given a CachedRowSet, it's easy to snag a data set and puruse it at your leisure, since the database connection is automatically closed by the RowSet. I've been using them for retrievals extensively, and they are an absolute pleasure to use. CachedRowSets are also mutable so you can update, deleted, and insert rows rows remotely, and (if your DBMS supports transactions) send the changes back to whence they came. Now, the next step is to create a RowSet from scratch to insert a new record to a new table. Given this, there doesn't seem to be any reason to have a seperate value object bean for a data set that is coming from or going to a persistent store. I'm going to take a whack at this tonite, so anyone who'd done this and has any pointers, please let me know! Steve Salkin wrote: Take a look at sun's CachedRowSet now available in early release. http://www.javaworld.com/javaworld/jw-02-2001/jw-0202-cachedrow.html S-
Re[2]: Scratch RowSets
Hello Steve, Thank you, good paper. Thursday, June 07, 2001, 12:31:52 AM, you wrote: SS Take a look at sun's CachedRowSet now available in early release. SS http://www.javaworld.com/javaworld/jw-02-2001/jw-0202-cachedrow.html SS S- -- Best regards, Olegmailto:[EMAIL PROTECTED]