我在Spring Boot项目中使用存储过程并尝试获取输出值,但是在我的项目中,它始终返回null。但是,如果我通过HeidiSQL调用过程,则它可以正常工作并为我提供正确的值。
因此,它必须对我的Java代码做一些事情。我调试了受影响的方法,但无法找出为什么它返回null。
我已经尝试查找其他帖子,但是找不到与我的特定问题匹配的内容。
这是我尝试使用存储过程的方法:
CompanyResourceServiceImpl
@Service public class CompanyResourceServiceImpl implements CompanyResourceService { @PersistenceContext private EntityManager entityManager; ... private int getMetalResourceByPlayerId(int theId) { StoredProcedureQuery theQuery = entityManager.createStoredProcedureQuery("getAllMetalFromCompaniesByPlayerId"); theQuery.registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN); theQuery.registerStoredProcedureParameter(2, BigDecimal.class, ParameterMode.OUT); theQuery.setParameter(1, theId); theQuery.execute(); BigDecimal outAmount = (BigDecimal) theQuery.getOutputParameterValue(2); return outAmount.intValue(); } ... }
以下是存储过程:
getAllMetalFromCompaniesByPlayerId
CREATE DEFINER=`root`@`localhost` PROCEDURE `getAllMetalFromCompaniesByPlayerId`( IN `playerId` INT, OUT `metalSum` DECIMAL(19,2) ) LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN SELECT sum(cr.amount) as metalSum FROM company_resource cr JOIN company c ON (c.id = cr.company_id) WHERE c.player_id = playerId and cr.resource_id = 1; END
我的目标是获取输出值并在@Scheduled方法中使用它。就像我说的那样,在HeidiSQL中,存储过程有效。
@Scheduled
经过数小时的尝试,我找到了使其工作的方法。
首先,我添加@NamedStoredProcedureQuery到CompanyResource实体类中:
@NamedStoredProcedureQuery
CompanyResource
CompanyResource.java
@Entity @Table(name = "company_resource") @NamedStoredProcedureQueries({ @NamedStoredProcedureQuery(name = "getAllMetalFromCompaniesByPlayerId", procedureName = "getAllMetalFromCompaniesByPlayerId", parameters = { @StoredProcedureParameter(mode = ParameterMode.IN, name = "playerId", type = Integer.class), @StoredProcedureParameter(mode = ParameterMode.OUT, name = "metalSum", type = BigDecimal.class) }) }) @IdClass(CompanyResourcePK.class) public class CompanyResource { ... }
然后我按如下getMetalResourceByPlayerId()方式更改了我的方法CompanyResourceServiceImpl:
getMetalResourceByPlayerId()
CompanyResourceServiceImpl.java
@Service public class CompanyResourceServiceImpl implements CompanyResourceService { @PersistenceContext private EntityManager entityManager; ... private int getMetalResourceByPlayerId(int theId) { StoredProcedureQuery theQuery = entityManager.createNamedStoredProcedureQuery("getAllMetalFromCompaniesByPlayerId"); theQuery.setParameter("Param1", theId); BigDecimal outAmount = (BigDecimal) theQuery.getSingleResult(); return outAmount.intValue(); } ... }