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: Scratch RowSets
Oleg V Alexeev wrote: > So I can place several 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
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 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 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: Scratch RowSets
Defining the SQL commands in struts-config.xml is definately a leap-forward (I missed link to the sample WAR at first, and didn't see how you were implementing everything.) Though, if stay on this road, larger project swill have to start assembling their struts-config.xml from smaller files, as some people do with their Applicaton Resource now. ;-) The bean factory proposal seems excellent, and I'm going to try and take a closer at it this weekend. < http://www.sura.ru/~gonza/bean-factory/ > It's an exciting idea, and works well with the J2EE patterns I'm using now. Being able to define the various beans we need in XML could bring a real productivity boost to a lot of Struts developers, myself included. I'm also getting ready to do something about a code generator, which could work well with a factory like this. Incidentally, getting this to work is a real testament of how easy Java app configuration can be. Edited two lines in struts-config.xml and I'm up and running with some other DBMS. -- Ted Husted, Husted dot Com, Fairport NY USA. -- Custom Software ~ Technical Services. -- Tel 716 737-3463. -- http://www.husted.com/about/struts/ Oleg V Alexeev 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.
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: 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 Resul
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() thr
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: 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
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]