#java #database #jakarta-ee
#java #База данных #джакарта-ee
Вопрос:
У меня есть вопрос относительно Java при извлечении данных, скажем, из базы данных MySQL. На данный момент мне нужно написать довольно много избыточного кода при извлечении данных. И мне интересно, есть ли лучший способ сделать это.
Например. У меня есть метод, который извлекает данные из таблицы A. Тогда метод для этого будет выглядеть примерно так
public void readDataBase() throws Exception {
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager
.getConnection("jdbc:mysql://localhost/feedback?"
"user=sqluseramp;password=sqluserpw");
statement = connect.createStatement();
resultSet = statement
.executeQuery("select * from FEEDBACK.COMMENTS");
writeResultSet(resultSet);
} catch (Exception e) {
throw e;
} finally {
close();
}
}
Интересно, есть ли лучший способ написать метод, подобный этому. Потому что это становится довольно некрасиво, когда вам приходится писать подобный код, а именно то, что вам приходится постоянно записывать эти строки в getConnection
в каждом методе, который извлекает данные из базы данных.
Комментарии:
1. Извините, вы не думаете провести рефакторинг исходного кода? можете ли вы посмотреть документацию в википедии по рефакторингу кода
Ответ №1:
Используйте Spring с MyBatis или spring-jdbc для доступа к данным вместо необработанного JDBC.
spring-jdbc — это библиотека, содержащая базовый код JDBC, где вы можете предоставлять обратные вызовы, чтобы указать, как вы хотите, чтобы результирующие наборы отображались на объекты и тому подобное. Mybatis немного более высокого уровня, вы указываете свои запросы в XML-файле.
С Spring большой выигрыш заключается в том, что вы получаете декларативные транзакции, поэтому у вас нет кода, запускающего и фиксирующего транзакции, вы также получаете шаблоны для объектов доступа к данным, и настройка пула соединений проста. И есть множество примеров того, как собрать части вместе.
Ответ №2:
В какой-то момент вам лучше написать свой собственный DAO, который обрабатывает всю сантехнику за вас.
Ответ №3:
Я бы делал разные вещи в зависимости от того, нахожусь ли я в однопоточном пакетном задании или внутри контейнера.
Для однопоточного пакетного задания:
- создайте только одно соединение и повторно используйте его
- создайте только один подготовленный оператор и повторно используйте его
- оптимизация вызовов фиксации
Для J2EE
- используйте управляемый контейнером пул источников данных
Ответ №4:
В большинстве случаев, когда вы пишете программу, работающую с базой данных, вы не открываете соединение каждый раз, когда хотите что-то с ней сделать. Вместо этого вы открываете соединение в начале программы, а затем используете его каждый раз при доступе к базе данных.
Взгляните на этот пример (псевдокод!):
class Database {
private Connection conn;
public Database() {
connect();
}
private void connect() {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(dbUrl);
}
public void close() {
conn.close();
}
private ResultSet readSth() {
statement = conn.createStatement();
return statement.executeQuery("select * from FEEDBACK.COMMENTS");
}
private void doSth() {
// do sth else with conn
}
}
Комментарии:
1. Не является ли плохой практикой совместное использование одного соединения? Соединения должны исходить из пула соединений
2. Эй, это всего лишь очень простой фрагмент кода. Я жду вашего ответа с примером пула соединений.
Ответ №5:
Вы можете создать класс со статическим методом, который возвращает вам экземпляр соединения, как показано ниже:
import java.sql.*;
import java.util.Properties;
public class Getconnection{
private static final String dbClassName = "com.mysql.jdbc.Driver";
private static final String CONNECTION ="jdbc:mysql://127.0.0.1/dbUserData";
private static Properties p = new Properties();
public static Connection getConnection(){
p.put("user","root");
p.put("password","library");
try{
Class.forName(dbClassName);
Connection con=DriverManager.getConnection(CONNECTION,p);
return con;
}
catch(Exception ie){
ie.printStackTrace();
return null;
}
}
}
Так что вам не нужно создавать разные экземпляры подключения и изменять только в одном месте, если вы хотите…
Ответ №6:
Я думаю, вы страдаете от базовой организации кода. Например, вы должны создать соединение только один раз, а затем передать его любым методам, которые в нем нуждаются. Обычно люди используют пулы подключений, чтобы к БД когда-либо существовало только определенное количество подключений (потому что они дорогие), а менеджер пула подключений будет предоставлять их по мере необходимости и отслеживать их состояния. В Java есть несколько библиотек пула соединений (у Apache есть одна), но мне повезло использовать:http://sourceforge.net/projects/c3p0 /
Мне не очень нравятся тяжелые ORM, такие как Hibernate, но мне нравятся MyBatis. Это позволяет мне использовать wright SQL и не внедряется во все модели моего домена: http://www.mybatis.org/java.html Я думаю, вам было бы очень полезно иметь объектный уровень доступа к данным (DAO). Этот уровень абстрагирует связь с вашими данными, поэтому слои выше могут просто извлекать коллекции данных, не беспокоясь о базовом SQL, который потребовался для создания этого списка.
Ответ №7:
Я отошел от прямого доступа к JDBC с тех пор, как начал использовать ORM (например. Переход в спящий режим). Или почему у вас нет какого-либо общедоступного статического метода для чтения из БД:
public ResultSet readDataBase(String query) throws Exception {
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager
.getConnection("jdbc:mysql://localhost/feedback?"
"user=sqluseramp;password=sqluserpw");
statement = connect.createStatement();
return statement.executeQuery(query);
} catch (Exception e) {
throw e;
} finally {
close();
}
}
и у вас могут быть аналогичные методы при обновлении / удалении и т. Д