Новичок Java нуждается в помощи в соединении базы данных - PullRequest
4 голосов
/ 18 августа 2010

Я новичок в Java и еще новее в соединениях с базой данных Java. Мне удалось создать соединение с базой данных и запросить таблицу, когда я поместил ее в класс Main. Теперь, когда я переместил его в новый класс с именем Connection, я получаю ошибки:

package lokate;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;

public class Connection {

private static Statement stmt = null;
private static ResultSet rs = null;
private static Connection con = null;

public Connection() throws SQLException {
    try {
        Class.forName("com.mysql.jdbc.Driver");
        String connectionUrl = "jdbc:mysql://localhost:3306/Lokate?" +
                               "user=root&password=";
        con = DriverManager.getConnection(connectionUrl);
        stmt = con.createStatement();
        retriveData("SELECT * FROM Users");
        int rowsEffected = 0;
    } catch (SQLException sqlEx) {
        System.out.println("SQL Exception: "+ sqlEx.toString());
    } catch (ClassNotFoundException classEx) {
        System.out.println("Class Not Found Exception: "+ classEx.toString());
    } catch (Exception Ex) {
        System.out.println("Exception: "+ Ex.toString());
    }
}

public static void retriveData(String SQL) throws Exception {
    rs = stmt.executeQuery(SQL);
    while (rs.next()) 
    {
        System.out.println(rs.getString("fname") + " : " + rs.getString("lname"));
    }
}

}

Я получаю сообщение о том, что не могу найти символ. Символ: метод createStatement () и несопоставимые типы для con = DriveManager .....

Может кто-нибудь помочь?

Кроме того, лучше ли устанавливать такое соединение в классе, а затем вызывать новый объект каждый раз, когда я хочу что-то сделать с БД?

С уважением,

1012 * Билли *

Ответы [ 4 ]

6 голосов
/ 18 августа 2010

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

  1. Ваш класс Connection является плохой абстракцией, которая не предлагает ничего сверх уровня java.sql.Connection.
  2. Если вы используете свой класс, вы никогда не сможете воспользоваться пулами соединений.
  3. Вы жестко связываете свой класс драйверов, URL-адрес подключения и т. Д. Вы не можете изменить его без редактирования и перекомпиляции. Лучшим решением было бы экстернализировать такие вещи.
  4. Печать сообщения об ошибке в блоках перехвата является гораздо меньшей информацией, чем при выводе всей трассировки стека.
  5. Твой код причиняет мне боль. Он не соответствует стандартам кодирования Sun Java.
  6. Ваш retrieveData метод совершенно бесполезен. Что вы будете делать со всеми этими печатными заявлениями? Не лучше ли загрузить их в структуру данных или объект, чтобы остальная часть вашего кода могла использовать эту информацию?
  7. Это rowsAffected - "аффект" - это глагол, "эффект" - это существительное. Еще одна переменная, которая не приносит никакой пользы.

Вы на неправильном пути. Переосмыслить.

Я думаю, вы найдете этот код более полезным.

package persistence;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DatabaseUtils
{
    public static Connection createConnection(String driver, String url, String username, String password) throws ClassNotFoundException, SQLException
    {
        Class.forName(driver);

        if ((username == null) || (password == null) || (username.trim().length() == 0) || (password.trim().length() == 0))
        {
            return DriverManager.getConnection(url);
        }
        else
        {
            return DriverManager.getConnection(url, username, password);
        }
    }

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


    public static void close(Statement st)
    {
        try
        {
            if (st != null)
            {
                st.close();
            }
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

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

    public static void rollback(Connection connection)
    {
        try
        {
            if (connection != null)
            {
                connection.rollback();
            }
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    public static List<Map<String, Object>> map(ResultSet rs) throws SQLException
    {
        List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();

        try
        {
            if (rs != null)
            {
                ResultSetMetaData meta = rs.getMetaData();
                int numColumns = meta.getColumnCount();
                while (rs.next())
                {
                    Map<String, Object> row = new HashMap<String, Object>();
                    for (int i = 1; i <= numColumns; ++i)
                    {
                        String name = meta.getColumnName(i);
                        Object value = rs.getObject(i);
                        row.put(name, value);
                    }
                    results.add(row);
                }
            }
        }
        finally
        {
            close(rs);
        }

        return results;
    }
}
3 голосов
/ 18 августа 2010

Ваша проблема в том, что DriverManager.getConnection возвращает java.sql.Connection.Поскольку ваш класс также называется Connection, вы получаете конфликт имен между lokate.Connection и java.sql.Connection.Вам нужно будет указать полное имя класса, где бы вы ни хотели использовать java.sql.Connection, в противном случае предполагается lokate.Connection.

Укажите полное имя класса, например:

java.sql.Connection con = null;
// ....
con = DriverManager.getConnection(connectionUrl);

Или переименуйте свой класс Connection во что-то другое, и у вас не возникнет этот конфликт имен.

1 голос
/ 18 августа 2010

Connection - это существующий тип в пакете java.sql, который возвращает DriverManager.getConnection. Вы также назвали свой класс Connection, так что это вызывает путаницу. Самый простой выход - переименовать ваш класс во что-то еще и добавить import java.sql.Connection; вверху.

0 голосов
/ 03 ноября 2015

Кроме того, лучше ли помещать соединение в класс таким образом, а затем вызывать новый объект каждый раз, когда я хочу что-то сделать с базой данных?

Я думаю, что наилучшей практикой будет использование существующего решения этой проблемы, чтобы вы могли избежать повторного изобретения колеса и сосредоточиться на том, что делает вашу проблему уникальной.

Если вы пишете серверное приложение (неясно, так ли это), то я бы также рассмотрел использование пула соединений с базой данных. Создание новых подключений к базе данных на лету неэффективно и плохо масштабируется. Вы можете прочитать о проблемах с подключением к базе данных в этой статье, которую я написал некоторое время назад.

...