package com.battery.device.neware; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.Properties; import java.util.logging.Logger; import javax.sql.DataSource; /** * 由 DriverManager 直连厂商库的极简数据源:只被设备适配器使用,不注册进 Spring, * 因此不参与任何业务事务,Druid 主数据源的回滚不会波及厂商库。 * *
连接复用一条并在查询失败时作废,避免厂商服务端重启后长期持有失效连接; * 厂商库实测按固定 60 秒写库,取数频率远低于连接复用带来的收益门槛。 * *
{@link DataSource} 接口中与连接获取无关的 JDK 样板方法(日志写出器、登录超时、父日志器、
* {@code unwrap} / {@code isWrapperFor})只转发驱动对象,不承载业务语义,因此不单独加方法注释。
*/
public final class SingleConnectionVendorDataSource implements DataSource
{
private final String url;
private final Properties credentials;
private Connection connection;
public SingleConnectionVendorDataSource(String url, String user, String password)
{
if (url == null || url.isBlank()) throw new IllegalArgumentException("vendor jdbc url must not be blank");
this.url = url;
this.credentials = new Properties();
this.credentials.setProperty("user", user == null ? "" : user);
this.credentials.setProperty("password", password == null ? "" : password);
}
/** 返回复用的单条连接,必要时按登记凭据新建;厂商库只读,连接不做写事务。 */
@Override
public synchronized Connection getConnection() throws SQLException
{
if (connection == null || connection.isClosed())
{
connection = DriverManager.getConnection(url, credentials);
}
return connection;
}
/** 按给定账号临时新建一条连接,不复用也不替换已缓存的那条。 */
@Override
public Connection getConnection(String username, String password) throws SQLException
{
return DriverManager.getConnection(url, username, password);
}
/** 作废当前连接,使下一次取数重新建立;用于查询失败后的自愈。 */
public synchronized void invalidate()
{
if (connection == null) return;
try
{
connection.close();
}
catch (SQLException ignored)
{
// 连接已失效,无需处理。
}
finally
{
connection = null;
}
}
@Override
public PrintWriter getLogWriter() throws SQLException
{
return DriverManager.getLogWriter();
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException
{
DriverManager.setLogWriter(out);
}
@Override
public void setLoginTimeout(int seconds) throws SQLException
{
DriverManager.setLoginTimeout(seconds);
}
@Override
public int getLoginTimeout() throws SQLException
{
return DriverManager.getLoginTimeout();
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException
{
return Logger.getLogger("com.battery.device.neware");
}
@Override
public