Может кто-нибудь помочь мне с некоторыми начинающими JDBC? - PullRequest
4 голосов
/ 27 августа 2010

Как разработчик C #, плохо знакомый с Java, я подумал, что будет проще, если я просто покажу немного кода C #, чтобы я мог видеть, что эквивалентны вызовам Java JDBC:

String myConnectionString = "...";
String mySql = "select name from people where id = @myId";
int myId = 123456;

List<Field> fields = new List<Field>();
using (SqlConnection conn = new SqlConnection(myConnectionString)
{
  conn.Open();
  using (SqlCommand cmd = new SqlCommand(mySql,conn))
  {
    cmd.Parameters.AddWithValue("@myId", myId);
    using(SqlDataReader rdr = cmd.ExecuteReader())
    {
      while (rdr.Read())
      {
        String name = rdr.GetString(0);
        fields.Add(name);
      }
    }
  }
}

Теперь я знаю, что операторы using выше безопасно закроют базу данных, если что-то пойдет не так, в то время как с Java это немного сложнее (попробуйте .. окончательно или что-то в этом роде). И в Java, я не уверен, что именно нужно ликвидировать или закрыть (или что-то еще) - только соединение? Или утверждение тоже?

Если бы вы могли помочь мне, это было бы здорово. Большое спасибо

edit: мне очень нравится код здесь: ( Обработка исключений Java - Стиль )

Connection conn = MyDatabaseLayer.getConnection();
try {
  ... use conn ...
}
finally {
  conn.close();
}

Тем не менее, нужно ли мне выполнять дальнейшую обработку исключений, чтобы обеспечить закрытие оператора, оператора чтения и всего остального? Или достаточно закрыть соединение?

Ответы [ 2 ]

4 голосов
/ 27 августа 2010

Вот грубое объяснение шагов, как свободно скопировано с некоторой случайной страницы:

сначала вы загружаете драйвер. Это будет класс в вашем файле jar драйвера. Во многих средах вы получаете это, на самом деле, из источника данных, это немного старомодно, но, вероятно, лучше увидеть гайки и болты.

Class.forName("com.imaginary.sql.msql.MsqlDriver");

тогда вы получите соединение:

  Connection conn = DriverManager.getConnection("jdbc:msql://www.myserver.com:1114/....", "user1", "password");

Строка url, как правило, различна для разных поставщиков БД. К счастью, мы не слишком часто меняем базы данных, поэтому вам нужно только один раз посмотреть их. Теперь вы можете наконец использовать проклятую вещь.

PreparedStatement ps = conn.prepareStatement("SELECT * FROM FOO WHERE A=?", 1);

Подготовленное утверждение кэшируется, поэтому вы можете использовать его со вставленными параметрами. Он будет работать с простым оператором SQL, но для этого вы можете просто использовать оператор. Вы также можете просто вызвать conn.executeQuery (...), чтобы получить resultSet, который вам нужен.

 ResultSet rs = ps.executeQuery();

Теперь вы можете перебрать rs и получить что угодно:

while (rs.next())
{
..
}

ResultSet также имеет ResultSetmetadata, который дает вам такие вещи, как имена столбцов, количество столбцов (но не общее количество результатов, что было бы слишком просто).

Что касается try catch, вам необходимо закрыть свой оператор / набор результатов после их использования. Каждый раз . Иначе произойдут плохие вещи. Как оставить открытые ресурсы на вашем БД. Так как ваш метод db connect может выдавать ошибки, вы все это рэпуете в try catch и закрываете свой оператор (и соединение, если вы сделали это здесь) в блоке finally.

Вот почему люди используют ORM-фреймворки в Java.

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

Вам действительно нужен блок try-finally здесь. Java-эквивалент ключевого слова using будет представлен в следующей версии Java 7. Порт Java вашего кода будет выглядеть следующим образом:

// Prepare.
String url = "...";
String sql = "SELECT name FROM people WHERE id = ?";
int id = 123456;
List<String> names = new ArrayList<String>();

// Declare before try.
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;

try {
    // Acquire inside try.
    connection = DriverManager.getConnection(url);
    statement = connection.prepareStatement(sql); 
    statement.setInt(1, id);
    resultSet = statement.executeQuery();

    // Process results.
    while (resultSet.next()) {
        names.add(resultSet.getString("name"));
    }
} finally { 
    // Close in reversed order in finally.
    if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
    if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
    if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}

Если пул соединений не используется, закрытие только Connection в большинстве случаев также приведет к закрытию Statement и ResultSet. Хотя это и не указано строго в API JDBC, средний драйвер JDBC сделает это неявно. Но это не нормальная идиома JDBC. Вы должны действительно закрыть все ресурсы явно. Это делает ваш код безопасным для повторного использования в том случае, если вы хотите ввести пул соединений.

Смотри также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...