Как правильно построить иерархию классов в Java?
Пишу прогу, которая импортирует ексель файл в базу данных, все работает отлично, но хотелось бы узнать как можно правильнее организовать иерархию. Использую JDBC драйвер. У меня сейчас она такая:
- Main
- DatabaseConnection (класс создаёт соединение с базой и загружает в память драйвер)
- Handler (производит непосредственно загрузку)
- Configs (конфигурация для работы (database name, password, user, driverURI и тд))
Заранее спасибо!
Ответы (1 шт):
Автор решения: Дмитрий
→ Ссылка
Попробовал сделать рефакторинг, поскольку у вас нет тестов, возможно где-то ошибся. Пожалуйста, задавайте ваши вопросы.
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Directory directory = new Directory("путь к директории");
List<String> defunctFiles = new ArrayList<>();
print("Uploading...");
// Индикатор загрузки
ProgressBar progressBar = new ProgressBar();
Handler handler = new Handler();
// Считает время работы программы
long start = System.nanoTime();
for (int i = 0; i < directory.getNumberOfFiles(); i++) {
try {
handler.uploadFile(directory.getDirectoryFile(i));
} catch (RuntimeException e) {
defunctFiles.add(directory.getDirectoryFile(i).getName() + "(" + e.getMessage() + ")");
}
progressBar.step(i, directory.getNumberOfFiles() - 1);
}
long leadTime = TimeUnit.SECONDS.convert((System.nanoTime() - start), TimeUnit.NANOSECONDS);
print("Uploaded files: " + (directory.getNumberOfFiles()-defunctFiles.size()) + "\\" + directory.getNumberOfFiles());
showDefunctFiles(defunctFiles);
print("Time: " + leadTime + " sec");
}
/**
* Функция создания вывода деффектных файлов
*/
private static void showDefunctFiles(Collection <String> files) {
if (!files.isEmpty()) print("Defunct files: ", files.stream().collect(Collectors.joining(", ")));
}
public static void print(Object ... args) {
for (Object arg : args) System.out.println(arg);
}
}
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
public class Handler {
/**
* Функция загрузки файлов Excel в базу данных
*
* @param file - файл, который нужно загрузить
*/
public void uploadFile(final File file) {
String sheetName = "название таблицы";
try (DatabaseConnection connection = new DatabaseConnection()) {
try (XSSFWorkbook workbook = new XSSFWorkbook(file)) {
//Класс представляет возможность перебрать все элементы в коллекции без вникания во внутреннюю структуру и устройство коллекций.
Iterator <Row> rowIterator = getIterator(workbook.getSheet(sheetName));
while (rowIterator.hasNext()) {
Iterator<Cell> cellIterator = getIterator(rowIterator.next());
while (cellIterator.hasNext()) {
//Ячейки электронной таблицы используются для размещения информации.
Cell cell = cellIterator.next();
//Проверка типа информации, которая содержиться в даной ячейке, запись значений в базу даных
if (CellType.NUMERIC.equals(cell.getCellType())) {
connection.set(cell.getColumnIndex(),cell.getNumericCellValue());
} else if (CellType.STRING.equals(cell.getCellType())) {
String cellValue = cell.getStringCellValue().trim();
if (!cellValue.isEmpty()) connection.set(cell.getColumnIndex(), cellValue);
}
}
connection.set(11, file.getName()).update();
}
} catch (IOException | InvalidFormatException e) {
throw new RuntimeException(e);
}
}
}
private <T> Iterator<T> getIterator(Iterable<T> iterable) {
Iterator<T> iterator = iterable.iterator();
if (iterator.hasNext()) iterator.next();
return iterator;
}
}
import java.io.Closeable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class DatabaseConnection implements Closeable {
private static final String HOST = "";
private static final String PORT = "";
private static final String USERNAME = "";
private static final String PASSWORD = "";
private static final String DB_NAME = "";
private static final String DB_DRIVER_NAME = "oracle.jdbc.driver.OracleDriver";
private static final String SQL = "insert into \"название таблицы\"(\"названия колонок\") values (?,?,?,?,?,?,?,?,?,?,?)";
private static final Connection CONNECTION;
private final PreparedStatement preparedStatement;
static {
try {
Class.forName(DB_DRIVER_NAME);
CONNECTION = DriverManager.getConnection("jdbc:oracle:thin:@" + HOST + ":" + PORT + "/" + DB_NAME, USERNAME, PASSWORD);
} catch (ClassNotFoundException | SQLException ex) {
throw new RuntimeException(ex);
}
}
public DatabaseConnection() {
try {
//Для подтверждения SQL-запросов мы используем объекты, созданные с использованием этого интерфейса.
this.preparedStatement = CONNECTION.prepareStatement(SQL);
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
public DatabaseConnection update() {
try {
preparedStatement.executeUpdate();
return this;
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
public DatabaseConnection set(int parameterIndex, double x) {
try {
preparedStatement.setDouble(parameterIndex, x);
return this;
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
public DatabaseConnection set(int parameterIndex, String x) {
try {
preparedStatement.setString(parameterIndex, x);
return this;
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
@Override
public void close() {
try {
preparedStatement.close();
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
}