Problèmes de sécurité des threads de la connexion Java à MySQL
phpcn_u1582
phpcn_u1582 2017-06-16 09:19:30
0
4
1139

J'ai cherché sur Internet pendant N jours et il n'y a presque pas de solutions thread-safe. Le même problème peut être facilement résolu avec Redis. Je l'ai remplacé par une classe d'outils que j'ai trouvée en ligne. Veuillez m'aider à le modifier ou me donner des conseils. .Mon idée actuelle est d'ajouter le mot-clé synchronisé, mais j'ai toujours l'impression qu'il y a un problème. Merci beaucoup !

class MySQLUtil {
  
  private static final String driver = "com.mysql.jdbc.Driver";
  private static final String url = "jdbc:mysql://192.168.31.103:3306/";
  private static final String character = "?useUnicode=true&characterEncoding=utf8";
  private static final String ssl = "&useSSL=false";
  private static final String user = "root";
  private static final String password = "111111";
  private static Connection connection = null;
  private static Statement statement = null;
  private static PreparedStatement ps = null;
  private static ResultSet rs = null;
  
  boolean TestConnection(String db) {
    try {
      Class.forName(driver);
      Connection connection = DriverManager.getConnection(url + db + character + ssl, user, password);
      
      if (!connection.isClosed()) {
        CloseConnection();
        return true;
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return false;
  }
  
  synchronized private void ConnectToDB(String db) {
    try {
      Class.forName(driver);
      Connection connection = DriverManager.getConnection(url + db + character + ssl, user, password);
      
      if (!connection.isClosed()) {
        statement = connection.createStatement();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  synchronized private void CloseConnection() {
    try {
      if (rs != null) {
        rs.close();
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
    
    try {
      if (ps != null) {
        ps.close();
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
    
    try {
      if (connection != null) {
        connection.close();
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  
  synchronized void ModifyData(String db, String data) {
    
    ConnectToDB(db);
    try {
      statement.execute(data);
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      CloseConnection();
    }
    
  }
  
  synchronized List ReadData(String db, String data) {
    List<String> list = new ArrayList<>();
    int count;
    ConnectToDB(db);
    
    try {
      rs = statement.executeQuery(data);
      ResultSetMetaData rsmd;
      rsmd = rs.getMetaData();
      count = rsmd.getColumnCount();
      
      while (rs.next()) {
        for (int i = 1; i <= count; i++) {
          String label = rsmd.getColumnLabel(i);
          list.add(label);
          String value = rs.getString(i);
          list.add(value);
        }
      }
      
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      CloseConnection();
    }
    return list;
  }
}
phpcn_u1582
phpcn_u1582

répondre à tous(4)
给我你的怀抱

Afin de garantir que les données entre les connexions sont indépendantes (non partagées), je suppose que vous souhaitez implémenter un Pool de connexions :

ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass( "org.postgresql.Driver" );
cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" );
cpds.setUser("caiyongji");
cpds.setPassword("test-password");

cpds.setMinPoolSize(5);
cpds.setAcquireIncrement(5);
cpds.setMaxPoolSize(20);
某草草

Après une légère modification, c'est peut-être mieux. Il est recommandé d'écouter le copain ci-dessus et d'utiliser un pool de connexions à une base de données mature. Il n'est pas nécessaire de réinventer la roue

.
  • Utilisez singleton pour garantir le caractère unique de la connexion à la base de données

  • Modifier l'utilisation des synchronizedmots-clés pour améliorer l'efficacité

  • Ajoutez des volatile mots-clés pour améliorer la stabilité

package com.singleton;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <b>功能:</b><br>
 * <br>
 * <b>完整路径:</b> com.singleton.MySQLUtil <br>
 * <b>创建日期:</b> 2017年6月15日 上午10:42:49 <br>
 * 
 * @author pfyangf<br>
 * @version 1.0
 */
class MySQLUtil {
    
    private MySQLUtil(){}
    
    private static volatile Connection connection = null;

    private static final String driver = "com.mysql.jdbc.Driver";
    private static final String url = "jdbc:mysql://192.168.31.103:3306/";
    private static final String character = "?useUnicode=true&characterEncoding=utf8";
    private static final String ssl = "&useSSL=false";
    private static final String user = "axtest";
    private static final String password = "axtest123";
    private static Statement statement = null;
    private static PreparedStatement ps = null;
    private static ResultSet rs = null;
    
    public static void main(String[] args) {
        /*Connection newConnection;
        try {
            newConnection = MySQLUtil.connectToDB("xxx");
            System.out.println(newConnection.isClosed());
        } catch (Exception e) {
            //TODO 异常处理
            e.printStackTrace();
        }*/
        try {
            List<Map<String, Object>> data = MySQLUtil.readData("xxx", "select now() from dual");
            System.out.println(data.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    boolean TestConnection(String db) {
        try {
            Class.forName(driver);
            Connection connection = DriverManager.getConnection(url + db + character + ssl, user, password);

            if (!connection.isClosed()) {
                CloseConnection();
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * <b>功能:获取DB连接</b><br>
     * <br>
     * @Author:pfyangf , 2017年6月15日
     * @param db
     * @return
     * @throws Exception Connection
     **/
    public static Connection connectToDB(String db) throws Exception {
        if(null == connection){
            synchronized (MySQLUtil.class) {
                if(null == connection){
                    Class.forName(driver);
                    connection = DriverManager.getConnection(url + db + character + ssl, user, password);
                    statement = connection.createStatement();
                }
            }
        }
        return connection;
    }

    private static void CloseConnection() {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        try {
            if (ps != null) {
                ps.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        try {
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void ModifyData(String db, String data) throws Exception {

        connectToDB(db);
        try {
            statement.execute(data);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            CloseConnection();
        }

    }

    public static List<Map<String, Object>> readData(String db, String sql) throws Exception {
        List<Map<String, Object>> list = new ArrayList<>();
        int count;
        connectToDB(db);

        try {
            rs = statement.executeQuery(sql);
            ResultSetMetaData rsmd;
            rsmd = rs.getMetaData();
            count = rsmd.getColumnCount();

            while (rs.next()) {
                Map<String, Object> map = null;
                for (int i = 1; i <= count; i++) {
                    map = new HashMap<>();
                    map.put(rsmd.getColumnLabel(i), rs.getString(i));
                    list.add(map);
                }
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            CloseConnection();
        }
        return list;
    }
}
给我你的怀抱

Pas besoin de synchroniser, plusieurs connexions n'ont pas d'importance.
La base de données possède son propre verrou.
Vous pouvez également utiliser directement le pool de connexions.

滿天的星座

Merci pour vos réponses. J'ai un peu modifié le code. S'il vous plaît, aidez-moi à voir s'il y a un problème. La raison principale est que je n'ai jamais utilisé Java. Ma façon de le gérer est la suivante : à l'exception des constantes, il n'y a pas de classe. variables membres. Tous les paramètres et la valeur de retour sont transmis et toutes les variables sont déclarées dans la méthode

class MySQLUtil {
    
    private static final String driver = "com.mysql.jdbc.Driver";
    private static final String url = "jdbc:mysql://192.168.31.103:3306/";
    private static final String character = "?useUnicode=true&characterEncoding=utf8";
    private static final String ssl = "&useSSL=false";
    private static final String user = "root";
    private static final String password = "111111";
    
    boolean TestConnection(String db) {
        try {
            Class.forName(driver);
            Connection connection = DriverManager.getConnection(url + db + character + ssl, user, password);
            
            if (!connection.isClosed()) {
                CloseConnection(connection, null);
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    
    private List ConnectToDB(String db) {
        
        List<Object> list = new ArrayList<>();
        
        try {
            Class.forName(driver);
            Connection connection = DriverManager.getConnection(url + db + character + ssl, user, password);
            
            if (!connection.isClosed()) {
                Statement statement = connection.createStatement();
                list.add(1, connection);
                list.add(2, statement);
                return list;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return list;
    }
    
    private void CloseConnection(Connection connection, ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        try {
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    
    public void ModifyData(String db, String data) {
        
        List list = ConnectToDB(db);
        Connection connection = (Connection) list.get(1);
        Statement statement = (Statement) list.get(2);
        
        try {
            statement.execute(data);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            CloseConnection(connection, null);
        }
        
    }
    
    public List ReadData(String db, String data) {
        List<String> result = new ArrayList<>();
        ResultSet rs = null;
        int count;
        
        List list1 = ConnectToDB(db);
        Connection connection = (Connection) list1.get(1);
        Statement statement = (Statement) list1.get(2);
        
        try {
            rs = statement.executeQuery(data);
            ResultSetMetaData rsmd;
            rsmd = rs.getMetaData();
            count = rsmd.getColumnCount();
            
            while (rs.next()) {
                for (int i = 1; i <= count; i++) {
                    String label = rsmd.getColumnLabel(i);
                    result.add(label);
                    String value = rs.getString(i);
                    result.add(value);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            CloseConnection(connection, rs);
        }
        return result;
    }
}
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal