>> any plans to eliminate the Dao interface
>> reuirement on iBatis DAOs?
Yes. It's totally unecessary. I just didn't like the thought of returning Object.
>> 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.
Having thought about it more, I don't think it would make a difference. Tight binding could allow superinterfaces to be requested for partial/common behaviour.
>> How would a tight binding look like? How would the namespace be derived?
I don't want to derive the namespace, nor do I want to bind to it. Really, the namespace would just serve to protect the uniqueness of statements in different XML files, and would otherwise become largely irrelevant. I would't want the namespace named the same as the interface, as the namespace would be waaaay too long.
Here's how the tight binding would look:
<sqlMap namespace="person" interface="com.domain.PersonMapper">
Then you could request PersonMapper and all of it's superinterfaces from the getMapper() method as per the previous examples. Tight binding just means that you can't arbitrarily request any old interface from getMapper().
>> Does the TransactionManager expose the startBatch and executeBatch
>> methods? I didn't think it did.
It doesn't matter. All of the methods needed are exposed through SqlMapClient. The Mapper interfaces would just match up to methods such as startTransaction(), commitTransaction(), startBatch(), executeBatch() etc....
>> In other words, iBatis looks at both the method's signature AND the
>> SqlMap's tag to determine what SqlMapClient method to call.
The Javadoc describes the complete process in detail.
Cheers,
Clinton
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.
>>>
>>>
>>>
>>>
>>>
>>
>>
>