JavaRush /Blog Java /Random-ES /Parte 3. Creamos el esqueleto de nuestra base de datos, l...
Marat Sadykov
Nivel 41

Parte 3. Creamos el esqueleto de nuestra base de datos, los primeros comandos SQL usando ejemplos de java.sql.

Publicado en el grupo Random-ES
Primera parte Segunda parte
Parte 3. Creamos el esqueleto de nuestra base de datos, los primeros comandos SQL usando ejemplos de java.sql.  - 1

aplicación java

organización de 3 niveles

Volvamos a la aplicación Java. La versión de la parte anterior fue creada en estilo HelloWorld para controlar la corrección de las acciones iniciales. Implementamos una arquitectura de tres niveles (tres capas), que en la literatura en inglés a menudo se denomina 3tier/3layer . Su breve esencia es la siguiente:
  • Todas las entidades están diseñadas como modelos. Estos son objetos que contienen:
    • Un conjunto de atributos (campos privados de la clase).
    • Constructor(es).
    • Configuradores y captadores para configurar/leer atributos.
    • Es importante que no contengan ningún otro código además del anterior. Estos objetos suelen denominarse POJO (objeto Java antiguo simple).
  • Toda la lógica para trabajar con modelos la implementa la capa de Servicio. Genera reglas de negocio para modelos. Por ejemplo, procesar solicitudes desde una aplicación Java. Los argumentos de consulta y los resultados devueltos suelen incluir modelos (o colecciones de ellos).
  • La capa de Repositorio es un "intermediario" entre el DBMS y el Servicio, que trabaja directamente con la base de datos y es responsable de la interacción con ella.
Parte 3. Creamos el esqueleto de nuestra base de datos, los primeros comandos SQL usando ejemplos de java.sql.  - 2 ¿Por qué necesitamos formar un conglomerado así? El hecho es que cada capa está lo más aislada posible de las demás. Si en lugar de una base de datos tenemos un conjunto de archivos de texto, entonces sólo necesitamos cambiar la implementación de Repositorio sin tocar el resto del código. De manera similar, podemos conectar/agregar otro Servicio con cambios mínimos. Para sistemas grandes, podemos dar la implementación de diferentes capas a diferentes personas o experimentar combinando implementaciones óptimas de diferentes capas. Creemos paquetes modelo , repositorio , servicio para nuestra aplicación, donde se ubicarán las clases correspondientes. Volveremos a la capa de Servicio en las siguientes partes, pero por ahora prestaremos atención a los modelos y repositorios. Parte 3. Creamos el esqueleto de nuestra base de datos, los primeros comandos SQL usando ejemplos de java.sql.  - 3

Modelo

Todas nuestras entidades (acciones, comerciantes, tasas y acciones de los comerciantes) y sus equivalentes en la tabla tienen una característica común: una clave primaria artificial. Por lo tanto, creemos una clase base BaseModel. Todos los modelos heredarán de él.
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);
    }
}
A continuación se muestra un modelo de acciones de ejemplo. Puedes ver el resto de listados de modelos siguiendo el enlace al repositorio de github al final del artículo.
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

En la primera parte, aprendimos cómo establecer una conexión con la base de datos y cerrarla. Ahora sigamos adelante. Las etapas de trabajo con JDBC se muestran en el siguiente diagrama: Parte 3. Creamos el esqueleto de nuestra base de datos, los primeros comandos SQL usando ejemplos de java.sql.  - 4
  • Class.forName()carga la clase y la registra con DriverManager;
  • DriverManager.getConnection()devolverá Connection: una conexión a la base de datos especificada en el argumento del método y utilizando el controlador JDBC correspondiente (que se cargó usando Class.forName()).
  • createStatement()nos devolverá Statementun objeto a partir del cual podremos realizar consultas a la base de datos. También hay:
      CallableStatementpara llamar a las funciones y procedimientos SQL propios del DBMS (se llaman almacenados).
    • PreparedStatementfacilitando la creación de consultas parametrizadas y por lotes.
  • Tener "en la mano" le statementpermitirá execute()enviar una solicitud en forma de comando de lenguaje de consulta SQL directamente a la ejecución del DBMS y devolver una respuesta en forma de ResultSet. Para mayor comodidad existen:
    • executeQuery()– para leer datos del DBMS.
    • executeUpdate()– modificar datos en el DBMS.
  • La respuesta del servidor en sí ResultSetse puede procesar en el formulario iterando a través de first(), last(), next()etc. Podemos obtener campos de resultados individuales a través de captadores: getInteger(), getString()...
Hay que tener en cuenta que después de trabajar con el DBMS, para ahorrar recursos, es recomendable cerrar los objetos detrás de usted (¡en el orden correcto!) y ResultSetahorrar recursos. Recuerde, al cerrar un objeto que está más arriba en la secuencia del diagrama, cerrará en cascada todos los objetos generados en el proceso de trabajar con él. Por lo tanto, cerrar una conexión provocará el cierre de toda ella y de todo lo recibido con su ayuda. StatementConnectionStatementResultSet

Implementación del repositorio

Después de la parte teórica de JDBC, pasemos a la implementación del repositorio. Lo implementamos arquitectónicamente de la siguiente manera:
  • Moveremos las partes más generales del trabajo con un DBMS a un ancestro común: BaseTable;
  • Las operaciones lógicas que realizaremos serán declaradas en la interfaz TableOperation;
Parte 3. Creamos el esqueleto de nuestra base de datos, los primeros comandos SQL usando ejemplos de java.sql.  - 5 El nuevo repositorio heredará de la clase BaseTablee implementará la interfaz TableOperation. Por lo tanto, necesitamos escribir la implementación de los métodos declarados en la interfaz TableOperation. En este caso, podemos utilizar los métodos de la clase padre BaseTable. Por el momento, la interfaz declara métodos para crear tablas:
package sql.demo.repository;
import java.sql.SQLException;

// Операции с mesaми
public interface TableOperations {
    void createTable() throws SQLException; // создание таблицы
    void createForeignKeys() throws SQLException; // создание связей между mesaми
    void createExtraConstraints() throws SQLException; // создание дополнительных правил для значений полей таблиц
}
A medida que estudie el material, la lista de declaraciones de métodos se expandirá ( read(), update()....). Implementaremos nuevas funciones en dos pasos:
  1. Agreguemos otra capacidad para trabajar con una tabla en forma de un nuevo método de interfaz.
  2. A continuación, en las clases que implementan la interfaz, describiremos la implementación del software en nuevos métodos generados por la interfaz.
Repositorio de ejemplo para Share(acciones). La lógica principal está en los comandos para crear tablas, especificar tipos de datos SQL para campos y agregar restricciones:
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)", "Создана mesa " + 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");

    }
}
Los listados de otros repositorios y la clase principal están disponibles a través del enlace al repositorio de github al final del artículo. Por supuesto, puede hacer un diseño de programa diferente o una refactorización más exhaustiva del programa: mover partes comunes a una clase principal, resaltar métodos comunes, etc. Pero el objetivo principal de la serie de artículos es trabajar directamente con la base de datos, por lo que si lo desea, puede diseñar el programa y cosas similares, puede hacerlo usted mismo. Estructura actual del proyecto: Parte 3. Creamos el esqueleto de nuestra base de datos, los primeros comandos SQL usando ejemplos de java.sql.  - 6 Además de repositorios y modelos, hemos creado adicionalmente una clase StockExchangeDBpara la gestión general de nuestra emulación. En esta etapa gestionamos los repositorios (en las siguientes partes pasaremos a los servicios). Los declaramos y comenzamos a crear tablas:
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();
    }

    // Инициализация по умолчанию, без удаления archivo БД
    public StockExchangeDB() throws SQLException, ClassNotFoundException {
        this(false);
    }

    // Creación всех таблиц и внешних ключей
    public void createTablesAndForeignKeys() throws SQLException {
        shares.createTable();
        shareRates.createTable();
        traiders.createTable();
        traiderShareActions.createTable();
        // Creación ограничений на поля таблиц
        traiderShareActions.createExtraConstraints();
        shares.createExtraConstraints();
        // Creación внешних ключей (связи между mesaми)
        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 драйвер для СУБД не найден!");
        }
    }
}
Resultado de la ejecución: Parte 3. Creamos el esqueleto de nuestra base de datos, los primeros comandos SQL usando ejemplos de java.sql.  - 7

Resumen

En la segunda y tercera parte del artículo aprendimos:
  • Tipos de datos SQL.
  • Tablas de bases de datos.
  • Diseño de una base de datos: estructuras de tablas y relaciones entre ellas.
  • Lenguaje de consulta SQL en términos de creación de tablas de bases de datos, establecimiento de restricciones en campos y relaciones entre tablas.
  • Más sobre la interacción con JDBC.
  • Arquitectura de modelo/repositorio/servicio de tres niveles (tres capas) de una aplicación de procesamiento de datos.

Enlaces útiles

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION