Java 这是一个有效的单例实现吗?

Java 这是一个有效的单例实现吗?,java,jdbc,singleton,database-connection,Java,Jdbc,Singleton,Database Connection,这是在不同类中获取语句的有效单例实现吗?返回的stmt变量总是null。您可能忘记了以下语句: package com.infoobjects.emsmaria.connection.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; public class JDBCConnection { private static Statement Singlet

这是在不同类中获取语句的有效单例实现吗?

返回的
stmt
变量总是
null
。您可能忘记了以下语句:

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;
    }   
}
即使在解决了这个问题之后,使用单个
语句
实例也是错误的

语句的Javadoc说:

如果一个ResultSet对象的读取与另一个对象的读取交错,则每个对象都必须由不同的语句对象生成


这意味着,如果您的代码可以同时执行SQL语句,则不能使用单个
语句
实例。

此代码有很多错误:

  • 它是马车;您正在分配给
    Singleton\u stmt
    ,并返回未设置的
    stmt
  • 它忽略了例外情况。不要那样做。这个方法应该声明为
    抛出SQLException
    ,这是最好的解决方案,这样您就根本不需要try/catch了。如果您坚持认为这个设计错误是不应该的,那么至少把它放在catch块中:
    抛出新的RuntimeException(“Uncaught”,e)
  • 它不遵守java约定。它是
    singletonStmt
    ,而不是
    singletonStmt
  • SQL不是这样工作的;只有在零变量的情况下,才能使用纯jane语句,如中所示,除了一个长的硬编码SQL字符串外,查询中没有其他内容。类似于
    stmt.executeQuery(“SELECT*FROM users WHERE username=“+username”)
    的内容是一种安全漏洞,会让您的服务器在短时间内遭到黑客攻击。正确的解决方案是使用
    PreparedStatement
    ;拥有一个只允许您使用语句的DB连接工具是危险的,也是不可靠的
  • 必须关闭连接;这段代码从来没有这样做过,或者如果调用方这样做了,那么这段代码就会永久中断(连接不是空的,而是无效的,并且这段代码永远不会重新创建它)
  • 不需要
    类.forName
    行;移除它。或者,如果要确保在mysql jdbc驱动程序不在类路径上时在编译时出错,请编写
    Class.forName(com.mysql.jdbc.driver.Class.getName())
    。(不推荐)
  • 这不是你创造单身的方式;如果两个线程同时调用
    getStatement
    方法,则可能会创建两个连接和两个语句,并且任意一个线程“获胜”并最终设置字段。如果必须,可以使用双重锁定。然而,这是不相关的:你不能有一个“单例连接”;连接不是这样工作的。连接在多线程环境中也不起作用。每个都需要自己的连接。使用连接池,请参见第9点
  • 不建议使用原始JDBC与DBs对话。你可能应该使用类似的东西
  • 如果您希望优化,而不是在每次需要时创建连接(我建议你开始时不要这样做;任何时候你需要与数据库交谈,建立连接,完成你的事情,然后再次关闭它。如果你做了大量的数据库工作,这可能会变得效率低下,但要等到这种效率低下真正显现出来;现代服务器和数据库可以处理相当多的连接流量)–使用游泳池,例如
  • 此类的正确名称应为
    JdbcConnection
    。首字母缩略词不大写(按照java惯例,它是
    DvdPlayer
    。而不是
    DvdPlayer

  • 您当前的方法(getStatement)将始终返回null。
    stmt
    将始终为null,因此
    getStatement()
    也将始终返回null。一点也不。它有很多缺陷,例如吞没任何异常、不必要的强制转换和“单例语句”的概念.我投票结束这个问题,因为它应该迁移到
    stmt = Singleton_stmt;