![](/img/trans.png)
[英]How to configure EclipseLink to use HikariCP as its connection pool
[英]How to use a HikariCP connection pool with prepared statements?
我正在开发一个 Spring Boot web (REST) 应用程序,我需要在其中处理许多请求。 因此我希望我的应用程序能够同时处理请求。 由于 Spring 引导 REST 服务是开箱即用的并发可用,我只需要使 (PostgreSQL) 数据库访问并发访问。 为此,我正在使用 HikariCP 数据源。
由于我的很多语句都是准备好的语句,因此我将它们收集在一种调用pstmt = connection.prepareStatement("SQLCODE");
的方法中。 每个语句一次。 当处理来自 REST 服务的用户交互时,这些准备好的语句将用于各种方法。
现在,当我使用 HikariCP 时,我不能再这样做了,可以吗? 当我准备一个语句时,这个语句绑定到一个连接。 如果我然后尝试同时访问它,我不能,因为连接未共享。
我错过了什么吗? 我该如何解决这个问题? 我是否需要从池中检索连接、在本地准备语句、执行查询并关闭连接? 如果是这样,那么使用准备好的语句有什么意义(除了防止 SQL 注入)?
我知道这些语句是在 PostreSQL 端缓存的。 那么保留所有准备好的语句都准备好的方法是个好主意吗? 将它们发送到数据库缓存。 然后再次在本地创建相同的语句。 这样,人们仍然可以利用数据库的缓存可能性。 但另一方面,这将是非常丑陋的代码。
我正在使用 Spring:5.3.10、Java:11、PostgreSQL:14.0
@RestController
public class RESTController {
/** The database controller. */
private DBController dbc;
/** The data source object serving as a connection pool. */
private HikariDataSource ds;
/** The logger object for this class. */
private static Logger logger = LoggerFactory.getLogger(RESTController.class);
public RESTController(DBController dbc, Config config) {
this.dbc = dbc;
// Create the database
if (!this.dbc.createDB(config)) {
logger.error("Couldn't create the database. The service will now exit.");
Runtime.getRuntime().halt(1);
}
// Create a connection pool
ds = new HikariDataSource();
ds.setJdbcUrl(config.getUrl());
ds.setUsername(config.getUser());
ds.setPassword(config.getPassword());
ds.addDataSourceProperty("cachePrepStmts", "true");
ds.addDataSourceProperty("prepStmtCacheSize", "250");
ds.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
// Create the necessary tables
if (!this.dbc.createTables(ds)) {
logger.error("Couldn't create the tables. The service will now exit.");
ds.close();
Runtime.getRuntime().halt(1);
}
// Prepare SQL statements
if (!this.dbc.prepareStatements(ds)) {
logger.error("Couldn't prepare the SQL statements. The service will now exit.");
ds.close();
Runtime.getRuntime().halt(1);
}
}
@PostMapping("/ID")
public ResponseEntity<String> createNewDomain(@RequestParam(name = "name", required = true) String name) {
// Do stuff ...
}
// [...]
}
@Component
public class DBController {
/** The logger object for this class. */
private static Logger logger = LoggerFactory.getLogger(DBController.class);
// Prepared Statements
private PreparedStatement stmt1, stmt2, stmt3;
public boolean prepareStatements(HikariDataSource ds) {
try {
// Get connection from the pool
Connection c = ds.getConnection();
// Prepare all the statements
stmt1 = c.prepareStatement("SQLCODE");
stmt2 = c.prepareStatement("SQLCODE1");
stmt2 = c.prepareStatement("SQLCODE1");
// [...]
} catch (SQLException e) {
logger.debug("Could not prepare the SQL statements: " + e.getMessage());
return false;
}
logger.debug("Successfully prepared the SQL statements.");
return true;
}
public boolean m1(int i) {
stmt1.setInt(i);
ResultSet rs = stmt1.executeQuery();
}
public boolean m2(int j) {
stmt1.setInt(j);
ResultSet rs = stmt1.executeQuery();
}
public boolean m3(String a) {
stmt2.setString(a);
ResultSet rs = stmt2.executeQuery();
}
// [...]
}
提前致谢。
请阅读 https 上的声明缓存部分://github.com/brettwoldridge/HikariCP
许多连接池,包括 Apache DBCP、Vibur、c3p0 等都提供 PreparedStatement 缓存。 HikariCP 没有。 为什么?
所以它不缓存。 如果您阅读了解释,也许您会决定不需要它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.