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 主数据源的回滚不会波及厂商库。
|
*
|
* <p>连接复用一条并在查询失败时作废,避免厂商服务端重启后长期持有失效连接;
|
* 厂商库实测按固定 60 秒写库,取数频率远低于连接复用带来的收益门槛。
|
*
|
* <p>{@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 <T> T unwrap(Class<T> iface) throws SQLException
|
{
|
if (iface.isInstance(this)) return iface.cast(this);
|
throw new SQLFeatureNotSupportedException("不支持解包为 " + iface);
|
}
|
|
@Override
|
public boolean isWrapperFor(Class<?> iface)
|
{
|
return iface.isInstance(this);
|
}
|
}
|