Arquitetura do Sistema
A plataforma de adoção e resgate de animais foi desenvolvida utilizando uma arquitetura full-stack, combinando o backend em Spring Boot com o frontend em Vue.js, além do MyBatis como camada de persistência de dados.
Backend: Spring Boot
O Spring Boot é um framework que acelera a criação de aplicações Java baseadas no ecossistema Spring, permitindo que os desenvolvedores construam aplicações autônomas prontas para produção com mínima configuração manual. Através do princípio de convenção sobre configuração, o framework reduz drasticamente o código boilerplate, oferecendo configurações padrão para componentes comuns em projetos de grande escala.
Entre os principais benefícios estão a configuração automática de servidores embarcados como Tomcat, Jetty ou Undertow, eliminando a necessidade de deploy em servidores externos, e a autoconfiguração inteligente de beens com base nas dependências presentes no classpath.
Frontend: Vue.js
Vue.js é um framework JavaScript progressivo para construção de interfaces de usuário. Sua arquitetura baseia-se em três pilares fundamentais: reatividade de dados, Virtual DOM e componentização. O sistema reativo permite que qualquer alteração nos dados seja automaticamente refletida na interface, dispensando manipulação manual do DOM.
O Virtual DOM atua como uma representação em memória da estrutura da página, permitindo que o framework calcule as diferenças entre estados anteriores e atuais da interface, aplicando apenas as mudanças necesárias no DOM real. Isso resulta em renderizações significativamente mais performáticas.
Persistência: MyBatis
O MyBatis é um framework de mapeamento objeto-relacional que separa as instruções SQL do código Java através de arquivos XML ou anotações. Essa separação promove maior flexibilidade no controle das queries executadas no banco de dados.
Os destaques do MyBatis incluem:
- Mapeamento declarativo: associa objetos Java a tabelas do banco sem necessidade de escrita manual de JDBC repetitivo;
- SQL dinâmico: permite construir consultas condicionais em tempo de execução através de tags como
<if>,<choose>e<foreach>; - Cache de múltiplos níveis: disponibiliza cache de primeiro nível (sessão) e segundo nível (aplicação), reduzindo acessos desnecessários ao banco;
- Extensibilidade via plugins: possibilita interceptar chamadas de métodos para adicionar comportamentos personalizados como paginação ou auditoria.
Implementação do Controlador de Resgate
Abaixo está um exemplo do controlador responsável por gerenciar os registros de resgate de animais, implementado com Spring Boot e MyBatis-Plus:
package com.petrescue.api.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.petrescue.api.common.ApiResponse;
import com.petrescue.api.config.annotation.PublicAccess;
import com.petrescue.api.model.RescueRecord;
import com.petrescue.api.service.RescueRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
/**
* Controlador para gestão de registros de resgate animal
*/
@RestController
@RequestMapping("/api/rescues")
public class RescueController {
private final RescueRecordService rescueService;
@Autowired
public RescueController(RescueRecordService rescueService) {
this.rescueService = rescueService;
}
@PostMapping
public ApiResponse<Void> createOrUpdate(@RequestBody RescueRecord record) {
rescueService.saveOrUpdate(record);
return ApiResponse.ok();
}
@DeleteMapping("/{recordId}")
public ApiResponse<Void> remove(@PathVariable Long recordId) {
rescueService.deleteById(recordId);
return ApiResponse.ok();
}
@PostMapping("/bulk-remove")
public ApiResponse<Void> removeBatch(@RequestBody Collection<Long> recordIds) {
rescueService.removeAllByIds(recordIds);
return ApiResponse.ok();
}
@GetMapping
public ApiResponse<?> list() {
return ApiResponse.ok(rescueService.fetchAll());
}
@GetMapping("/{recordId}")
public ApiResponse<RescueRecord> getById(@PathVariable Long recordId) {
return ApiResponse.ok(rescueService.fetchById(recordId));
}
@PublicAccess
@GetMapping("/search")
public ApiResponse<?> searchPaginated(
@RequestParam(required = false, defaultValue = "") String keyword,
@RequestParam int pageNumber,
@RequestParam int itemsPerPage
) {
LambdaQueryWrapper<RescueRecord> wrapper = new LambdaQueryWrapper<>();
wrapper.orderByDesc(RescueRecord::getId);
if (!keyword.isEmpty()) {
wrapper.like(RescueRecord::getTitle, keyword);
}
Page<RescueRecord> resultPage = new Page<>(pageNumber, itemsPerPage);
return ApiResponse.ok(rescueService.fetchPage(resultPage, wrapper));
}
}
Estrutura do Banco de Dados
O schema do banco de dados é composto por tabelas para gerenciar adoções, cadastro de animais e solicitações de adoção:
-- Tabela de adoções
DROP TABLE IF EXISTS `adoption_records`;
CREATE TABLE `adoption_records` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Identificador único',
`pet_id` int(11) NOT NULL COMMENT 'Referência ao animal',
`adoption_state` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT 'Situação da adoção',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC;
-- Tabela de animais cadastrados
DROP TABLE IF EXISTS `pets`;
CREATE TABLE `pets` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Identificador único',
`pet_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Nome do animal',
`gender` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Sexo',
`species` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Espécie',
`age_info` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Idade',
`photo_url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Foto',
`location` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Local de atividade',
`health_status` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Estado de saúde',
`neutered` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Castrado',
`vaccinated` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Vacinação',
`available_for_adoption` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Disponibilidade',
`description` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Observações',
`adopted` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Já adotado',
`likes` int(11) DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC;
INSERT INTO `pets` VALUES
(1,'Mimi','Macho','Gato','2 anos','/img/mimi.png','Ambiente interno','Saudável','Sim','Vacinado','Disponível','Dócil e calmo','Não',1),
(2,'Shiro','Macho','Cachorro','12 meses','/img/shiro.jpg','Ambiente misto','Saudável','Não','Não vacinado','Indisponível','Brincalhão','Sim',2),
(3,'Loki','Macho','Husky','12 meses','/img/loki.jpg','Ambiente misto','Saudável','Não','Vacinado','Disponível','Energético','Não',0),
(4,'Luna','Fêmea','British Shorthair','6 meses','/img/luna.jpg','Ambiente interno','Saudável','Não','Vacinado','Disponível','Filhote adorável','Não',0);
-- Tabela de solicitações de adoção
DROP TABLE IF EXISTS `adoption_requests`;
CREATE TABLE `adoption_requests` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Identificador único',
`applicant_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Nome do solicitante',
`applicant_gender` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Gênero',
`applicant_age` int(11) DEFAULT NULL COMMENT 'Idade',
`prior_experience` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Experiência com animais',
`current_pets` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Pets atuais',
`contact_number` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Telefone',
`marital_status` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Estado civil',
`monthly_income` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Renda mensal',
`occupation` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Profissão',
`residence` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Endereço',
`motivation` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Motivo da adoção',
`review_state` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'Pendente' COMMENT 'Status da revisão',
`target_pet_id` int(11) DEFAULT NULL COMMENT 'Animal solicitado',
`submitter_id` int(11) DEFAULT NULL COMMENT 'ID do usuário',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC;
INSERT INTO `adoption_requests` VALUES
(1,'Carlos Silva','Masculino',29,'Sem experiência',NULL,'15877777777','Solteiro','5000+','Desenvolvedor','São Paulo','Apaixonado por animais','Reprovado',2,2),
(2,'Ana Costa','Feminino',29,'Com experiência',NULL,'15877777777','Casada','9000+','Analista','São Paulo','Amor por animais','Aprovado',2,3);