Java 如果我对数据库连接使用单例类,一个用户可以为所有人关闭连接吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6567839/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 07:47:48  来源:igfitidea点击:

If I use a singleton class for a database connection, can one user close the connection for everybody?

javadesign-patternsjdbc

提问by hanhu

I wrote a singleton class for obtaining a database connection.

我写了一个单例类来获取数据库连接。

Now my question is this: assume that there are 100 users accessing the application. If one user closes the connection, for the other 99 users will the connection be closed or not?

现在我的问题是:假设有 100 个用户访问该应用程序。如果一个用户关闭连接,其他 99 个用户的连接是否会关闭?

This is my sample program which uses a singleton class for getting a database connection:

这是我的示例程序,它使用单例类来获取数据库连接:

public class GetConnection {

    private GetConnection() { }

    public Connection getConnection() {
        Context ctx = new InitialContext();
        DataSource ds = ctx.lookup("jndifordbconc");
        Connection con = ds.getConnection();
        return con;
    }

    public static  GetConnection   getInstancetoGetConnection () {
        // which gives GetConnection class instance to call getConnection() on this .
    }
}

Please guide me.

请指导我。

采纳答案by BalusC

As long as you don't return the sameConnectioninstance on getConnection()call, then there's nothing to worry about. Every caller will then get its own instance. As far now you're creating a brand new connection on every getConnection()call and thus not returning some static or instance variable. So it's safe.

只要您在调用时不返回同一个Connection实例getConnection(),就没有什么可担心的。每个调用者都将获得自己的实例。到目前为止,您在每次getConnection()调用时都创建了一个全新的连接,因此不会返回一些静态或实例变量。所以是安全的。

However, this approach is clumsy. It doesn't need to be a singleton. A helper/utility class is also perfectly fine. Or if you want a bit more abstraction, a connection manager returned by an abstract factory. I'd only change it to obtain the datasource just once during class initialization instead of everytime in getConnection(). It's the same instance everytime anyway. Keep it cheap. Here's a basic kickoff example:

然而,这种方法是笨拙的。它不需要是单身人士。助手/实用程序类也非常好。或者,如果您想要更多的抽象,抽象工厂返回的连接管理器。我只会在类初始化期间更改它以获取数据源一次,而不是每次都在getConnection(). 反正每次都是同一个实例。保持便宜。这是一个基本的开球示例:

public class Database {

    private static DataSource dataSource;

    static {
        try {
            dataSource = new InitialContext().lookup("jndifordbconc");
        }
        catch (NamingException e) { 
            throw new ExceptionInInitializerError("'jndifordbconc' not found in JNDI", e);
        }
    }

    public static Connection getConnection() {
        return dataSource.getConnection();
    }

}

which is to be used as follows according the normal JDBC idiom.

根据正常的 JDBC 习惯用法,将按如下方式使用。

public List<Entity> list() throws SQLException {
    List<Entity> entities = new ArrayList<Entity>();

    try (
        Connection connection = Database.getConnection();
        PreparedStatement statement = connection.prepareStatement("SELECT id, foo, bar FROM entity");
        ResultSet resultSet = statement.executeQuery();
    ) {
        while (resultSet.next()) {
            Entity entity = new Entity();
            entity.setId(resultSet.getLong("id"));
            entity.setFoo(resultSet.getString("foo"));
            entity.setBar(resultSet.getString("bar"));
            entities.add(entity);
        }
    }

    return entities;
}

See also:

也可以看看:

回答by gayan rangana

import java.sql.Connection;
import java.sql.DriverManager;

public class sql11 {

    static Connection getConnection() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/ics", "root", "077");
        return c;

    }
}

回答by PauRibes

package es.sm2.conexion;

    import java.sql.Connection;
    import java.sql.DriverManager;

    public class ConexionTest {
        private static Connection conn = null;

        static Connection getConnection() throws Exception {
            if (conn == null) {
                String url = "jdbc:mysql://localhost:3306/";
                String dbName = "test";
                String driver = "com.mysql.jdbc.Driver";
                String userName = "userparatest";
                String password = "userparatest";

                Class.forName(driver).newInstance();
                conn = DriverManager.getConnection(url + dbName, userName, password);
            }

            return conn;
        }
    }

To close Connection

关闭连接

public static void closeConnection(Connection conn) {

        try {

            conn.close();

        } catch (SQLException e) {

        }

    }

To call to the connection:

调用连接:

package conexion.uno;

import java.sql.*;

import es.sm2.conexion.ConexionTest;

public class LLamadorConexion {

    public void llamada() {
        Connection conn = null;
        PreparedStatement statement = null;
        ResultSet resultado = null;
        String query = "SELECT * FROM empleados";

        try {
            conn = ConexionTest.getConnection();
            statement = conn.prepareStatement(query);
            resultado = statement.executeQuery();

            while (resultado.next()) {
                System.out.println(resultado.getString(1) + "\t" + resultado.getString(2) + "\t" + resultado.getString(3) + "\t" );
            }
        } 
        catch (Exception e) {
            System.err.println("El porque del cascar: " + e.getMessage());
        } 
        finally {
            ConexionTest.closeConnection(conn);

        }
    }
}

回答by farhangdon

Below code is a working and tested Singleton Pattern for Java.

下面的代码是一个有效且经过测试的 Java 单例模式。

public class Database {

    private static Database dbIsntance;
    private static Connection con ;
    private static Statement stmt;


    private Database() {
      // private constructor //
    }

    public static Database getInstance(){
    if(dbIsntance==null){
        dbIsntance= new Database();
    }
    return dbIsntance;
    }

    public  Connection getConnection(){

        if(con==null){
            try {
                String host = "jdbc:derby://localhost:1527/yourdatabasename";
                String username = "yourusername";
                String password = "yourpassword";
                con = DriverManager.getConnection( host, username, password );
            } catch (SQLException ex) {
                Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        return con;
    }

While getting Connection in any Class simply use below line

在任何类中获取连接时,只需使用下面的行

Connection con = Database.getInstance().getConnection();

Hope it may help :)

希望它可以帮助:)

回答by Mr. Demirel

Great post, farhangdon! I, however, found it a little troublesome because once you close the connection, you have no other way to start a new one. A little trick will solve it though:

伟大的职位,farhangdon!但是,我发现它有点麻烦,因为一旦关闭连接,就没有其他方法可以开始新的连接。一个小技巧可以解决它:

Replace if(con==null)with if(con==null || con.isClosed())

替换if(con==null)if(con==null || con.isClosed())