【问题标题】:Spring batch executing stor proc conditionallySpring批量有条件地执行stor proc
【发布时间】:2018-02-18 16:16:26
【问题描述】:

在我的 Spring Batch 应用程序中,我正在读取、处理然后尝试使用 stored procedure 将 ItemWriter 写入数据库:

下面是我的 CSV 文件的样子,让我们说出我想要读取、处理和写入的内容:

Cob Date;Customer Code;Identifer1;Identifier2;Price
20180123;ABC LTD;BFSTACK;1231.CZ;102.00

我的ItemWriter

@Slf4j
public class MyDBWriter implements ItemWriter<Entity> {

    private final EntityDAO scpDao;

    public MyWriter(EntityDAO scpDao) {
        this.scpDao = scpDao;
    }

    @Override
    public void write(List<? extends Entity> items) {
        items.forEach(scpDao::insertData);
    }
}

我的 DAO 实现:

@Repository
public class EntityDAOImpl implements EntityDAO {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    private SimpleJdbcCall simpleJdbcCall = null;


    @PostConstruct
    private void prepareStoredProcedure() { 
        simpleJdbcCall = new SimpleJdbcCall(jdbcTemplate).withProcedureName("loadPrice");
        //declare params
    }

    @Override
    public void insertData(Entity scp) {

        Map<String, Object> inParams = new HashMap<>();

        inParams.put("Identifier1", scp.getIdentifier1());
        inParams.put("Identifier2", scp.getIdentifier1());
        inParams.put("ClosingPrice", scp.getClosingPrice());
        inParams.put("DownloadDate", scp.getDownloadDate());

        simpleJdbcCall.execute(inParams);
    }
}

我用来更新的存储过程如下:

ALTER PROCEDURE [dbo].[loadPrice]
@Identifier1 VARCHAR(50),
@Identifier1  VARCHAR(50),
@ClosingPrice decimal(28,4),
@DownloadDate datetime

AS
 SET NOCOUNT ON;

UPDATE p
SET ClosingPrice = @ClosingPrice,
from Prices p
join Instrument s on s.SecurityID = p.SecurityID
WHERE convert(date, @DownloadDate) = convert(date, DownloadDate)
    and s.Identifier1 = @Identifier1


if @@ROWCOUNT = 0
    INSERT INTO dbo.Prices
    (
        sec.SecurityID
        , ClosingPrice
        , DownloadDate
    )
    select sec.SecurityID
        , @ClosingPrice
        , LEFT(CONVERT(VARCHAR, @DownloadDate, 112), 8)
    from dbo.Instrument sec
    WHERE sec.Identifier1 = @Identifier1

如果我有这个设置,我的要求之一是如果我无法使用@Identifier1 更新/插入数据库,即没有与Identifier1 匹配的SecurityID,我需要然后更新/插入 使用Identifier2。如果您愿意,可以进行二级比赛。

如何在我的 DAO insertData() 中执行此操作?它是业务逻辑,更喜欢使用 java 代码而不是存储过程,但我很想看看你的例子是如何实现的。

如何返回更新/插入行的结果并决定是否使用第二个标识符更新/插入?

【问题讨论】:

    标签: java sql spring spring-batch microservices


    【解决方案1】:

    对于更新,我会将 where 子句更改为

    WHERE convert(date, @DownloadDate) = convert(date, DownloadDate)
    and (s.Identifier1 = @Identifier1 OR s.Identifier2 = @Identifier2)
    

    对于插入

    WHERE sec.Identifier1 = @Identifier1 OR sec.Identifier2 = @Identifier2
    

    即使我自己没有验证它也应该有效。我假设 identifier1 和 identifier2 的给定值不能匹配 Instrument 表中的两个不同行。

    【讨论】:

    • 我需要identifier1 优先于identifier2OR 条件是这种情况吗?第一次查找是identiier1 ?
    • 是的,这就是 OR 子句的工作方式,但如果标识符 1 和标识符 2 都用于唯一标识同一个 Instrument 实例,则使用哪个并不重要。
    猜你喜欢
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多