Another thought is that if you want your Mapping interface to have
transaction and batch functionality exposed... couldn't you simply
cause your Mapping interface to extend the SqlMapTransactionManager
and/or the SqlMapExecutor interface? Then you would have the
transaction methods needed to bind  to for transaciton management.
Heck you could even wind up exposing all the normal ibatis
functionality by implementing the ExtendedSqlMapClient interface.

The idea in the binding interfaces is to simply give you a type safe
way of interacting with your sqlmaps so that you can catch basic
problems up front either during compile time or initialization. It's a
good guardian against potential uncaught problems in your sqlmapping.
Let's face it... runtime errors suck :)

My recommendation is that the multi statement transactions should
always be handled outside of the Dao layer. The Service layer is a
more appropriate area for that. Also, wouldn't batching be more
appropriately handled on the service layer too? So, the exposing of
transactions is really a minor deal IMO. If someone needs the
functionality it will be there. All they need to do is expose those
calls via an interface.

Brandon




On 5/25/05, Brandon Goodin <[EMAIL PROTECTED]> wrote:
> In order to solve the namespace issue... why doesn't the namespace
> represent the interface name? Usually, when i have a sqlmap file it is
> one to one with the Dao class.
> 
> public interface CustomerMapping {
> ...
> }
> 
> <sqlMap namespace="CustomerMapping">
> ...
> </sqlMap>
> 
> On 5/25/05, Philippe Laflamme <[EMAIL PROTECTED]> wrote:
> >  >>>1- Does the class (interface) passed to the getMapper() method need to
> >  >>>extend a special iBatis interface (as with the Dao interface)?
> >  >
> >  >
> >  > Nope.
> >
> > Good.
> >
> > Completely off topic: any plans to eliminate the Dao interface
> > reuirement on iBatis DAOs?
> >
> >  >>>2- Can this handle extended interfaces? For example, interface B extends
> >  >>>interface A. Are both interfaces "mapped" like you described?
> >  >
> >  >
> >  > The way it's implemented right now, the answer is: yes. I was
> > thinking of
> >  > binding it more tightly, but this is definitely an option.
> >
> > I'm not sure if a "tight" binding would be beneficial. Considering
> > extended interfaces, it would seem non-intuitive to have the extended
> > interface partialy mapped to statements.
> >
> >  >>>3- What about namespaces? Can they or are they being used?
> >  >
> >  >
> >  > That's going to be the challenge with the current implementation, and
> > may
> >  > require the tight binding that I mentioned in the previous question.
> >
> > How would a tight binding look like? How would the namespace be derived?
> >
> >  >>>4- Can we still use startBatch/executeBatch?
> >  >
> >  > But I don't see any reason why we couldn't just allow you to define
> > methods
> >  > with the same signature to any interface that you can then call. Of
> > course,
> >  > you could always just use SqlMapClient for this, but if you truly
> > wanted to
> >  > isolate yourself, then you could define your own TransactionManager
> >  > interface that has all of these methods declared.
> >
> > Does the TransactionManager expose the startBatch and executeBatch
> > methods? I didn't think it did.
> >
> > I guess keeping the SQLMapClient around isn't such a bad thing... Unless
> > someone would like to get rid of their DAOs completely...
> >
> >  >>>5- Can you explain how insert() and insertXXXX() differs (besides the
> >  >>>executed statement's name)?
> >  >
> >  >
> >  > No, because I don't know what you mean. :-) The method name is only
> >  > significant when you're calling a stored procedure (because procs can do
> >  > anything...insert, update, delete, query or a combination).
> >
> > I have to admit, my question was not very clear! I realize now that it
> > was due to a misunderstanding of the javadoc you posted...
> >
> > If my interface looks like this:
> >
> > public List searchFoos(Foo value);
> >
> > public Foo insertFoo(Foo value);
> >
> > public Foo saveFoo(Foo value);
> >
> > public Foo createASpecialFoo(Foo value);
> >
> >
> > And my SqlMap looks like this:
> >
> > searchFoos=<select>
> > insertFoo=<insert>
> > saveFoo=<update>
> > createASpecialFoo=<procedure>
> >
> > iBatis will execute these methods:
> >
> > searchFoos=queryForList()
> > insertFoo=insert()
> > saveFoo=update()
> > createASpecialFoo=insert()
> >
> > In other words, iBatis looks at both the method's signature AND the
> > SqlMap's tag to determine what SqlMapClient method to call.
> >
> > Is that how the mapping occurs?
> >
> >
> > Clinton Begin wrote:
> > > Great questions!
> > >
> > >
> > >>>1- Does the class (interface) passed to the getMapper() method need to
> > >>>extend a special iBatis interface (as with the Dao interface)?
> > >
> > >
> > > Nope.
> > >
> > >
> > >>>2- Can this handle extended interfaces? For example, interface B extends
> > >>>interface A. Are both interfaces "mapped" like you described?
> > >
> > >
> > > The way it's implemented right now, the answer is: yes. I was thinking of
> > > binding it more tightly, but this is definitely an option.
> > >
> > >
> > >>>3- What about namespaces? Can they or are they being used?
> > >
> > >
> > > That's going to be the challenge with the current implementation, and may
> > > require the tight binding that I mentioned in the previous question.
> > >
> > >
> > >>>4- Can we still use startBatch/executeBatch?
> > >
> > >
> > > I haven't decided how best to deal with all of the non-execute methods 
> > > like
> > > startTransaction(), commitTransaction(), endTransaction(), startBatch(),
> > > endBatch() etc.
> > >
> > > But I don't see any reason why we couldn't just allow you to define 
> > > methods
> > > with the same signature to any interface that you can then call. Of 
> > > course,
> > > you could always just use SqlMapClient for this, but if you truly wanted 
> > > to
> > > isolate yourself, then you could define your own TransactionManager
> > > interface that has all of these methods declared.
> > >
> > >
> > >>>5- Can you explain how insert() and insertXXXX() differs (besides the
> > >>>executed statement's name)?
> > >
> > >
> > > No, because I don't know what you mean. :-) The method name is only
> > > significant when you're calling a stored procedure (because procs can do
> > > anything...insert, update, delete, query or a combination).
> > >
> > > Cheers,
> > > Clinton
> > >
> > > On 5/24/05, Philippe Laflamme <[EMAIL PROTECTED]> wrote:
> > >
> > >>Great idea. I think this will help make SQLMaps even more usable. I do
> > >>have a few questions:
> > >>
> > >>1- Does the class (interface) passed to the getMapper() method need to
> > >>extend a special iBatis interface (as with the Dao interface)?
> > >>
> > >>2- Can this handle extended interfaces? For example, interface B extends
> > >>interface A. Are both interfaces "mapped" like you described? This can
> > >>be very interesting for common persistence methods for example. One
> > >>would simply need to extend a CustomPersistenceMapper interface instead
> > >>of redefining every method.
> > >>
> > >>3- What about namespaces? Can they or are they being used?
> > >>
> > >>4- Can we still use startBatch/executeBatch?
> > >>
> > >>5- Can you explain how insert() and insertXXXX() differs (besides the
> > >>executed statement's name)?
> > >>
> > >>Cheers,
> > >>Philippe
> > >>
> > >>
> > >>Clinton Begin wrote:
> > >>
> > >>>Although quite simple, there are some tradeoffs with the typical
> > >>>SqlMapClient methods like:
> > >>>
> > >>>Document doc = (Document) sqlMap.queryForList("getDocument", new
> > >>>Integer (1));
> > >>>
> > >>>First of all, it is possible that you could spell getDocuments
> > >>>incorrectly. Second, the parameter is not strongly typed. So at code
> > >>>time, you could easily pass in an inappropriate object. Also, the
> > >>>return type is cast, so it's even possible for the statement to return
> > >>>an invalid object (i.e. result map returns a Dog instead of a
> > >>>Document). Finally, if you're using anything less than J2SE 5.0, you
> > >>>have to wrap primitives with their wrapper types. DISCLAIMER: Yes, you
> > >>>should have unit tests to verify this anyway! ;-)
> > >>>
> > >>>But what else can we do about this? Well, what if we mapped the
> > >>>"getDocument" mapped statement to an interface. For example, this one:
> > >>>
> > >>>public interface DocumentMapper {
> > >>>Document getDocument (int id);
> > >>>}
> > >>>
> > >>>So basically we have a method that mirrors the queryForList signature,
> > >>>except the method name matches the mapped statement name, instead of
> > >>>passing it as a parameter. Furthermore, as soon as the SqlMapClient is
> > >>>built, this method is validated against the mapped statement to ensure
> > >>>that the proper parameter and result types are defined. Finally, using
> > >>>the sucker is a whole lot easier:
> > >>>
> > >>>Document doc = documentMapper.getDocument(1);
> > >>>
> > >>>No more casting. No more wrapping. No more ambiguous types. No more
> > >>>misspelling.
> > >>>
> > >>>Sounds good, how do I create a Mapper? Well, we already have. The
> > >>>interface above is all we need. A simple call to the following
> > >>>SqlMapClient method, creates the instance that can be used:
> > >>>
> > >>>DocumentMapper documentMapper = (DocumentMapper)
> > >>>sqlMap.getMapper(DocumentMapper.class);
> > >>>
> > >>>The instance is thread safe, so you can keep this sucker around as a
> > >>>field on your DAO or service class.
> > >>>
> > >>>Best of all, unit testing becomes a snap, as you can mock a
> > >>>DocumentMapper a heck of a lot easier than you could the SqlMapClient
> > >>>interface.
> > >>>
> > >>>Alrighty! So when will it be implemented? It already is. It's in SVN
> > >>>right now for your perusal, here's the unit test:
> > >>>
> > >>>
> > >>
> > >>http://svn.apache.org/repos/asf/incubator/ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/BindingTest.java
> > >>
> > >>><
> > >>
> > >>http://svn.apache.org/repos/asf/incubator/ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/BindingTest.java
> > >>
> > >>>
> > >>>The JavaDoc is below.
> > >>>
> > >>>The current implementation isn't optimized, nor does it perform full
> > >>>validation. In it's current state, it's mostly intended to be easily
> > >>>removed if you don't like the idea.
> > >>>
> > >>>So let us know what you think!
> > >>>
> > >>>Cheers,
> > >>>Clinton
> > >>>
> > >>>
> > >>>
> > >>>----------------------------------------
> > >>>
> > >>>
> > >>>getMapper
> > >>>
> > >>>public java.lang.Object *getMapper*(java.lang.Class iface)
> > >>>
> > >>>Returns a generated implementation of a cusom mapper class as
> > >>>specified by the method parameter. The generated implementation will
> > >>>run mapped statements by matching the method name to the statement
> > >>>name. The mapped statement elements determine how the statement is
> > >>>run as per the following:
> > >>>
> > >>>* <insert> -- insert()
> > >>>* <update> -- update()
> > >>>* <delete> -- delete()
> > >>>* <select> -- queryForObject, queryForList or queryForMap, as
> > >>>determined by signature (see below)
> > >>>* <procedure> -- determined by method name (see below)
> > >>>
> > >>>How select statements are run is determined by the method signature,
> > >>>as per the following:
> > >>>
> > >>>* Object methodName (Object param) -- queryForObject
> > >>>* List methodName (Object param [, int skip, int max | , int
> > >>>pageSize]) -- queryForList
> > >>>* Map methodName (Object param, String keyProp [,valueProp]) --
> > >>>queryForMap
> > >>>
> > >>>How stored procedures are run is determined by the method name, as
> > >>>per the following:
> > >>>
> > >>>* insertXxxxx -- insert()
> > >>>* createXxxxx -- insert()
> > >>>* updateXxxxx -- update()
> > >>>* saveXxxxx -- update()
> > >>>* deleteXxxxx -- delete()
> > >>>* removeXxxxx -- delete()
> > >>>* selectXxxxx -- queryForXxxxxx() determined by method signature
> > >>>as above
> > >>>* queryXxxxx -- queryForXxxxxx() determined by method signature
> > >>>as above
> > >>>* fetchXxxxx -- queryForXxxxxx() determined by method signature
> > >>>as above
> > >>>* getXxxxx -- queryForXxxxxx() determined by method signature as
> > >>>above
> > >>>
> > >>>*Parameters:*
> > >>>|iface| - The interface that contains methods representing the
> > >>>mapped statements contained.
> > >>>*Returns:*
> > >>>An instance of iface that can be used to call mapped statements
> > >>>directly in a typesafe manner.
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>
> > >>
> > >
> >
> >
>

Reply via email to