Если я использую одноэлементный класс для соединения с базой данных, может ли один пользователь закрыть соединение для всех? - PullRequest
16 голосов
/ 04 июля 2011

Я написал одноэлементный класс для получения соединения с базой данных.

Теперь мой вопрос таков: предположим, что к приложению обращаются 100 пользователей.Если один пользователь закрывает соединение, для остальных 99 пользователей соединение будет закрыто или нет?

Это мой пример программы, которая использует одноэлементный класс для получения соединения с базой данных:

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 .
    }
}

Пожалуйста, ведите меня.

Ответы [ 5 ]

24 голосов
/ 04 июля 2011

Пока вы не вернете тот же экземпляр Connection при вызове getConnection(), вам не о чем беспокоиться.Каждый вызывающий затем получит свой экземпляр.На данный момент вы создаете новое соединение при каждом вызове getConnection() и, таким образом, не возвращаете какую-либо статическую переменную или переменную экземпляра.Так что это безопасно.

Однако такой подход неуклюж.Это не обязательно должен быть синглтон.Вспомогательный / служебный класс также отлично подойдет.Или, если вы хотите немного больше абстракции, менеджер соединений возвращается абстрактной фабрикой.Я бы изменил его, чтобы получить источник данных только один раз во время инициализации класса, а не каждый раз в 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();
    }

}

, который должен использоваться следующим образом в соответствии с обычной идиомой 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;
}

См. Также:

2 голосов
/ 21 марта 2013
package es.sm2.conexion;

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

public class ConexionTest {

    static Connection getConnection() throws Exception {

        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();
        Connection conn = DriverManager.getConnection(url + dbName, userName,password);

        return conn;
    }
}

Для закрытия подключения

public static void closeConnection(Connection conn) {

        try {

            conn.close();

        } catch (SQLException e) {

        }

    }

Для вызова подключения:

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);

        }
    }
}
1 голос
/ 29 апреля 2016

Ниже приведен рабочий и протестированный шаблон Singleton для 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;
    }

При получении соединения в любом классе просто используйте строку ниже

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

Надеюсь, это поможет:)

0 голосов
/ 02 марта 2019

Отличный пост, Фархангдон!Я, однако, нашел это немного неприятным, потому что, как только вы закроете соединение, у вас не будет другого способа начать новое.Небольшая хитрость решит эту проблему:

Замените if(con==null) на if(con==null || con.isClosed())

0 голосов
/ 26 февраля 2013
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;

    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...