简体   繁体   English

如何通过自动生成的 PK 使用 Redisson 直写缓存策略

[英]How can I use Redisson Write-through caching strategy with an auto-generated PK

I am planning to use Redis with Redisson as a caching layer between my Java app and a PostgreSQL DB.我计划使用 Redis 和 Redisson 作为我的 Java 应用程序和 PostgreSQL DB 之间的缓存层。 I have a table called Nodes looking like this:我有一个名为 Nodes 的表,如下所示:

CREATE TABLE nodes
(
node_id bigint GENERATED BY DEFAULT AS IDENTITY(START WITH 1 INCREMENT BY 1),
node_name varchar(100) NOT NULL,
PRIMARY KEY (node_id)
)

I want to use Redisson RMap persistence to cache this structure.我想使用Redisson RMap 持久性来缓存这个结构。 My goal is to have an rmap looking like this:我的目标是让 rmap 看起来像这样:

Rmap<Integer, Node> 

where the key is the PK, and the value is the node itself.其中键是PK,值是节点本身。

I want to use read-through and write-trhough strategies for caching this Rmap, by using the MapLoader and the MapWriter.我想通过使用 MapLoader 和 MapWriter 使用 read-through 和 write-trhough 策略来缓存这个 Rmap。

Then, I want to have a Java method which should create and persist a node.然后,我想要一个 Java 方法,它应该创建和持久化一个节点。

public void createNode(String nodeName) {
  Node node = new Node();
  node.setName(nodeName);

  // how can I put elements in the rmap since, 
  // the PK will be available after the INSERT statement will run?
  rmap.put(?, node);
}

And here comes the problem.问题来了。 Since the PK is auto-generated from Postgres, how can I use the RMapWriter to insert a node, since, for putting elements in the RMap I need the key, which I don't have until the insert statement will run?由于 PK 是从 Postgres 自动生成的,我如何使用 RMapWriter 插入节点,因为为了将元素放入 RMap 我需要密钥,在插入语句运行之前我没有该密钥?

You can get generated Keys from postgres using prepared Statement.您可以使用准备好的语句从 postgres 获取生成的密钥。

   ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) ;
   ps.execute();
   ResultSet rs = ps.getGeneratedKeys();

I'm aware this is an older post but answering because I came across the same issue.我知道这是一篇较旧的帖子,但回答是因为我遇到了同样的问题。 For me, the solution was to use the MapLoader rather than the MapWriter , using a CallableStatement (rather than a PreparedStatement ) backed by a stored procedure in the SELECT_or_INSERTthenSELECT mould.对我来说,解决方案是使用MapLoader而不是MapWriter ,使用由SELECT_or_INSERTthenSELECT模具中的存储过程支持的CallableStatement (而不是PreparedStatement )。

    @Override
    public Integer load(Node node) {
        // second parameter to the procedure is an OUTPUT param
        try(CallableStatement callableStatement = conn.prepareCall("{CALL INSERT_or_SELECT_THEN_INSERT (?, ?)}"))
        {
            callableStatement.setString(1, node.getName());
            callableStatement.registerOutParameter(2, java.sql.Types.BIGINT);
            callableStatement.executeUpdate();
    
            System.out.println("Debug nodeName: " + node.getName() + ", id: " + callableStatement.getLong(2));
            return callableStatement.getLong(2);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }

Now you can just call map.get(node) and the load() override will be called if the node is not in the map.现在你可以调用map.get(node)如果节点不在 map 中,将调用load()覆盖。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM