Как использовать JDBC в JavaEE?

Я разрабатываю в среде JavaEE (weblogic 12), и часть моего кода использует JDBC; Поэтому мне нужно получить соединение JDBC с сервера приложений.
Я знаю, что использование JDBC в JavaEE — очень плохая практика, но этот код я не могу изменить (устаревший).

Я нашел способ сделать это, но я не уверен, что это правильный путь:

@Resource(mappedName="mydsjndipath")
private DataSource ds;

public void foo() {
    Connection conn = ds.getConnection();
}

Вопрос в том, что мне делать с соединением в конце?
Я не могу зафиксировать/откатить его, потому что использую распределенную транзакцию. Но должен ли я хотя бы закрыть его?
И всегда ли транзакция JTA будет влиять на соединение (при фиксации/откате)?

Или, может быть, есть другой лучший способ использовать JDBC в JavaEE? (нет, собственные запросы EntityManager не подходят)


person wafwaf    schedule 19.03.2012    source источник
comment
Почему было бы плохой практикой использовать JDBC в JEE?   -  person beny23    schedule 19.03.2012
comment
По двум причинам: 1. Вероятно, лучше использовать ORM (JPA). 2. Я не уверен в этом, но когда вы используете этот интерфейс, вы не открываете новое соединение, которое не управляется сервером приложений?   -  person wafwaf    schedule 19.03.2012
comment
Re 1. Почему лучше использовать ORM? Если мне нужно выполнить массовое обновление или конкретный запрос или мне не нужна объектная модель, почему бы мне просто не использовать JDBC.   -  person beny23    schedule 19.03.2012
comment
Относительно 2. Получение соединения из источника данных означает, что вы запрашиваете у контейнера/сервера приложений новое соединение, поэтому вы получите преимущества соединений, управляемых контейнером. Кроме того, он не обязательно открывает новое соединение, он может использовать соединение, связанное с текущей транзакцией.   -  person beny23    schedule 19.03.2012
comment
В конце концов, под капотом ORM будет делать то же самое, он будет запрашивать соединение с источником данных, когда это необходимо, и когда он будет завершен, он закроет соединение (что на самом деле передать соединение обратно в пул, управляемый сервером приложений)   -  person beny23    schedule 19.03.2012
comment
1. Я нахожу только три причины для использования JDBC в JEE; Представление; не имея времени на изучение ORM; и наличие устаревшего кода, использующего JDBC. Если у вас есть таблица, которую вы не хотите отображать с помощью ORM, а только для того, чтобы получить из нее что-то конкретное, вы можете использовать собственные запросы EntityManager. Если это единственный запрос в вашем приложении, я бы сомневался, что вам нужна JEE. 2. Я думаю, что это создает новое соединение; Я дважды вызывал getConnection, и это дало мне два разных соединения.   -  person wafwaf    schedule 19.03.2012
comment
Я думаю, что такое утверждение, как доступ к базе данных в JEE, всегда должно выполняться с использованием ORM, это обобщает и вызывает проблемы. Конечно, есть много причин использовать ORM для конкретных задач. Для других конкретных проблем использование ORM является излишним и приведет к снижению ремонтопригодности и снижению производительности, а решение будет хуже, чем использование прямого JDBC. Ведь только потому, что у тебя есть отвертка, ты не стал бы использовать ее с гвоздями...   -  person beny23    schedule 19.03.2012
comment
Я никогда не говорил, что доступ к БД всегда должен осуществляться с использованием ORM. Если использование ORM в вашем приложении является излишним, то есть большая вероятность, что использование JEE в вашем приложении также является излишним.   -  person wafwaf    schedule 19.03.2012
comment
Я думаю, мы просто согласимся не соглашаться. На мой взгляд, утверждение о том, что JDBC в JEE является плохой практикой, подразумевает, что в JEE для него нет места, и, на мой взгляд, так оно и есть, и предоставление серверу приложений возможности управлять соединениями, используемыми с JDBC, имеет смысл и происходит в более чем устаревший код.   -  person beny23    schedule 20.03.2012
comment
Возможный дубликат закрытия соединений JDBC в пуле   -  person Cypher    schedule 20.03.2018


Ответы (2)


Почему использование JDBC должно быть плохой практикой?

Если ваш сервер приложений поддерживает JDBC и вы разрешаете ему подключаться к БД через JDBC, я лично не вижу причин, по которым вы не должны использовать его и в своем приложении!?

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

Также вы отвергаете преимущество

  • серверное управление вашим пулом соединений JDBC
  • возможность повторного использования этого соединения

В конце вы всегда должны закрывать свой Connection/Statement/ResultSet, например:

try {
  // your stuff here
}
finally {
  if(connection != null) {
    connection.close();
  }
  // same for statement/ResultSet ift not used anymore
}
person SimonSez    schedule 19.03.2012
comment
Почему это плохая практика — другой вопрос для другого обсуждения. Это не то, о чем я прошу. И я в курсе, как надо закрывать ресурсы JDBC, это тоже не вопрос. - person wafwaf; 19.03.2012
comment
Я не понимаю. Ваш вопрос в том, что делать с connection в конце. Ответ: закрыть. На основе вашего кода ваш сервер уже использует JDBC и будет управлять вашей функциональностью фиксации/отката. Поэтому вы сделали заявление JDBC - это плохая практика Я (и некоторые другие пользователи) добавляю свои пять копеек. Не обижайся! Ваше здоровье! - person SimonSez; 19.03.2012
comment
1. Мой вопрос на самом деле не имеет ничего общего с моим мнением о том, что JDBC обычно является плохой практикой в ​​JEE (возможно, мне не стоило упоминать об этом). 2. Используя обычный JDBC, вы не можете зафиксировать или откатить соединение после его закрытия. Вот почему для меня странно, что в сочетании с JTA соединение может быть зафиксировано или отменено после его вызова с помощью «закрыть». - person wafwaf; 19.03.2012
comment
Хорошо, проблема JDBC в стороне. Закрыть соединение в вашей настройке JTA просто означает выпустить этот ресурс на сервер, где сервер решает, что произойдет дальше (GC или фиксация/откат). Если вы можете вызвать .commit() для уже закрытого соединения, возможно, это соединение не было закрыто/возвращено менеджером транзакций, потому что оно все еще содержит некоторые ссылки на открытую транзакцию. Обычно для вашего соединения установлено значение autoCommit, которое фиксируется после каждого оператора. Если вы отключили это, вам придется позаботиться об этом самостоятельно. Ваше здоровье - person SimonSez; 19.03.2012
comment
Я имел в виду не то, что я могу зафиксировать или откатить соединение после его закрытия (я не могу этого сделать, даже когда оно открыто), а то, что это может сделать сервер приложений. Я предполагаю, что они просто переопределили метод «закрыть» в своей реализации Connection, поэтому на самом деле он не закрывает соединение. - person wafwaf; 19.03.2012
comment
Я придерживаюсь своего утверждения, что вы делегировали управление транзакциями серверу, и поэтому он содержит ссылки на объекты. Из-за этого управления сервер может отложить фиксацию, которая обычно уже должна быть выполнена. Вы сказали, что используете распределенные транзакции: поэтому вам следует закрыть ВАШЕ соединение, чтобы убедиться, что сервер может зафиксировать/откатить транзакцию после завершения всех транзакций. Ваше здоровье! - person SimonSez; 19.03.2012

закрыть соединение - conn.close();

person digitebs    schedule 19.03.2012
comment
Как насчет фиксации или отката транзакции JTA? Будет ли это по-прежнему влиять на соединение, даже если оно закрыто? - person wafwaf; 19.03.2012
comment
Ни одна транзакция не фиксируется или откатывается в зависимости от реализации драйвера во время закрытия. - person digitebs; 21.03.2012