En este artículo, analizaré el uso de la utilidad
Liquibase en las aplicaciones Spring Boot para versionar la estructura de una base de datos relacional y migrar esta estructura de una versión a otra. En la primera parte, analizaremos el ejemplo básico, y en la segunda hablaremos sobre el uso de
liquibase-mave-plugin para revertir los cambios y generar automáticamente scripts comparando las estructuras de la base de datos.
Comencemos creando la aplicación más simple en Spring Boot + JPA (Hibernate).
Spring Initializr nos ayudará con esto. De las dependencias, seleccione JPA, MySQL y Web. Liquibase también se puede conectar en este paso, pero para una mejor comprensión lo haremos más adelante manualmente.
Crea la base de la aplicación
Agregamos una clase de entidad a nuestra aplicación, así como un repositorio y un controlador REST para trabajar con ella. Para concretar, almacenaremos información sobre los usuarios en la entidad creada.
@Entity @Table(name = "users") public class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "username", unique = true, nullable = false) private String userName; @Column(name = "password", nullable = false) private String password; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; @Column(name = "email") private String email;
Spring Data hace que el código del repositorio sea extremadamente conciso
public interface UserRepository extends JpaRepository<User, Long> { }
Controlador REST que mostrará todo el contenido de la tabla de usuario
@RestController public class UserController { private UserRepository userRepository; @Autowired public UserController(UserRepository userRepository) { this.userRepository = userRepository; } @GetMapping("/user/all") public List<User> allUsers() { return userRepository.findAll(); } }
Configuración en el archivo
application.properties spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/geek_db?createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.username=dbuser spring.datasource.password=dbpassword spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
Se supone que su computadora está ejecutando un servidor MySQL en un puerto estándar. Si es necesario, ajuste la URL del servidor en la cadena de conexión, así como el nombre de usuario y la contraseña. También vale la pena prestar atención al parámetro
createDatabaseIfNotExist . Gracias a él, al conectarnos, crearemos una base de datos llamada
geek_db si no está en el servidor.
Añadir liquibase
Seguramente notó que
falta una configuración para Hibernate, es decir,
spring.jpa.hibernate.ddl-auto . En la mayoría de los manuales para principiantes, el valor de
actualización está indicado para ello, debido a que Hibernate creará y ajustará la estructura de la tabla en el propio servidor, en función de las clases de entidad presentes en el proyecto. Este enfoque bien puede usarse si el esquema de datos es muy simple o si el proyecto está entrenando, pero con un esquema algo complicado, lo más probable es que comiencen los problemas, aunque solo sea porque no podemos controlar el proceso de generar secuencias de comandos DDL de Hibernate. Otro problema es que con este enfoque no hay una manera fácil de revertir los cambios realizados en Hibernate en la estructura de la base de datos.
Es para resolver los problemas anteriores que usaremos la utilidad
Liquibase . Afortunadamente para nosotros, ¡es perfectamente capaz de integrarse con las aplicaciones Spring Boot! Para comenzar a usarlo, debe realizar los siguientes pasos
Agregue la configuración al archivo
application.properties spring.jpa.hibernate.ddl-auto=none
Esto es para garantizar que Hibernate no tome ninguna medida para modificar el circuito, ya que Liquibase los hará ahora. Teóricamente, aquí también puede usar el valor de
validación para un control adicional sobre la corrección de la estructura de la tabla.
Agregar una dependencia a
pom.xml <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> </dependency>
Después de agregarlo, Spring boot creará automáticamente un bean especial llamado liquibase, que realizará todas las acciones para configurar el esquema de la base de datos basado en los scripts de Liquibase cada vez que se inicie la aplicación.
Ahora debe agregar el script Liquibase, que creará la tabla que necesitamos. En la carpeta / src / main / resources / db / changelog, cree un archivo llamado db.changelog-master.yaml y agregue los siguientes contenidos
databaseChangeLog: - logicalFilePath: db/changelog/db.changelog-lesson1.yaml - changeSet: id: 1 author: your_liquibase_username changes: - createTable: tableName: users columns: - column: name: id type: BIGINT autoIncrement: true constraints: primaryKey: true nullable: false - column: name: username type: varchar(50) constraints: unique: true nullable: false - column: name: password type: varchar(512) constraints: nullable: false - column: name: first_name type: varchar(50) - column: name: last_name type: varchar(50) - column: name: email type: varchar(50)
Analicemos el contenido de este script. En primer lugar, contiene un cambio de conjunto. ChangeSet es un análogo de una confirmación en sistemas de control de versiones como Git o SVN. Por analogía con un commit, los cambios que se realizaron como parte de un changeSet se pueden transferir o volver al servidor de la base de datos. Cada changeSet debe tener un identificador único con el que Liquibase determina si un determinado changeSet se ha bombeado a esta base de datos o no.
ChangeSet contiene un comando para crear una tabla, y Liquibase describe la estructura de la tabla, y no un script SQL. Gracias a esto, este archivo se convierte en multiplataforma. Liquibase generará un script SQL dependiendo del servidor de base de datos utilizado. Además, si necesitamos revertir el changeSet dado, Liquibase podrá crear automáticamente un script para eliminar la tabla dada. Si utilizamos scripts SQL, entonces tendríamos que escribir manualmente un script para revertir los cambios. En la sección de
cambios , solo tenemos un equipo y esto se considera una buena práctica, a pesar del hecho de que puede haber cualquier número de equipos en un solo
cambio .
El código escrito es suficiente para ejecutar el programa, pero para ver más claramente los resultados de su trabajo, agreguemos otro
changeSet , que llenará la tabla con datos.
- changeSet: id: 2 author: your_liquibase_username comment: "Create admin user" changes: - insert: tableName: users columns: - column: name: username value: "admin" - column: name: password value: "admin" - column: name: email value: "admin@server.com" - insert: tableName: users columns: - column: name: username value: "guest" - column: name: password value: "guest" - column: name: email value: "guest@server.com" rollback: - delete: tableName: users where: username in ('admin', 'guest')
En este caso, ya teníamos que escribir manualmente un bloque para operaciones de reversión, como Liquibase no puede crear automáticamente SQL de reversión cuando se trabaja con datos. En general, trabajar con datos en la base de datos no se encuentra entre las características clave de Liquibase y se limita solo a las operaciones más simples de inserción, eliminación o cambio. Por cierto, si necesita más, aquí puede usar las herramientas de la compañía
Red Gate .
Entonces, ejecutemos nuestra aplicación e intentemos seguir el enlace
http: // localhost: 8080 / user / all . Si se inició la aplicación, verá una respuesta JSON con información sobre los dos usuarios que se agregaron a la tabla. También vale la pena echar un vistazo a los registros de inicio de la aplicación, en los que puede ver los scripts que Liquibase ejecuta para inicializar la base de datos. Se debe prestar especial atención a la tabla
DATABASECHANGELOG . Es allí donde Liquibase almacena el registro de los cambios realizados en la base de datos.
Eso es todo por ahora. Después de algún tiempo, planeo publicar una continuación sobre el uso de
liquibase-maven-plugin para generar automáticamente scripts al comparar las estructuras de la base de datos y revertir los cambios realizados.
Estaría agradecido por cualquier adición y comentario!
PS Código completo escrito basado en este artículo
github.com/usharik/spring-liquibase-demo/tree/part-1Continúa en
habr.com/en/post/460907