첫 번째 부분 두 번째 부분
자바 애플리케이션
3계층 조직
Java 애플리케이션으로 돌아가 보겠습니다. 이전 부분의 버전은 초기 작업의 정확성을 제어하기 위해 HelloWorld 스타일로 생성되었습니다. 우리는 영어 문헌에서 종종 3tier/3layer 라고 불리는 3계층(3계층) 아키텍처를 구현합니다 . 그 간략한 본질은 다음과 같습니다.- 모든 엔터티는 모델로 설계되었습니다. 다음을 포함하는 개체입니다.
- 속성 세트(클래스의 비공개 필드)
- 생성자.
- 속성을 설정/읽기 위한 Setter 및 Getter입니다.
- 위 코드 외에 다른 코드를 포함하지 않는 것이 중요합니다. 이러한 객체를 흔히 POJO (Plain Old Java Object) 라고 합니다 .
- 모델 작업을 위한 모든 논리는 서비스 계층에 의해 구현됩니다. 모델에 대한 비즈니스 규칙을 생성합니다. 예를 들어 Java 애플리케이션의 요청을 처리합니다. 쿼리 인수와 반환된 결과에는 모델(또는 그 컬렉션)이 포함되는 경우가 많습니다.
- 리포지토리 계층은 DBMS와 서비스 사이의 "중개자"로서 데이터베이스와 직접 작업하고 상호 작용을 담당합니다.
모델
우리의 모든 엔터티(주식, 거래자, 금리 및 거래자의 행동)와 그에 상응하는 테이블에는 인공 기본 키라는 공통 기능이 있습니다. 따라서 기본 클래스를 만들어 보겠습니다BaseModel
. 모든 모델은 이를 상속받습니다.
package sql.demo.model;
import java.util.Objects;
// Базовый класс модели, имеющий ключ id
public class BaseModel {
protected long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public BaseModel() {}
public BaseModel(long id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BaseModel baseModel = (BaseModel) o;
return id == baseModel.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
아래는 주식 모델의 예입니다. 기사 마지막 부분에 있는 github 저장소 링크를 따라가면 나머지 모델 목록을 볼 수 있습니다.
package sql.demo.model;
import java.math.BigDecimal;
// Модель акции
public class Share extends BaseModel{
// поля SQL таблицы и соответствующие им поля модели
// типы данных SQL
private String name; // Наименование
private BigDecimal startPrice; // Начальная цена
private int changeProbability; // Вероятность смены курса (в процентах)
private int delta; // Максимальное колебание (в процентах)стоимости акции в результате торгов
public Share() {
}
public Share(long id, String name, BigDecimal startPrice, int changeProbability, int delta) {
super(id);
this.name = name;
this.startPrice = startPrice;
this.changeProbability = changeProbability;
this.delta = delta;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
... оставшиеся сеттеры/геттеры
}
JDBC
첫 번째 부분에서는 데이터베이스에 대한 연결을 설정하고 닫는 방법을 배웠습니다. 이제 계속 진행하겠습니다. JDBC 작업 단계는 다음 다이어그램에 나와 있습니다.Class.forName()
클래스를 로드하고 이를 DriverManager에 등록합니다.DriverManager.getConnection()
반환됩니다Connection
– 메소드 인수에 지정되고 해당 JDBC 드라이버(를 사용하여 로드됨Class.forName()
)를 사용하는 데이터베이스에 대한 연결입니다.createStatement()
Statement
데이터베이스에 대한 쿼리를 구성할 수 있는 기반으로 개체를 반환합니다 . 다음도 있습니다:PreparedStatement
매개변수화된 일괄 쿼리 생성을 촉진합니다.
CallableStatement
DBMS 자체의 SQL 함수 및 프로시저(저장된 기능이라고 함)를 호출합니다.- "in hand"를 사용하면 SQL 쿼리 언어 명령 형식의 요청을 DBMS 실행에 직접 보내고 형식으로 응답을 반환할 수
statement
있습니다 . 편의상 다음이 있습니다.execute()
ResultSet
executeQuery()
– DBMS에서 데이터를 읽는 데 사용됩니다.
executeUpdate()
– DBMS의 데이터를 수정합니다. - 서버 응답 자체는 , 등 을
ResultSet
반복하여 형식으로 처리할 수 있습니다 . getter를 통해 개별 결과 필드를 얻을 수 있습니다: , ...first()
last()
next()
getInteger()
getString()
ResultSet
DBMS 작업 후에는 리소스 를 절약하기 위해 뒤에 Statement
있는 개체를 올바른 순서로 닫고 Connection
리소스를 저장 하는 것이 좋습니다 . 다이어그램의 순서에서 더 높은 개체를 닫을 때 작업 과정에서 생성된 모든 개체를 계단식으로 닫게 된다는 점을 기억하십시오. Statement
따라서 연결을 닫으면 모든 연결 과 ResultSet
도움을 받은 모든 것이 닫히게 됩니다 .
저장소 구현
이론적 JDBC 부분을 마친 후 저장소 구현으로 넘어가겠습니다. 우리는 이를 아키텍처적으로 다음과 같이 구현합니다.- 우리는 DBMS 작업의 가장 일반적인 부분을 공통 조상으로 옮길 것입니다
BaseTable
. - 우리가 수행할 논리 연산은 인터페이스에서 선언됩니다
TableOperation
.
BaseTable
하고 인터페이스를 구현합니다 TableOperation
. 따라서 인터페이스에 선언된 메서드의 구현을 작성해야 합니다 TableOperation
. 이 경우 상위 클래스의 메소드를 사용할 수 있습니다 BaseTable
. 현재 인터페이스는 테이블 생성 방법을 선언합니다.
package sql.demo.repository;
import java.sql.SQLException;
// Операции с tableми
public interface TableOperations {
void createTable() throws SQLException; // создание таблицы
void createForeignKeys() throws SQLException; // создание связей между tableми
void createExtraConstraints() throws SQLException; // создание дополнительных правил для значений полей таблиц
}
자료를 공부하면서 메서드 선언 목록이 확장됩니다( read()
, update()
....). 우리는 두 단계로 새로운 기능을 구현할 것입니다:
- 새로운 인터페이스 메소드의 형태로 테이블 작업을 위한 또 다른 기능을 추가해 보겠습니다.
- 다음으로 인터페이스를 구현하는 클래스에서는 인터페이스에 의해 생성된 새로운 메서드의 소프트웨어 구현을 설명합니다.
Share
(주식) 에 대한 예시 저장소입니다 . 주요 논리는 테이블 생성, 필드에 대한 SQL 데이터 유형 지정 및 제한 추가 명령에 있습니다.
package sql.demo.repository;
import java.sql.SQLException;
public class Shares extends BaseTable implements TableOperations{
public Shares() throws SQLException {
super("shares");
}
@Override
public void createTable() throws SQLException {
super.executeSqlStatement("CREATE TABLE shares(" +
"id BIGINT AUTO_INCREMENT PRIMARY KEY," +
"name VARCHAR(255) NOT NULL," +
"startPrice DECIMAL(15,2) NOT NULL DEFAULT 10," +
"changeProbability INTEGER NOT NULL DEFAULT 25,"+
"delta INTEGER NOT NULL DEFAULT 15)", "Создана table " + tableName);
}
@Override
public void createForeignKeys() throws SQLException {
}
@Override
public void createExtraConstraints() throws SQLException {
super.executeSqlStatement(
" ALTER TABLE shares ADD CONSTRAINT check_shares_delta CHECK(delta <= 100 and delta > 0)",
"Cоздано ограничение для shares, поле delta = [1,100]");
super.executeSqlStatement(
" ALTER TABLE shares ADD CONSTRAINT check_shares_changeProbability " +
"CHECK(changeProbability <= 100 and changeProbability > 0)",
"Cоздано ограничение для shares, поле changeProbability = 1..100");
}
}
다른 저장소 및 상위 클래스 목록은 기사 끝에 있는 github 저장소 링크를 통해 확인할 수 있습니다. 물론, 다른 프로그램 디자인을 수행하거나 프로그램의 보다 철저한 리팩토링을 수행할 수 있습니다. 즉, 공통 부분을 상위 클래스로 이동하고, 공통 방법을 강조하는 등의 작업을 수행할 수 있습니다. 그러나 기사 시리즈의 주요 목표는 데이터베이스를 직접 사용하여 작업하는 것이므로 원하는 경우 프로그램 등을 디자인하고 직접 수행할 수 있습니다. 현재 프로젝트 구조: 리포지토리 및 모델 외에도 StockExchangeDB
에뮬레이션의 일반 관리를 위한 클래스를 추가로 만들었습니다. 이 단계에서는 리포지토리를 관리합니다(다음 부분에서는 서비스로 넘어갑니다). 이를 선언하고 테이블 생성을 시작합니다.
package sql.demo;
import org.h2.tools.DeleteDbFiles;
import sql.demo.repository.*;
import java.sql.*;
public class StockExchangeDB {
// Блок объявления констант
public static final String DB_DIR = "c:/JavaPrj/SQLDemo/db";
public static final String DB_FILE = "stockExchange";
public static final String DB_URL = "jdbc:h2:/" + DB_DIR + "/" + DB_FILE;
public static final String DB_Driver = "org.h2.Driver";
// Таблицы СУБД
Traiders traiders;
ShareRates shareRates;
Shares shares;
TraiderShareActions traiderShareActions;
// Получить новое соединение с БД
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(DB_URL);
}
// Инициализация
public StockExchangeDB(boolean renew) throws SQLException, ClassNotFoundException {
if (renew)
DeleteDbFiles.execute(DB_DIR, DB_FILE, false);
Class.forName(DB_Driver);
// Инициализируем таблицы
traiders = new Traiders();
shares = new Shares();
shareRates = new ShareRates();
traiderShareActions = new TraiderShareActions();
}
// Инициализация по умолчанию, без удаления file БД
public StockExchangeDB() throws SQLException, ClassNotFoundException {
this(false);
}
// Creation всех таблиц и внешних ключей
public void createTablesAndForeignKeys() throws SQLException {
shares.createTable();
shareRates.createTable();
traiders.createTable();
traiderShareActions.createTable();
// Creation ограничений на поля таблиц
traiderShareActions.createExtraConstraints();
shares.createExtraConstraints();
// Creation внешних ключей (связи между tableми)
shareRates.createForeignKeys();
traiderShareActions.createForeignKeys();
}
public static void main(String[] args) {
try{
StockExchangeDB stockExchangeDB = new StockExchangeDB(true);
stockExchangeDB.createTablesAndForeignKeys();
} catch (SQLException e) {
e.printStackTrace();
System.out.println("Ошибка SQL !");
} catch (ClassNotFoundException e) {
System.out.println("JDBC драйвер для СУБД не найден!");
}
}
}
실행 결과:
요약
기사의 두 번째 와 세 번째 부분 에서 우리는 다음을 배웠습니다.- SQL 데이터 유형.
- 데이터베이스 테이블.
- 데이터베이스 설계: 테이블 구조 및 테이블 간의 관계.
- 데이터베이스 테이블 생성, 필드에 대한 제한 설정 및 테이블 간의 관계 측면에서 SQL 쿼리 언어입니다.
- JDBC와의 상호 작용에 대해 자세히 알아보십시오.
- 데이터 처리 애플리케이션의 3계층(3계층) 모델/저장소/서비스 아키텍처입니다.
GO TO FULL VERSION