[英]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.