create or replace PACKAGE PACKAGE1 AS PROCEDURE TEST_EMPLOYEE ( I_GENDER IN VARCHAR2 DEFAULT 'M', O_RESULT OUT SYS_REFCURSOR, o_return_code OUT INT ); END PACKAGE1; create or replace PACKAGE BODY PACKAGE1 AS PROCEDURE TEST_EMPLOYEE ( I_GENDER IN VARCHAR2 DEFAULT 'M', O_RESULT OUT SYS_REFCURSOR, o_return_code OUT INT ) AS BEGIN OPEN O_RESULT FOR SELECT ID, NAME, PHONE, ADDRESS, GENDER FROM EMPLOYEE WHERE GENDER = I_GENDER; o_return_code := 0; END TEST_EMPLOYEE; END PACKAGE1;
Step1. Create a custom repository interface:
package com.example.jpa.repository.custom; import java.util.Map; public interface EmployeeRepositoryCustom { Map<String, Object> findEmployee(String gender); }
Step2. Create a custom implementation class:
package com.example.jpa.repository.impl; import com.example.jpa.entity.Employee; import com.example.jpa.repository.custom.EmployeeRepositoryCustom; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.simple.SimpleJdbcCall; import java.util.Map; @Slf4j public class EmployeeRepositoryImpl implements EmployeeRepositoryCustom { @Autowired private NamedParameterJdbcTemplate jdbcTemplate; @Override public Map<String, Object> findEmployee(String gender) { SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate.getJdbcTemplate().getDataSource()) .withCatalogName("PACKAGE1") .withProcedureName("TEST_EMPLOYEE") .returningResultSet("O_RESULT", BeanPropertyRowMapper.newInstance(Employee.class)); SqlParameterSource input = new MapSqlParameterSource().addValue("I_GENDER", gender); Map<String, Object> output = jdbcCall.execute(input); output.entrySet().forEach(entry -> log.debug("key = {}, value = {}", entry.getKey(), entry.getValue())); return output; } }
Step3. Create an repository interface
package com.example.jpa.repository; import com.example.jpa.entity.Employee; import com.example.jpa.repository.custom.EmployeeRepositoryCustom; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; @Repository public interface EmployeeRepository extends CrudRepository<Employee, String>, EmployeeRepositoryCustom { }
Step4. Create a test case:
package com.example.jpa; import com.example.jpa.entity.Employee; import com.example.jpa.repository.EmployeeRepository; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.builder.ToStringBuilder; import org.junit.Assert; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.math.BigDecimal; import java.util.List; import java.util.Map; @SpringBootTest @Slf4j public class TestEmployeeRepository { @Autowired private EmployeeRepository employeeRepository; @Test public void testFindEmployee() { Map<String, Object> output = employeeRepository.findEmployee("F"); List<Employee> employees = (List<Employee>) output.get("O_RESULT"); for (int i = 0; i < employees.size(); i++) { log.debug("employee = {}", ToStringBuilder.reflectionToString(employees.get(i))); } int returnCode = ((BigDecimal) output.get("O_RETURN_CODE")).intValue(); log.debug("returnCode = {}", returnCode); } }
Step5. Check result:
[ main] c.e.j.r.impl.EmployeeRepositoryImpl : key = O_RESULT, value = [com.example.jpa.entity.Employee@2adbd899, com.example.jpa.entity.Employee@d6831df] [ main] c.e.j.r.impl.EmployeeRepositoryImpl : key = O_RETURN_CODE, value = 0 [ main] com.example.jpa.TestEmployeeRepository : employee = com.example.jpa.entity.Employee@77ccded4[id=2,name=Mandy,phone=0911111111,address=Taipei,gender=F] [ main] com.example.jpa.TestEmployeeRepository : employee = com.example.jpa.entity.Employee@2bb717d7[id=3,name=Gina,phone=0911111111,address=ChiaYi,gender=F] [ main] com.example.jpa.TestEmployeeRepository : returnCode = 0