静态变量与命令行一起使用

时间:2013-11-20 08:24:34

标签: java command-line static cmd arguments

我目前有一个类:

public class SQL {
    private final static String DRIVER_CLASS_NAME = "com.mysql.jdbc.Driver";
    private final static String USERNAME = "secret";
    private final static String PASSWORD = "secret";
    private final static String URL = "jdbc:mysql://secret:3306/secret";

    private static BasicDataSource basicDataSource = null;

    public static void init() {
        basicDataSource = new BasicDataSource();
        basicDataSource.setDriverClassName(DRIVER_CLASS_NAME);
        basicDataSource.setUrl(URL);
        basicDataSource.setUsername(USERNAME);
        basicDataSource.setPassword(PASSWORD);
        basicDataSource.setValidationQuery("SELECT 1;");
        basicDataSource.setTestOnBorrow(true);
        basicDataSource.setTestOnReturn(true);
        basicDataSource.setTestWhileIdle(false);
    }

    public static void shutdown() {
        try {
            basicDataSource.close();
        } catch (SQLException ex) {
            Logger.getLogger(SQL.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static Connection getConnection() {
        if (basicDataSource == null) {
            init();
        }
        try {
            return basicDataSource.getConnection();
        } catch (SQLException ex) {
            Logger.getLogger(SQL.class.getName()).log(Level.SEVERE, null, ex);
            throw new IllegalStateException("bf4.sql.SQL.getConnection: No connection could be made: " + ex.getMessage());
        }
    }
}

我想使用命令行参数(我的main方法位于其他地方)来设置static变量,并使用.bat文件调用该变量以进行不同的配置。

现在我想知道:对此最好的解决方案是什么?

我自己也想过一些解决方案:

  • 创建static变量non-final,然后在调用main()之后直接设置它们,然后再执行程序,因此也可以在调用之前调用SQL变量staticnon-final课程。

  • 制作static变量Scanner,然后尝试通过System.in上的{{1}}在{{1}}块中设置它们。

我正在考虑使用解决方案#1,但它是否有任何挫折。我想听听它的评论。

2 个答案:

答案 0 :(得分:1)

首先,我想通知您,您的班级不是线程安全的。我建议你不要在SQL类中保留任何静态变量,因为它们实际上不是static逻辑上的。

创建类似

的类
class SQLConfiguration{

    private String userName;
    ....
}

现在可以从任何源读取这个SQLConfiguration实例,无论是属性文件还是xml或扫描程序,您只需创建它的实例,并在初始化时将其传递给SQL类。

class SQL{

    public static synchronized init(SQLConfiguration sqlConfiguration){
        //init in a thread safe manner
    }

}

我认为实现您的要求的最佳方式是Multiton design pattern

public class SQLMultiton{
    private static final Map<Object, SQLMultiton> instances = new HashMap<Object, SQLMultiton>();

    private SQLMultiton() {
        // no explicit implementation
    }

    public static synchronized SQLMultiton getInstance(SQLConfiguration key) {

        // Our "per key" singleton
        SQLMultiton instance = instances.get(key);

        if (instance == null) {
            // Lazily create instance
            instance = new SQLMultiton();
            instance.init();  
            // Add it to map   
            instances.put(key, instance);
        }

        return instance;
    }

    // other fields and methods ...
}

答案 1 :(得分:0)

您可以使用属性文件

Properties prop = new Properties();

    try {
           //load a properties file
        prop.load(new FileInputStream("config.properties"));

           //get the property value and print it out
            System.out.println(prop.getProperty("database"));
        System.out.println(prop.getProperty("dbuser"));
        System.out.println(prop.getProperty("dbpassword"));

    } catch (IOException ex) {
        ex.printStackTrace();
    }

当然在您的情况下,您希望将属性文件的值设置为您的变量(这将是非最终的)