This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit d5eb9a7753dd201532de6130b40aaa8594377de9 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Wed Mar 28 19:25:17 2018 +0200 CAMEL-12285: Added mybatis-bean as component to use MyBatis annotation mapper. --- ...BatisEndpoint.java => BaseMyBatisEndpoint.java} | 68 +-------- .../component/mybatis/MyBatisBeanComponent.java | 44 ++++++ .../component/mybatis/MyBatisBeanEndpoint.java | 80 +++++++++++ .../component/mybatis/MyBatisBeanProducer.java | 92 ++++++++++++ .../camel/component/mybatis/MyBatisComponent.java | 8 +- .../camel/component/mybatis/MyBatisEndpoint.java | 156 +-------------------- .../org/apache/camel/component/mybatis-bean | 18 +++ .../component/mybatis/bean/AccountService.java | 35 +++++ .../mybatis/bean/MyBatisBeanSelectListTest.java | 57 ++++++++ .../mybatis/bean/MyBatisBeanSelectOneTest.java | 54 +++++++ .../src/test/resources/SqlMapConfig.xml | 2 + .../MyBatisBeanComponentAutoConfiguration.java | 129 +++++++++++++++++ .../MyBatisBeanComponentConfiguration.java | 78 +++++++++++ .../src/main/resources/META-INF/spring.factories | 4 +- 14 files changed, 602 insertions(+), 223 deletions(-) diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/BaseMyBatisEndpoint.java similarity index 73% copy from components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java copy to components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/BaseMyBatisEndpoint.java index a394ef2..77ae5de 100644 --- a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java +++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/BaseMyBatisEndpoint.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,28 +19,12 @@ package org.apache.camel.component.mybatis; import java.io.IOException; import org.apache.camel.Component; -import org.apache.camel.Consumer; -import org.apache.camel.Processor; -import org.apache.camel.Producer; import org.apache.camel.impl.DefaultPollingEndpoint; -import org.apache.camel.spi.Metadata; -import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; -import org.apache.camel.spi.UriPath; -import org.apache.camel.util.ObjectHelper; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSessionFactory; -/** - * Performs a query, poll, insert, update or delete in a relational database using MyBatis. - */ -@UriEndpoint(firstVersion = "2.7.0", scheme = "mybatis", title = "MyBatis", syntax = "mybatis:statement", consumerClass = MyBatisConsumer.class, label = "database,sql") -public class MyBatisEndpoint extends DefaultPollingEndpoint { - - @UriPath @Metadata(required = "true") - private String statement; - @UriParam(label = "producer") - private StatementType statementType; +public abstract class BaseMyBatisEndpoint extends DefaultPollingEndpoint { @UriParam(label = "consumer", description = "Enables or disables transaction. If enabled then if processing an exchange failed then the consumer" + "break out processing any further exchanges to cause a rollback eager.") private boolean transacted; @@ -61,29 +45,11 @@ public class MyBatisEndpoint extends DefaultPollingEndpoint { @UriParam(label = "producer", defaultValue = "SIMPLE") private ExecutorType executorType; - public MyBatisEndpoint() { + public BaseMyBatisEndpoint() { } - public MyBatisEndpoint(String endpointUri, Component component, String statement) { + public BaseMyBatisEndpoint(String endpointUri, Component component) { super(endpointUri, component); - this.statement = statement; - } - - public Producer createProducer() throws Exception { - ObjectHelper.notNull(statementType, "statementType", this); - ObjectHelper.notNull(statement, "statement", this); - return new MyBatisProducer(this); - } - - public Consumer createConsumer(Processor processor) throws Exception { - ObjectHelper.notNull(statement, "statement", this); - MyBatisConsumer consumer = new MyBatisConsumer(this, processor); - consumer.setMaxMessagesPerPoll(getMaxMessagesPerPoll()); - consumer.setOnConsume(getOnConsume()); - consumer.setUseIterator(isUseIterator()); - consumer.setRouteEmptyResultSet(isRouteEmptyResultSet()); - configureConsumer(consumer); - return consumer; } public boolean isSingleton() { @@ -99,28 +65,6 @@ public class MyBatisEndpoint extends DefaultPollingEndpoint { return getComponent().getSqlSessionFactory(); } - public String getStatement() { - return statement; - } - - /** - * The statement name in the MyBatis XML mapping file which maps to the query, insert, update or delete operation you wish to evaluate. - */ - public void setStatement(String statement) { - this.statement = statement; - } - - public StatementType getStatementType() { - return statementType; - } - - /** - * Mandatory to specify for the producer to control which kind of operation to invoke. - */ - public void setStatementType(StatementType statementType) { - this.statementType = statementType; - } - public ExecutorType getExecutorType() { return executorType; } diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanComponent.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanComponent.java new file mode 100644 index 0000000..6a0b1a6 --- /dev/null +++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanComponent.java @@ -0,0 +1,44 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.mybatis; + +import java.util.Map; + +import org.apache.camel.Endpoint; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.StringHelper; + +public class MyBatisBeanComponent extends MyBatisComponent { + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { + String beanName = StringHelper.before(remaining, ":"); + String methodName = StringHelper.after(remaining, ":"); + + if (ObjectHelper.isEmpty(beanName)) { + throw new IllegalArgumentException("The option beanName must be provided when creating endpoint: " + uri); + } + if (ObjectHelper.isEmpty(methodName)) { + throw new IllegalArgumentException("The option methodName must be provided when creating endpoint: " + uri); + } + + MyBatisBeanEndpoint answer = new MyBatisBeanEndpoint(uri, this, beanName, methodName); + setProperties(answer, parameters); + return answer; + } + +} diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java new file mode 100644 index 0000000..09a94cd6 --- /dev/null +++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java @@ -0,0 +1,80 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.mybatis; + +import org.apache.camel.Component; +import org.apache.camel.Consumer; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.UriEndpoint; +import org.apache.camel.spi.UriParam; +import org.apache.camel.spi.UriPath; + +/** + * Performs a query, insert, update or delete in a relational database using MyBatis. + */ +@UriEndpoint(firstVersion = "2.22.0", scheme = "mybatis-bean", title = "MyBatis Bean", syntax = "mybatis-bean:beanName:methodName", producerOnly = true, label = "database,sql") +public class MyBatisBeanEndpoint extends BaseMyBatisEndpoint { + + @UriPath @Metadata(required = "true") + private String beanName; + @UriParam(label = "producer") + private String methodName; + + public MyBatisBeanEndpoint() { + } + + public MyBatisBeanEndpoint(String endpointUri, Component component, String beanName, String methodName) { + super(endpointUri, component); + this.beanName = beanName; + this.methodName = methodName; + } + + public Producer createProducer() throws Exception { + return new MyBatisBeanProducer(this); + } + + @Override + public Consumer createConsumer(Processor processor) throws Exception { + throw new IllegalArgumentException("Consumer not support on this component (mybatis-bean), use mybatis instead."); + } + + public String getBeanName() { + return beanName; + } + + /** + * Name of the bean with the MyBatis annotations. + * This can either by a type alias or a FQN class name. + */ + public void setBeanName(String beanName) { + this.beanName = beanName; + } + + public String getMethodName() { + return methodName; + } + + /** + * Name of the method on the bean that has the SQL query to be executed. + */ + public void setMethodName(String methodName) { + this.methodName = methodName; + } + +} diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanProducer.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanProducer.java new file mode 100644 index 0000000..31ca99c --- /dev/null +++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanProducer.java @@ -0,0 +1,92 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.mybatis; + +import org.apache.camel.Exchange; +import org.apache.camel.component.bean.BeanProcessor; +import org.apache.camel.impl.DefaultProducer; +import org.apache.camel.util.IOHelper; +import org.apache.camel.util.ServiceHelper; +import org.apache.ibatis.session.ExecutorType; +import org.apache.ibatis.session.SqlSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MyBatisBeanProducer extends DefaultProducer { + + private static final Logger LOG = LoggerFactory.getLogger(MyBatisBeanProducer.class); + private MyBatisBeanEndpoint endpoint; + private BeanProcessor beanProcessor; + private SqlSession session; + + public MyBatisBeanProducer(MyBatisBeanEndpoint endpoint) { + super(endpoint); + this.endpoint = endpoint; + } + + public void process(Exchange exchange) throws Exception { + LOG.trace("Invoking MyBatisBean on {}:{}", endpoint.getBeanName(), endpoint.getMethodName()); + beanProcessor.process(exchange); + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + + // discover the bean and get the mapper + session = null; + + ExecutorType executorType = endpoint.getExecutorType(); + if (executorType == null) { + session = endpoint.getSqlSessionFactory().openSession(); + } else { + session = endpoint.getSqlSessionFactory().openSession(executorType); + } + LOG.debug("Opened MyBatis SqlSession: {}", session); + + // is the bean a alias type + Class clazz = session.getConfiguration().getTypeAliasRegistry().resolveAlias(endpoint.getBeanName()); + if (clazz == null) { + // its maybe a FQN so try to use Camel to lookup the class + clazz = getEndpoint().getCamelContext().getClassResolver().resolveMandatoryClass(endpoint.getBeanName()); + } + + LOG.debug("Resolved MyBatis Bean: {} as class: {}", endpoint.getBeanName(), clazz); + + // find the mapper + Object mapper = session.getMapper(clazz); + if (mapper == null) { + throw new IllegalArgumentException("No Mapper with typeAlias or class name: " + endpoint.getBeanName() + " in MyBatis configuration."); + } + LOG.debug("Resolved MyBatis Bean mapper: {}", mapper); + + beanProcessor = new BeanProcessor(mapper, getEndpoint().getCamelContext()); + beanProcessor.setMethod(endpoint.getMethodName()); + ServiceHelper.startService(beanProcessor); + } + + @Override + protected void doStop() throws Exception { + super.doStop(); + + ServiceHelper.stopService(beanProcessor); + + LOG.debug("Closing MyBatis SqlSession: {}", session); + IOHelper.close(session); + session = null; + } +} diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisComponent.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisComponent.java index 1635ea7..deb8d7a 100644 --- a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisComponent.java +++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisComponent.java @@ -21,7 +21,7 @@ import java.io.InputStream; import java.util.Map; import org.apache.camel.Endpoint; -import org.apache.camel.impl.UriEndpointComponent; +import org.apache.camel.impl.DefaultComponent; import org.apache.camel.spi.Metadata; import org.apache.camel.util.IOHelper; import org.apache.camel.util.ObjectHelper; @@ -32,17 +32,13 @@ import org.apache.ibatis.session.SqlSessionFactoryBuilder; /** * @version */ -public class MyBatisComponent extends UriEndpointComponent { +public class MyBatisComponent extends DefaultComponent { @Metadata(label = "advanced") private SqlSessionFactory sqlSessionFactory; @Metadata(defaultValue = "SqlMapConfig.xml") private String configurationUri = "SqlMapConfig.xml"; - public MyBatisComponent() { - super(MyBatisEndpoint.class); - } - @Override protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { MyBatisEndpoint answer = new MyBatisEndpoint(uri, this, remaining); diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java index a394ef2..418c6e9 100644 --- a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java +++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java @@ -34,32 +34,13 @@ import org.apache.ibatis.session.SqlSessionFactory; /** * Performs a query, poll, insert, update or delete in a relational database using MyBatis. */ -@UriEndpoint(firstVersion = "2.7.0", scheme = "mybatis", title = "MyBatis", syntax = "mybatis:statement", consumerClass = MyBatisConsumer.class, label = "database,sql") -public class MyBatisEndpoint extends DefaultPollingEndpoint { +@UriEndpoint(firstVersion = "2.7.0", scheme = "mybatis", title = "MyBatis", syntax = "mybatis:statement", consumerClass = MyBatisConsumer.class, label = "database,sql") +public class MyBatisEndpoint extends BaseMyBatisEndpoint { @UriPath @Metadata(required = "true") private String statement; @UriParam(label = "producer") private StatementType statementType; - @UriParam(label = "consumer", description = "Enables or disables transaction. If enabled then if processing an exchange failed then the consumer" - + "break out processing any further exchanges to cause a rollback eager.") - private boolean transacted; - @UriParam(label = "consumer", defaultValue = "0") - private int maxMessagesPerPoll; - @UriParam - private String outputHeader; - @UriParam(label = "consumer") - private String inputHeader; - @UriParam(label = "consumer", optionalPrefix = "consumer.") - private String onConsume; - @UriParam(label = "consumer", optionalPrefix = "consumer.", defaultValue = "true") - private boolean useIterator = true; - @UriParam(label = "consumer", optionalPrefix = "consumer.") - private boolean routeEmptyResultSet; - @UriParam(label = "consumer,advanced") - private MyBatisProcessingStrategy processingStrategy = new DefaultMyBatisProcessingStrategy(); - @UriParam(label = "producer", defaultValue = "SIMPLE") - private ExecutorType executorType; public MyBatisEndpoint() { } @@ -86,19 +67,6 @@ public class MyBatisEndpoint extends DefaultPollingEndpoint { return consumer; } - public boolean isSingleton() { - return true; - } - - @Override - public MyBatisComponent getComponent() { - return (MyBatisComponent) super.getComponent(); - } - - public SqlSessionFactory getSqlSessionFactory() throws IOException { - return getComponent().getSqlSessionFactory(); - } - public String getStatement() { return statement; } @@ -121,124 +89,4 @@ public class MyBatisEndpoint extends DefaultPollingEndpoint { this.statementType = statementType; } - public ExecutorType getExecutorType() { - return executorType; - } - - /** - * The executor type to be used while executing statements. - * <ul> - * <li>simple - executor does nothing special.</li> - * <li>reuse - executor reuses prepared statements.</li> - * <li>batch - executor reuses statements and batches updates.</li> - * </ul> - */ - public void setExecutorType(ExecutorType executorType) { - this.executorType = executorType; - } - - public void setExecutorType(String executorType) { - this.executorType = ExecutorType.valueOf(executorType.toUpperCase()); - } - - public boolean isTransacted() { - return transacted; - } - - /** - * Enables or disables transaction. If enabled then if processing an exchange failed then the consumer - + break out processing any further exchanges to cause a rollback eager - */ - public void setTransacted(boolean transacted) { - this.transacted = transacted; - } - - public MyBatisProcessingStrategy getProcessingStrategy() { - return processingStrategy; - } - - /** - * To use a custom MyBatisProcessingStrategy - */ - public void setProcessingStrategy(MyBatisProcessingStrategy processingStrategy) { - this.processingStrategy = processingStrategy; - } - - public int getMaxMessagesPerPoll() { - return maxMessagesPerPoll; - } - - /** - * This option is intended to split results returned by the database pool into the batches and deliver them in multiple exchanges. - * This integer defines the maximum messages to deliver in single exchange. By default, no maximum is set. - * Can be used to set a limit of e.g. 1000 to avoid when starting up the server that there are thousands of files. - * Set a value of 0 or negative to disable it. - */ - public void setMaxMessagesPerPoll(int maxMessagesPerPoll) { - this.maxMessagesPerPoll = maxMessagesPerPoll; - } - - public String getOutputHeader() { - return outputHeader; - } - - /** - * Store the query result in a header instead of the message body. - * By default, outputHeader == null and the query result is stored in the message body, - * any existing content in the message body is discarded. - * If outputHeader is set, the value is used as the name of the header to store the - * query result and the original message body is preserved. Setting outputHeader will - * also omit populating the default CamelMyBatisResult header since it would be the same - * as outputHeader all the time. - */ - public void setOutputHeader(String outputHeader) { - this.outputHeader = outputHeader; - } - - public String getInputHeader() { - return inputHeader; - } - - /** - * User the header value for input parameters instead of the message body. - * By default, inputHeader == null and the input parameters are taken from the message body. - * If outputHeader is set, the value is used and query parameters will be taken from the - * header instead of the body. - */ - public void setInputHeader(String inputHeader) { - this.inputHeader = inputHeader; - } - - public String getOnConsume() { - return onConsume; - } - - /** - * Statement to run after data has been processed in the route - */ - public void setOnConsume(String onConsume) { - this.onConsume = onConsume; - } - - public boolean isUseIterator() { - return useIterator; - } - - /** - * Process resultset individually or as a list - */ - public void setUseIterator(boolean useIterator) { - this.useIterator = useIterator; - } - - public boolean isRouteEmptyResultSet() { - return routeEmptyResultSet; - } - - /** - * Whether allow empty resultset to be routed to the next hop - */ - public void setRouteEmptyResultSet(boolean routeEmptyResultSet) { - this.routeEmptyResultSet = routeEmptyResultSet; - } } diff --git a/components/camel-mybatis/src/main/resources/META-INF/services/org/apache/camel/component/mybatis-bean b/components/camel-mybatis/src/main/resources/META-INF/services/org/apache/camel/component/mybatis-bean new file mode 100644 index 0000000..f9da46f --- /dev/null +++ b/components/camel-mybatis/src/main/resources/META-INF/services/org/apache/camel/component/mybatis-bean @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +class=org.apache.camel.component.mybatis.MyBatisBeanComponent diff --git a/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/AccountService.java b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/AccountService.java new file mode 100644 index 0000000..ec3320a --- /dev/null +++ b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/AccountService.java @@ -0,0 +1,35 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.mybatis.bean; + +import java.util.List; + +import org.apache.camel.component.mybatis.Account; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.ResultMap; +import org.apache.ibatis.annotations.Select; + +public interface AccountService { + + @Select("select ACC_ID as id, ACC_FIRST_NAME as firstName, ACC_LAST_NAME as lastName" + + ", ACC_EMAIL as emailAddress from ACCOUNT where ACC_ID = #{id}") + Account selectBeanAccountById(@Param("id") int no); + + @Select("select * from ACCOUNT order by ACC_ID") + @ResultMap("Account.AccountResult") + List<Account> selectBeanAllAccounts(); +} diff --git a/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectListTest.java b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectListTest.java new file mode 100644 index 0000000..72cbe1a --- /dev/null +++ b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectListTest.java @@ -0,0 +1,57 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.mybatis.bean; + +import java.util.List; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.component.mybatis.Account; +import org.apache.camel.component.mybatis.MyBatisTestSupport; +import org.junit.Test; + +public class MyBatisBeanSelectListTest extends MyBatisTestSupport { + + @Test + public void testSelectList() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedMessageCount(1); + + template.sendBody("direct:start", null); + + assertMockEndpointsSatisfied(); + + List<?> list = mock.getReceivedExchanges().get(0).getIn().getBody(List.class); + Account james = (Account) list.get(0); + Account claus = (Account) list.get(1); + assertEquals("James", james.getFirstName()); + assertEquals("Claus", claus.getFirstName()); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .to("mybatis-bean:AccountService:selectBeanAllAccounts") + .to("mock:result"); + } + }; + } + +} diff --git a/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectOneTest.java b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectOneTest.java new file mode 100644 index 0000000..bdb4025 --- /dev/null +++ b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectOneTest.java @@ -0,0 +1,54 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.mybatis.bean; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.component.mybatis.Account; +import org.apache.camel.component.mybatis.MyBatisTestSupport; +import org.junit.Test; + +public class MyBatisBeanSelectOneTest extends MyBatisTestSupport { + + @Test + public void testSelectOne() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedMessageCount(1); + mock.message(0).body().isInstanceOf(Account.class); + + template.sendBody("direct:start", 456); + + assertMockEndpointsSatisfied(); + + Account account = mock.getReceivedExchanges().get(0).getIn().getBody(Account.class); + assertEquals("Claus", account.getFirstName()); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .to("mybatis-bean:AccountService:selectBeanAccountById") + .to("mock:result"); + } + }; + } + + +} diff --git a/components/camel-mybatis/src/test/resources/SqlMapConfig.xml b/components/camel-mybatis/src/test/resources/SqlMapConfig.xml index 4bc93c3..9347c08 100644 --- a/components/camel-mybatis/src/test/resources/SqlMapConfig.xml +++ b/components/camel-mybatis/src/test/resources/SqlMapConfig.xml @@ -30,6 +30,7 @@ <!-- Use type aliases to avoid typing the full classname every time. --> <typeAliases> <typeAlias alias="Account" type="org.apache.camel.component.mybatis.Account"/> + <typeAlias alias="AccountService" type="org.apache.camel.component.mybatis.bean.AccountService"/> </typeAliases> <!-- setup environment with JDBC data source --> @@ -46,6 +47,7 @@ <!-- mapping files --> <mappers> <mapper resource="org/apache/camel/component/mybatis/Account.xml"/> + <package name="org.apache.camel.component.mybatis.bean"/> </mappers> </configuration> \ No newline at end of file diff --git a/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentAutoConfiguration.java new file mode 100644 index 0000000..ea67c21 --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentAutoConfiguration.java @@ -0,0 +1,129 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.mybatis.springboot; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import org.apache.camel.CamelContext; +import org.apache.camel.component.mybatis.MyBatisBeanComponent; +import org.apache.camel.spi.ComponentCustomizer; +import org.apache.camel.spi.HasId; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.spring.boot.ComponentConfigurationProperties; +import org.apache.camel.spring.boot.util.CamelPropertiesHelper; +import org.apache.camel.spring.boot.util.ConditionalOnCamelContextAndAutoConfigurationBeans; +import org.apache.camel.spring.boot.util.GroupCondition; +import org.apache.camel.spring.boot.util.HierarchicalPropertiesEvaluator; +import org.apache.camel.util.IntrospectionSupport; +import org.apache.camel.util.ObjectHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; + +/** + * Generated by camel-package-maven-plugin - do not edit this file! + */ +@Generated("org.apache.camel.maven.packaging.SpringBootAutoConfigurationMojo") +@Configuration +@Conditional({ConditionalOnCamelContextAndAutoConfigurationBeans.class, + MyBatisBeanComponentAutoConfiguration.GroupConditions.class}) +@AutoConfigureAfter(CamelAutoConfiguration.class) +@EnableConfigurationProperties({ComponentConfigurationProperties.class, + MyBatisBeanComponentConfiguration.class}) +public class MyBatisBeanComponentAutoConfiguration { + + private static final Logger LOGGER = LoggerFactory + .getLogger(MyBatisBeanComponentAutoConfiguration.class); + @Autowired + private ApplicationContext applicationContext; + @Autowired + private CamelContext camelContext; + @Autowired + private MyBatisBeanComponentConfiguration configuration; + @Autowired(required = false) + private List<ComponentCustomizer<MyBatisBeanComponent>> customizers; + + static class GroupConditions extends GroupCondition { + public GroupConditions() { + super("camel.component", "camel.component.mybatis-bean"); + } + } + + @Lazy + @Bean(name = "mybatis-bean-component") + @ConditionalOnMissingBean(MyBatisBeanComponent.class) + public MyBatisBeanComponent configureMyBatisBeanComponent() + throws Exception { + MyBatisBeanComponent component = new MyBatisBeanComponent(); + component.setCamelContext(camelContext); + Map<String, Object> parameters = new HashMap<>(); + IntrospectionSupport.getProperties(configuration, parameters, null, + false); + for (Map.Entry<String, Object> entry : parameters.entrySet()) { + Object value = entry.getValue(); + Class<?> paramClass = value.getClass(); + if (paramClass.getName().endsWith("NestedConfiguration")) { + Class nestedClass = null; + try { + nestedClass = (Class) paramClass.getDeclaredField( + "CAMEL_NESTED_CLASS").get(null); + HashMap<String, Object> nestedParameters = new HashMap<>(); + IntrospectionSupport.getProperties(value, nestedParameters, + null, false); + Object nestedProperty = nestedClass.newInstance(); + CamelPropertiesHelper.setCamelProperties(camelContext, + nestedProperty, nestedParameters, false); + entry.setValue(nestedProperty); + } catch (NoSuchFieldException e) { + } + } + } + CamelPropertiesHelper.setCamelProperties(camelContext, component, + parameters, false); + if (ObjectHelper.isNotEmpty(customizers)) { + for (ComponentCustomizer<MyBatisBeanComponent> customizer : customizers) { + boolean useCustomizer = (customizer instanceof HasId) + ? HierarchicalPropertiesEvaluator.evaluate( + applicationContext.getEnvironment(), + "camel.component.customizer", + "camel.component.mybatis-bean.customizer", + ((HasId) customizer).getId()) + : HierarchicalPropertiesEvaluator.evaluate( + applicationContext.getEnvironment(), + "camel.component.customizer", + "camel.component.mybatis-bean.customizer"); + if (useCustomizer) { + LOGGER.debug("Configure component {}, with customizer {}", + component, customizer); + customizer.customize(component); + } + } + } + return component; + } +} \ No newline at end of file diff --git a/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentConfiguration.java new file mode 100644 index 0000000..35025db --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentConfiguration.java @@ -0,0 +1,78 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.mybatis.springboot; + +import javax.annotation.Generated; +import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon; +import org.apache.ibatis.session.SqlSessionFactory; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; + +/** + * Performs a query, insert, update or delete in a relational database using + * MyBatis. + * + * Generated by camel-package-maven-plugin - do not edit this file! + */ +@Generated("org.apache.camel.maven.packaging.SpringBootAutoConfigurationMojo") +@ConfigurationProperties(prefix = "camel.component.mybatis-bean") +public class MyBatisBeanComponentConfiguration + extends + ComponentConfigurationPropertiesCommon { + + /** + * To use the SqlSessionFactory + */ + @NestedConfigurationProperty + private SqlSessionFactory sqlSessionFactory; + /** + * Location of MyBatis xml configuration file. The default value is: + * SqlMapConfig.xml loaded from the classpath + */ + private String configurationUri = "SqlMapConfig.xml"; + /** + * Whether the component should resolve property placeholders on itself when + * starting. Only properties which are of String type can use property + * placeholders. + */ + private Boolean resolvePropertyPlaceholders = true; + + public SqlSessionFactory getSqlSessionFactory() { + return sqlSessionFactory; + } + + public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { + this.sqlSessionFactory = sqlSessionFactory; + } + + public String getConfigurationUri() { + return configurationUri; + } + + public void setConfigurationUri(String configurationUri) { + this.configurationUri = configurationUri; + } + + public Boolean getResolvePropertyPlaceholders() { + return resolvePropertyPlaceholders; + } + + public void setResolvePropertyPlaceholders( + Boolean resolvePropertyPlaceholders) { + this.resolvePropertyPlaceholders = resolvePropertyPlaceholders; + } +} \ No newline at end of file diff --git a/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/resources/META-INF/spring.factories b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/resources/META-INF/spring.factories index 63c8b50..8a07a35 100644 --- a/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/resources/META-INF/spring.factories +++ b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/resources/META-INF/spring.factories @@ -15,4 +15,6 @@ ## limitations under the License. ## --------------------------------------------------------------------------- org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.apache.camel.component.mybatis.springboot.MyBatisComponentAutoConfiguration +org.apache.camel.component.mybatis.springboot.MyBatisComponentAutoConfiguration,\ +org.apache.camel.component.mybatis.springboot.MyBatisBeanComponentAutoConfiguration + -- To stop receiving notification emails like this one, please contact davscl...@apache.org.