package com.infoobjects.emsmaria.connection.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JDBCConnection {
private static Statement Singleton_stmt = null;
private static Connection con = null;
public static Statement getStatement() {
Statement stmt = null;
try {
if (Singleton_stmt == null && con == null) {
Class.forName("com.mysql.jdbc.Driver");
con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/EMSCMS", "root", "");
Singleton_stmt = con.createStatement();
}
} catch (Exception e) {
}
return stmt;
}
}
这是有效的单例实现,以获取不同类中的语句吗?
您返回的stmt
变量始终为null
。您可能在某处忘记了以下声明:
stmt = Singleton_stmt;
即使解决了该问题,使用单个Statement
实例也是错误的。
Statement
的Javadoc说:
如果一个ResultSet对象的读取与另一个的读取交错,则每个都必须由不同的Statement对象生成。
这意味着,如果您的代码可以同时执行SQL语句,则不能使用单个Statement
实例。
此代码有很多很多错误:
Singleton_stmt
,并返回未设置的stmt
。throws SQLException
,这是最好的解决方案–然后,您根本不需要try / catch。如果您坚持不应该这样做的设计错误,请至少将其放在catch块中:throw new RuntimeException("Uncaught", e);
。singletonStmt
,而不是Singleton_stmt
。stmt.executeQuery("SELECT * FROM users WHERE username = " + username)
之类的漏洞是安全漏洞,将使您的服务器心跳加速。正确的解决方案是使用PreparedStatement
。具有仅允许您使用语句的数据库连接工具是危险的,而且很糟糕。Class.forName
行;去掉它。或者,如果要确保在编译时出现错误(如果mysql jdbc驱动程序不在类路径中),请写Class.forName(com.mysql.jdbc.Driver.class.getName())
。 (不推荐)。getStatement
方法,则可能会创建2个连接和2条语句,并且任意一个“获胜”并最终设置了字段。如果需要,可以使用双重锁定。但是,这是无关紧要的:您不能具有“单连接”。连接不能那样工作。连接在多线程环境中也不起作用。每个都需要自己的连接。使用连接池,请参阅第9点。JdbcConnection
。不是DvdPlayer
)。