Allow parameter name binding for SimpleJdbcCall
Update SimpleJdbcCall to offer a way to use named parameters binding instead of the simple `?` binding it offers thus far. Issue: SPR-12801
This commit is contained in:
parent
477d4c5126
commit
8dec8823fb
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -46,6 +46,7 @@ import org.springframework.util.StringUtils;
|
|||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Juergen Hoeller
|
||||
* @author Kiril Nugmanov
|
||||
* @since 2.5
|
||||
*/
|
||||
public class CallMetaDataContext {
|
||||
|
@ -83,6 +84,9 @@ public class CallMetaDataContext {
|
|||
/** Should we access call parameter meta data info or not */
|
||||
private boolean accessCallParameterMetaData = true;
|
||||
|
||||
/** Should we bind parameter by name **/
|
||||
private boolean namedBinding;
|
||||
|
||||
/** The provider of call meta data */
|
||||
private CallMetaDataProvider metaDataProvider;
|
||||
|
||||
|
@ -213,6 +217,19 @@ public class CallMetaDataContext {
|
|||
return this.accessCallParameterMetaData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether parameters should be bound by name.
|
||||
*/
|
||||
public void setNamedBinding(boolean namedBinding) {
|
||||
this.namedBinding = namedBinding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether parameters should be bound by name.
|
||||
*/
|
||||
public boolean isNamedBinding() {
|
||||
return namedBinding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ReturnResultSetParameter/SqlOutParameter depending on the support provided
|
||||
|
@ -595,7 +612,7 @@ public class CallMetaDataContext {
|
|||
callString += ", ";
|
||||
}
|
||||
if (parameterCount >= 0) {
|
||||
callString += "?";
|
||||
callString += createParameterBinding(parameter);
|
||||
}
|
||||
parameterCount++;
|
||||
}
|
||||
|
@ -605,4 +622,17 @@ public class CallMetaDataContext {
|
|||
return callString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the parameter binding fragment.
|
||||
* @param parameter call parameter
|
||||
* @return parameter binding fragment
|
||||
*/
|
||||
protected String createParameterBinding(SqlParameter parameter) {
|
||||
if (isNamedBinding()) {
|
||||
return parameter.getName() + " => ?";
|
||||
} else {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -198,6 +198,21 @@ public abstract class AbstractJdbcCall {
|
|||
this.callMetaDataContext.setAccessCallParameterMetaData(accessCallParameterMetaData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does parameters should be bound by name?
|
||||
*/
|
||||
public boolean isNamedBinding() {
|
||||
return this.callMetaDataContext.isNamedBinding();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether parameters should be bound by name.
|
||||
* The default is {@code false}.
|
||||
*/
|
||||
public void setNamedBinding(boolean namedBinding) {
|
||||
this.callMetaDataContext.setNamedBinding(namedBinding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the call string that should be used based on parameters and meta data.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -53,6 +53,7 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
|||
* to provide the ability to chain multiple ones together in a "fluent" interface style.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.5
|
||||
* @see java.sql.DatabaseMetaData
|
||||
* @see org.springframework.jdbc.core.JdbcTemplate
|
||||
|
@ -139,6 +140,12 @@ public class SimpleJdbcCall extends AbstractJdbcCall implements SimpleJdbcCallOp
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleJdbcCall withNamedBinding() {
|
||||
setNamedBinding(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T executeFunction(Class<T> returnType, Object... args) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -28,6 +28,7 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
|||
* as it can easily be mocked or stubbed.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.5
|
||||
*/
|
||||
public interface SimpleJdbcCallOperations {
|
||||
|
@ -100,6 +101,12 @@ public interface SimpleJdbcCallOperations {
|
|||
*/
|
||||
SimpleJdbcCallOperations withoutProcedureColumnMetaDataAccess();
|
||||
|
||||
/**
|
||||
* Indicates that parameters should be bound by name.
|
||||
* @return the instance of this SimpleJdbcCall
|
||||
*/
|
||||
SimpleJdbcCallOperations withNamedBinding();
|
||||
|
||||
|
||||
/**
|
||||
* Execute the stored function and return the results obtained as an Object of the
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -24,6 +24,7 @@ import java.sql.SQLException;
|
|||
import java.sql.Types;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
@ -41,9 +42,10 @@ import static org.mockito.BDDMockito.*;
|
|||
import static org.springframework.tests.Matchers.*;
|
||||
|
||||
/**
|
||||
* Mock object based tests for SimpleJdbcCall.
|
||||
* Tests for {@link SimpleJdbcCall}.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Kiril Nugmanov
|
||||
*/
|
||||
public class SimpleJdbcCallTests {
|
||||
|
||||
|
@ -193,7 +195,8 @@ public class SimpleJdbcCallTests {
|
|||
|
||||
}
|
||||
|
||||
@Test public void testAddInvoiceFuncWithMetaDataUsingArrayParams() throws Exception {
|
||||
@Test
|
||||
public void testAddInvoiceFuncWithMetaDataUsingArrayParams() throws Exception {
|
||||
initializeAddInvoiceWithMetaData(true);
|
||||
SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withFunctionName("add_invoice");
|
||||
Number newId = adder.executeFunction(Number.class, 1103, 3);
|
||||
|
@ -203,6 +206,34 @@ public class SimpleJdbcCallTests {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectFunctionStatement() throws Exception {
|
||||
initializeAddInvoiceWithMetaData(true);
|
||||
SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withFunctionName("add_invoice");
|
||||
adder.compile();
|
||||
verifyStatement(adder, "{? = call ADD_INVOICE(?, ?)}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectFunctionStatementNamed() throws Exception {
|
||||
initializeAddInvoiceWithMetaData(true);
|
||||
SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withNamedBinding().withFunctionName("add_invoice");
|
||||
adder.compile();
|
||||
verifyStatement(adder, "{? = call ADD_INVOICE(AMOUNT => ?, CUSTID => ?)}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectProcedureStatementNamed() throws Exception {
|
||||
initializeAddInvoiceWithMetaData(false);
|
||||
SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withNamedBinding().withProcedureName("add_invoice");
|
||||
adder.compile();
|
||||
verifyStatement(adder, "{call ADD_INVOICE(AMOUNT => ?, CUSTID => ?, NEWID => ?)}");
|
||||
}
|
||||
|
||||
private void verifyStatement(SimpleJdbcCall adder, String expected) {
|
||||
Assert.assertEquals("Incorrect call statement", expected, adder.getCallString());
|
||||
}
|
||||
|
||||
private void initializeAddInvoiceWithoutMetaData(boolean isFunction)
|
||||
throws SQLException {
|
||||
given(databaseMetaData.getDatabaseProductName()).willReturn("MyDB");
|
||||
|
@ -281,6 +312,5 @@ public class SimpleJdbcCallTests {
|
|||
verify(callableStatement).close();
|
||||
verify(proceduresResultSet).close();
|
||||
verify(procedureColumnsResultSet).close();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue