Попробуйте следующие реализации:
Получите java.sql.Connection
, используя EntityManager
:
Connection cc = ((SessionImpl) em.getDelegate()).connection();
С этим Connection
вы можете использовать класс java.sql.CallableStatement
для выполнения вызововхранимые процедуры и функции следующим образом:
CallableStatement callableStatement;
try {
callableStatement = cc.prepareCall("{call stored_proc(?,?,?,?,?)}");
callableStatement.setString(1, "1");//Parameter #1
callableStatement.setString(2, "ET");////Parameter #2
callableStatement.setString(3, "|s|");// //Parameter #3
callableStatement.registerOutParameter(4, Types.INTEGER); //Output # 1
callableStatement.registerOutParameter(5, Types.VARCHAR); //Output # 2
callableStatement.execute();
Integer outputValue = callableStatement.getInt(4);
String outputValue1 = callableStatement.getString(5);
}
Другая реализация основана на этом post .
Создайте класс, который расширяет StoredProcedure
:
/**
* Class to provide access to the database. With this class you can invoke functions and stored procedures.
*/
public class GenericDatabaseCaller {
/**Data source. */
private DataSource dataSource;
/**
* This method requires LinkedHashMaps for inParams and outParams so that parameters can be set in a
* sequence.
* @param functionName Name of the stored procedure or function.
* @param isFunction indicates if the process to execute is a Function or a Stored procedure.
* @param inParams {@link LinkedHashMap} of IN parameters.
* @param outParams {@link LinkedHashMap} of OUT Parameters.
* @return {@link Map} with the output parameters.
*/
public Map executeSimpleProcedure(String functionName, boolean isFunction, Map<String, Object> inParams,
Map<String, Object> outParams) {
InnerStoredProcedure innerStoredProcedure = new InnerStoredProcedure(dataSource, functionName, isFunction,
inParams, outParams);
return innerStoredProcedure.executeProcedure(inParams);
}
private class InnerStoredProcedure extends StoredProcedure {
/**
* @param ds
* @param SQL
* @param isFunction
* @param inParams
* @param outParams
*/
public InnerStoredProcedure(DataSource ds, String SQL, boolean isFunction, Map<String, Object> inParams, Map<String, Object> outParams) {
setDataSource(ds);
setFunction(isFunction);
setSql(SQL);
configerParameters(inParams, outParams);
compile();
}
/**
* Configure the input and output parameters for the stored procedure
* @param inParams
* @param outputParamers
*/
public void configerParameters(Map<String, Object> inParams, Map<String, Object> outputParamers) {
if (inParams != null && inParams.size() > 0) {
Iterator<String> keySetIterator = inParams.keySet().iterator();
while (keySetIterator.hasNext()) {
String key = keySetIterator.next();
if (inParams.get(key) instanceof String) {
declareParameter(new SqlParameter(key, Types.VARCHAR));
} else if (inParams.get(key) instanceof Integer) {
declareParameter(new SqlParameter(key, Types.INTEGER));
} else if (inParams.get(key) instanceof Date || inParams.get(key) instanceof java.sql.Date) {
declareParameter(new SqlParameter(key, Types.DATE));
}
// TODO Add more types.
}
}
if (outputParamers != null && outputParamers.size() > 0) {
Iterator<String> keySetIterator = outputParamers.keySet().iterator();
while (keySetIterator.hasNext()) {
String key = keySetIterator.next();
if (outputParamers.get(key) instanceof String) {
declareParameter(new SqlOutParameter(key, Types.VARCHAR));
} else if (outputParamers.get(key) instanceof Integer) {
declareParameter(new SqlOutParameter(key, Types.INTEGER));
}
}
}
}
public Map executeProcedure(Map inputs) {
return execute(inputs);
}
}
}
Затем вы можете вызвать вашу функцию или хранимую процедуру:
String procedureName = "stored_proc";
Map<String, Object> inMap = new LinkedHashMap<String, Object>();
inMap.put("parameter1", "10");
inMap.put("parameter2", "|Lib");
inMap.put("parameter3", "P");
Map<String, Object> outMap = new LinkedHashMap<String, Object>();
outMap.put("output", 0);
outMap.put("output1", "");
Map resultMap = genericDatabaseCaller.executeSimpleProcedure(procedureName, inMap, outMap);
Чтобы создать экземпляр GenericDatabaseCaller
, мы добавим несколько строк к нашему application-context.xml
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="genericDatabaseCaller"
class="co.com.custom.GenericDatabaseCaller">
<property name="dataSource" ref="dataSource" />
</bean>
Примечание что источник данных тот же, который мы используем для создания экземпляра EntityManager
.
Затем в нашем классе мы используем аннотацию @Respository
и добавляем аннотацию @Autowired
в поле GenericDatabaseCaller
.
@Repository(value = "customDao")
public class JPACustomDao implements CustomDao {
/** entity manager. */
private EntityManager em = null;
/**
* Sets the entity manager.
*
* @param entityManager {@link EntityManager}.
*/
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.em = entityManager;
}
@Autowired
private GenericDatabaseCaller genericStoredProcedure;
}
Надеюсь, это сработает для вас.