I' am trying to use Apache Camel's "mybatis-bean" to select some records with multiple parameters, but it turned out to be harder than I thought.
The mapper is defined as
@Mapper
public interface CityMapper {
@Select("SELECT * FROM CITY WHERE state = #{state}")
List<City> findByState(@Param("state") String state);
@Select("SELECT * FROM CITY WHERE state = #{state} AND country = #{country}")
List<City> findByStateAndCountry(@Param("state") String state, @Param("country") String country);
}
You can see from the code, I have two select query
findByState: select with 1 param (state)findByStateAndCountry: select with 1 param (state and country)
One param
If I use my route to call findByState and set NY as the state in the body
from("timer:myTimer?repeatCount=1")
.setBody(constant("NY"))
.to("mybatis-bean:com.netbase.camel.mapper.CityMapper:findByState").log("${body}");
You can see from the following log -- the NY in the body gets mapped to the only param state
2023-08-25 09:42:15.575 DEBUG 68665 --- [timer://myTimer] c.n.camel.mapper.CityMapper.findByState : ==> Preparing: SELECT * FROM CITY WHERE state = ?
2023-08-25 09:42:15.595 DEBUG 68665 --- [timer://myTimer] c.n.camel.mapper.CityMapper.findByState : ==> Parameters: NY(String)
2023-08-25 09:42:15.617 DEBUG 68665 --- [timer://myTimer] c.n.camel.mapper.CityMapper.findByState : <== Total: 1
2023-08-25 09:42:15.620 INFO 68665 --- [timer://myTimer] route1 : [City(name=New York City, country=US, state=NY)]
Two params 1st trial
However, when I try to call findByStateAndCountry (with two params - state and country), I couldn't get the data in body mapped correctly to each param. I've tried using Map and List -- none of them worked
from("timer:myTimer?repeatCount=1")
.process(exchange -> {
exchange.getIn().setBody(Map.of("state", "CA", "country", "US"));
})
.to("mybatis-bean:CityMapper:findByStateAndCountry")
.log("${body}");
Two params 2nd trial
And finally, just before I gave up, I tried to call the mapper method like a Java method and I could inject header values into it.
from("timer:myTimer?repeatCount=1")
.setHeader("state", constant("CA"))
.setHeader("country", constant("US"))
.to("mybatis-bean:CityMapper:findByStateAndCountry('${header.state}','${header.country}')")
.log("${body}");
My question is:
- Is my way a common way to bind the params in Camel?
- Is there another way to achieve the same effect?
In Apache Camel official doc, it doesn't mention anything about this. It's really frustrating. After figuring out the correct way to do it, I would like to contribute to the doc.
Thank you