0
votes

Est-il correct d'utiliser la même base de baseDatasource, de la même connexion, de l'instruction et de la même pièce dans des méthodes de classe multiples.?

J'ai ci-dessous le code qui utilise des objets statiques de basicdatasource, de connexion SQL, de relevé et de résultatsset. Le code ci-dessous fonctionne bien, mais je veux juste savoir sur la sécurité de ces types de pratiques de codage. Ou comment puis-je optimiser le code ci-dessous afin qu'il puisse devenir plus stable et peut être fiable?

public class Testing {
     static BasicDataSource bds = DBConnection.getInstance().getBds();
     static Connection con = null;
     static PreparedStatement stmt = null;
     static ResultSet rs = null;

    private void show() {
        try {
            con = bds.getConnection();
            stmt = con.prepareStatement("SELECT * FROM users");
            rs = stmt.executeQuery();
            if(rs.next()) {
                System.out.println(rs.getString("firstname") + " " + rs.getString("lastname"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    private void display() {
        try {
            con = bds.getConnection();
            stmt = con.prepareStatement("SELECT * FROM agent_cities");
            rs = stmt.executeQuery();
            while(rs.next()) {
                System.out.println(rs.getString("city_name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    private void add() {
        try {
            con = bds.getConnection();
            stmt = con.prepareStatement("UPDATE users SET firstname = 'shsh' WHERE id = 2");
            stmt.executeUpdate();
            System.out.println("updated successfully");
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        Testing t = new Testing();
        t.show();
        t.display();
        t.add();
    }
}


7 commentaires

En fonction de la complexité d'une application, vous ne devez pas vraiment utiliser de champs pour connexions, relevés et ensembles de résultats (et les champs statiques sont même une plus grande odeur).


Alors quelles sont de meilleures alternatives.


Variables locales bien sûr.


et quelle est la raison pour laquelle


Il empêche la liaison de la vie trop longue, il empêche le partage accidentel des connexions entre plusieurs threads et empêche d'autres types de fuites de ressources.


Ne pensez-vous pas que déclarer des variables locales à chaque fois dans des méthodes distinctes prend beaucoup de temps pour les grands systèmes que j'ai.


Comme je l'ai dit dans mon commentaire initial: cela dépend, mais en général, les avoir statiques est une odeur de code.


3 Réponses :


1
votes

C'est plus ou moins ok si nous parlons d'un programme aussi petit. Mais il n'est pas nécessaire de garder Con, STMT et RS en tant que variables statiques, elles peuvent être déclarées à l'intérieur d'une méthode. De plus, vous devez réécrire d'essayer d'attraper des blocs enfin et de fermer les ressources correctement: xxx

comme prochaine étape, vous pouvez vérifier Essayez avec des ressources Construction pour nettoyer ce code.


3 commentaires

Oui. Mais j'ai beaucoup de grand programme dans lequel je ne peux pas créer de nouveaux objets pour chaque signature de méthode, quelle est votre solution pour un très grand programme contenant de nombreuses signatures de méthodes.


Cela dépend de la pile technique. Si vous avez Java sans printemps / hibernate, vous avez besoin d'une seule source de données (que vous avez déjà statique basicdatasource bds = dbconnection.getinstance (). GetBDS (); ) et fermer les ressources correctement.


Yup je n'utilise pas printemps / hibernate. J'utilise Java Servlets et Maven comme outil de construction avec Eclipse IDE.



1
votes

Meilleure utilisation essais avec ressources forte>. Cela ferme automatiquement la connexion, la déclaration et les Resultset, même lorsqu'une exception a été soulevée ou sur un retour intérieur.

    String sql = "UPDATE users SET firstname = ? WHERE id = ?";
    try (Connection con = bds.getConnection();
            PreparedStatement stmt = con.prepareStatement()) {
        stmt.setString(1, "shsh");
        stmt.setLong(2, 2);
        stmt.executeUpdate();
        System.out.println("updated successfully");
    }

    String sql = "SELECT city_name FROM agent_cities";
    try (Connection con = bds.getConnection();
            PreparedStatement stmt = con.prepareStatement()) {
        try (ResultSet rs = stmt.executeQuery()) {
            while(rs.next()) {
                System.out.println(rs.getString("city_name"));
            }
        }
    }


6 commentaires

Cela ne concerne pas la collecte des ordures mais Nettoyage des ressources tandis que "ressource" désigne toute ressource pas gérée par le collectionneur des ordures de Java. La mémoire de ces objets dans le tas Java n'est qu'un problème mineur.


@Holger vrai, merci. En fait, je suis un peu perdu de trouver les mots corrects ici. Un ancien programmeur C / Fortran de style ancien utiliserait des variables globales telles que proposées.


Le libellé est délicat, comme avec d'autres langages de programmation, tout ce qui a besoin d'une allocation et d'une distribution est une "ressource", qui inclut une mémoire explicitement gérée. Le travail d'esprit d'un programmeur Java est d'exclure la mémoire de la mémoire gérée de l'ensemble des ressources, tout en envisageant une "ressource" comme une "ressource" qui nécessite toujours une fermeture explicite (en tenant compte de essayer (...) comme gestion explicite) et devrait être fermé le plus tôt possible. Ensuite, il est plus facile de comprendre la futilité de la vieille idée de la fermeture des ressources dans un finisseur, comme le collectionneur des ordures seulement se soucie de la mémoire de tas.


Merci. À partir de maintenant, j'utiliserai le bloc d'essai suivant.


@Joopeggen Veuillez regarder la partie de mise à jour en question et partager votre opinion à ce sujet


Cela pourrait être une sorte de fuite de ressources (commentaire de Holger), trop de connexions, déclarations par connexion tenues ouvertes. Mais c'est une spéculation pure. Lorsqu'un champ est écrasé, l'ancien objet n'est pas fermé etcetera. A Piscine de connexion ? Max connexions? Les moteurs de base de données ont des commutateurs de débogage.



0
votes

Vous devez utiliser des ressources traitantes pour éviter tout type de fuite de connexion.

L'exemple suivant lit la première ligne d'un fichier. Il utilise une instance de bufferedreader pour lire les données du fichier. BufferedReader est une ressource qui doit être fermée après la fin du programme avec celui-ci: P>

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}


0 commentaires