这是有效的Singleton实现吗?

问题描述 投票:-1回答:2
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;
    }   
}

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

java jdbc singleton database-connection
2个回答
1
投票

您返回的stmt变量始终为null。您可能在某处忘记了以下声明:

stmt = Singleton_stmt;

即使解决了该问题,使用单个Statement实例也是错误的。

Statement的Javadoc说:

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

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


0
投票

此代码有很多很多错误:

  1. 这是越野车;您正在分配给Singleton_stmt,并返回未设置的stmt
  2. 它忽略异常。不要那样做应该将此方法声明为throws SQLException,这是最好的解决方案–然后,您根本不需要try / catch。如果您坚持不应该这样做的设计错误,请至少将其放在catch块中:throw new RuntimeException("Uncaught", e);
  3. 它不遵守Java约定。它是singletonStmt,而不是Singleton_stmt
  4. SQL无法以这种方式工作;仅当变量为零时才可以使用纯简jane语句,例如,除了单个长且硬编码的SQL字符串外,没有其他要放入查询中的内容。诸如stmt.executeQuery("SELECT * FROM users WHERE username = " + username)之类的漏洞是安全漏洞,将使您的服务器心跳加速。正确的解决方案是使用PreparedStatement。具有仅允许您使用语句的数据库连接工具是危险的,而且很糟糕。
  5. 连接必须关闭;该代码永远不会这样做,或者如果调用者这样做,则该代码将永久断开(连接不是null,而是无效的,并且此代码将永远无法重做)。
  6. 不需要Class.forName行;去掉它。或者,如果要确保在编译时出现错误(如果mysql jdbc驱动程序不在类路径中),请写Class.forName(com.mysql.jdbc.Driver.class.getName())。 (不推荐)。
  7. 这不是您制作单身人士的方式;如果2个线程同时调用getStatement方法,则可能会创建2个连接和2条语句,并且任意一个“获胜”并最终设置了字段。如果需要,可以使用双重锁定。但是,这是无关紧要的:您不能具有“单连接”。连接不能那样工作。连接在多线程环境中也不起作用。每个都需要自己的连接。使用连接池,请参阅第9点。
  8. 不建议使用原始JDBC与数据库对话。您可能应该使用JDBI之类的东西。
  9. [如果您想在每次需要连接时都尽量避免创建连接(我建议您一开始就不要这样做;只要您需要与数据库对话,就建立连接,做您的事情,并再次关闭它。如果您执行大量的数据库工作,这可能会变得效率低下,但要等待这种效率低下才能真正显示出来;现代服务器和数据库可以按原样处理大量连接流量)–使用诸如[C0 ]。
  10. 此类的专有名称为HikariCP。取消大写首字母缩写(在Java约定中为JdbcConnection。不是DvdPlayer)。
© www.soinside.com 2019 - 2024. All rights reserved.