Połączenie z bazą.

0

Witam.

Chciałem przedstawić sposób w jaki zamierzam się łączyć z bazą do oceny. Wszystko niby działa, ale wiem że coś mogę zrobić dużo lepiej, a więc prosiłbym o jakies sugestie. Wzorowałem się na szablonie do obsługi db napisany w pewnym temacie przez użytkownika Koziołka.

package hotel;


import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

/*
 * Klasa odpowiedzialna za obsługę bazy
**/
public class DBConnector {
    
    private static Connection CON;
    
    public DBConnector() {
        
    }
    
    public static void init(Properties p) {
        
        String driver=null;
        String url = null;
        String user = null;
        String pass = null;
        
        try {
            
            driver = p.getProperty("driver");
            url = p.getProperty("url");
            user = p.getProperty("user");
            pass = p.getProperty("pass");
           
        } catch(Exception e) {
            
            System.out.println("Properties load failed. " + e.getMessage());
        }
        
        try {
            Class.forName(driver);
            System.out.println("Driver succesfully loaded!");
            CON = DriverManager.getConnection(url, user, pass);
            System.out.println("You are connected to the database!");
            
            //CON.setAutoCommit(false);
            
        } catch(Exception e) {
            System.out.println(e.getMessage());
            CON = null;
            
            
        }
    }
        public static Connection getCON() {
            if (CON == null)
                throw new NullPointerException(
             
                        "Connection in null! Call init() first");
            
            return CON;
            
        }
        
        @Override
        protected void finalize() throws Throwable {
            CON.close();
        }
        
        
    }
package hotel;

import java.util.Properties;
//import java.io.FileInputStream;
import java.io.*;
/**
 * Główna klasa.
 * 
 */
public class Hotel {
    
    public static void main(String[] args) {
        
        Properties props = new Properties();
            try {
                props.load(new FileInputStream("XXXXXX"));
                
                System.out.println("Properties  succesfully loaded");
                
            } catch(IOException e) {
                
                e.printStackTrace();
            }
        
        DBConnector db = new DBConnector();
        
        
        db.init(props);
        //db.getCON();
            
        
        
    }

}

Pozdrawiam

0

Za dużo pisania :) Pomieszany kod statyczny i niestatyczny.

package hotel;


import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

/*
 * Klasa odpowiedzialna za obsługę bazy
**/
public class DBConnector {
   
    private static Connection CON;
   
    public DBConnector(Properties p) {
        init(p);
    }
   
    private void init(Properties p) {
       
        String driver=null;
        String url = null;
        String user = null;
        String pass = null;
       
        try {
           
            driver = p.getProperty("driver");
            url = p.getProperty("url");
            user = p.getProperty("user");
            pass = p.getProperty("pass");
           
        } catch(Exception e) {
            System.out.println("Properties load failed. " + e.getMessage());
        }
    }
        public Connection getCON() throws Exception{
            if (CON == null)
                Class.forName(driver);
                System.out.println("Driver succesfully loaded!");
                CON = DriverManager.getConnection(url, user, pass);
                System.out.println("You are connected to the database!");
            return CON;
        }
       
        @Override
        protected void finalize() throws Throwable {
            CON.close();
        }
       
       
    }

I tak oto masz rozdzieloną inicjację danych potrzebnych do połączenia od nawiązania samego połączenia. Nadal nie jest to doskonałe ponieważ połączenie jest jedno globalne na całą aplikację, a ładniej wygląda zarządzanie za pomocą puli połączeń. Z drugiej strony patrząc i tak jest nieźle.

0

Dzięki, a co do samego tworzenia obiektu klasy Properties w funkcji main jest dobre?, można to zrobić w jakiś klasie która posiada odpowiednią metodę zwracający obiekt p przygotowany do przekazania do metody init()?, będzie to lepsze rozwiązanie?

Inna sprawa to czy:

  String driver=null;
        String url = null;
        String user = null;
        String pass = null;

Nie powinny być polami w klasie? lub być zwracane przez metodę init i przekazywane jako parametry do getCon(), bo w kodzie, który podałeś na sztywno wklejonym funkcja getCon nie widzi powyższych zmiennych?
Można to zrobić np zwrócić wektor zawierający zaktualizowane te zmienne przez funkcję init i wsadzic go do getCon()?

0

generalnie nie jest źle, ale można to wyrzucić do jakiegoś osobnego obiektu, który będzie zarządzał wszelkiej maści konfiguracjami w programie.

0

czyli rozumiem jak wrzucę te stringi jako prywatne pola klasy to nie będzie źle.

Sorry że męcze, ale mógłbyś podać przykładową implementację takiego rozwiązania. bo nie bardzo to kumam.

0

Przykładowa implementacja jest w dziale Java serwisu :)

0

Można też w taki sposób:

package hotel;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

/*
 * Klasa odpowiedzialna za obsługę bazy
**/
public class DBConnector {
   
    private static Connection CON;
    private static DBConnector instance = new DBConnector();
   
    private DBConnector() {//konstruktor singleton
        //nothing ;)
    }
    public static DBConnector getInstance(){
         return instance;
    }
        public Connection getCON(Properties p) throws Exception{
            if (CON == null){
                Class.forName(p.getProperty("driver"));
                System.out.println("Driver succesfully loaded!");
                CON = DriverManager.getConnection(p);//"user","password"
                System.out.println("You are connected to the database!");
            }
            return CON;
        }
       
        @Override
        protected void finalize() throws Throwable {
            CON.close();
        }
       
       
    }

I wtedy...:


package hotel;

import java.util.Properties;
//import java.io.FileInputStream;
import java.io.*;
/**
 * Główna klasa.
 * 
 */
public class Hotel {
    
    public static void main(String[] args) {
        
        Properties props = new Properties();
            try {
                props.load(new FileInputStream("XXXXXX"));
                
                System.out.println("Properties  succesfully loaded");
                Connection con = DBConnector.getInstance().getCON(props);  
                ...
            } catch(Exception e) {
                e.printStackTrace();
            }
    }

}




0

dzięki, za odpowiedzi, ale nie rozumiem:

        public Connection getCON(Properties p) throws Exception{
                 if (CON == null){
                Class.forName(p.getProperty("driver"));
                System.out.println("Driver succesfully loaded!");
               
                
                CON = DriverManager.getConnection(p.getProperty("url"),
                        p.getProperty("user"), p.getProperty("pass"));//linia 47
                System.out.println("You are connected to the database!");
            }
            return CON;
        }

Dlaczego kompilator pluje się o linie 47 błędem, skoro ładowania drivera bazy przechodzi:

Exception in thread "main" java.lang.NullPointerException
        at java.util.Hashtable.get(Hashtable.java:334)
        at java.util.Properties.getProperty(Properties.java:932)
        at hotel.DBConnector.getCON(DBConnector.java:47)
        at hotel.Hotel.main(Hotel.java:25)

0

Stawiam, że

p.getProperty("url")
//lub
p.getProperty("user")
//lub
p.getProperty("pass")

zwraca null

0

dzięki za odpowiedź.

Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1