En este tutorial vamos a aprender a crear un CRUD usando Spring Boot con la base de datos de MySQL. Crearemos una API REST que desarrolle las peticiones CRUD (Create, Read, Update, Delete) usando el Framework Backend de Java.
Crear proyecto
Es el link para generar proyecto
Properties
src\main\resources\application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/springboot
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Indica si debe mostrar el log de las consultas sql ejecutadas
spring.jpa.show-sql: true
# Configurar Hibernate
spring.jpa.hibernate.ddl-auto: update
# he SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.hibernate.dialect: org.hibernate.dialect.MySQL5Dialect
# mostrar sql
spring.jpa.properties.hibernate.format_sql=true
# mostrar el error de sql
logging.level.org.hibernate.SQL=DEBUG
Dependencias
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependency>
Entity
Primero crear el modelo entity donde se encarga definir los campos y tipo de datos.
src\main\java\com\tutofox\demo\entity\Person.java
package com.tutofox.demo.entity; import java.io.Serializable; import java.util.Date; import org.hibernate.validator.constraints.Length; import org.springframework.data.annotation.CreatedDate; import jakarta.persistence.Column; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; import jakarta.persistence.Temporal; import jakarta.persistence.TemporalType; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.NotBlank; import jakarta.persistence.Entity; @Entity @Table(name="persons") public class Person implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "id") private Long id; @NotBlank @Column(name = "name") private String name; @Column(name = "address") private String address; @Column(name = "phone") private Integer phone; @Column(name="create_at") @CreatedDate private Date createAt; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Integer getPhone() { return phone; } public void setPhone(Integer phone) { this.phone = phone; } public Date getCreateAt() { return createAt; } public void setCreateAt(Date createAt) { this.createAt = createAt; } }
Dao
Dao es un objeto de acceso a datos que trae todos los métodos de consultas.
src\main\java\com\tutofox\demo\repository\PersonDao.java
package com.tutofox.demo.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.tutofox.demo.entity.Person; public interface PersonDao extends JpaRepository<Person, Long> { }
Services / Servicios
El servicio es el encargado donde comunica entre el controlador y repositorio donde se encarga las consultas.
src\main\java\com\tutofox\demo\services\PersonServiceImpl.java
package com.tutofox.demo.services; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.tutofox.demo.entity.Person; import com.tutofox.demo.repository.PersonDao; import jakarta.transaction.Transactional; @Service public class PersonServiceImpl implements PersonService{ @Autowired private PersonDao personDao; @Override @Transactional public List<Person> findAll() { return (List<Person>) personDao.findAll(); } @Override @Transactional public Person save(Person person) { return personDao.save(person); } @Override public Person findById(Long id) { return personDao.findById(id).orElse(null); } @Override @Transactional public void delete(Person person) { personDao.delete(person); } }
src\main\java\com\tutofox\demo\services\PersonService.java
package com.tutofox.demo.services; import java.util.List; import com.tutofox.demo.entity.Person; public interface PersonService { public List<Person> findAll(); public Person save(Person person); public Person findById(Long id); public void delete(Person person); }
Controller / Controlador
El controlador es el que encarga la interacción de API y realiza las solicitudes al servicio que trae los datos y retorna la respuesta de peticón.
src\main\java\com\tutofox\demo\controller\PersonController.java
package com.tutofox.demo.controller; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.tutofox.demo.entity.Person; import com.tutofox.demo.services.PersonService; @RestController @RequestMapping("/api/v1") public class PersonController { @Autowired private PersonService personService; @GetMapping(value="/persons") public ResponseEntity<Object> get(){ Map<String, Object> map = new HashMap<String, Object>(); try { List<Person> list = personService.findAll(); return new ResponseEntity<Object>(list,HttpStatus.OK); } catch (Exception e) { map.put("message", e.getMessage()); return new ResponseEntity<>( map, HttpStatus.INTERNAL_SERVER_ERROR); } } @GetMapping(value="/persons/{id}") public ResponseEntity<Object> getById(@PathVariable Long id){ try { Person data = personService.findById(id); return new ResponseEntity<Object>(data,HttpStatus.OK); } catch (Exception e) { Map<String, Object> map = new HashMap<String, Object>(); map.put("message", e.getMessage()); return new ResponseEntity<>( map, HttpStatus.INTERNAL_SERVER_ERROR); } } @PostMapping(value="/persons") public ResponseEntity<Object> create(@RequestBody Person person){ Map<String, Object> map = new HashMap<String, Object>(); try { Person res = personService.save(person); return new ResponseEntity<Object>(res,HttpStatus.OK); } catch (Exception e) { map.put("message", e.getMessage()); return new ResponseEntity<>( map, HttpStatus.INTERNAL_SERVER_ERROR); } } @PutMapping("/persons/{id}") public ResponseEntity<Object> update(@RequestBody Person person, @PathVariable Long id){ Map<String, Object> map = new HashMap<String, Object>(); try { Person currentPerson = personService.findById(id); currentPerson.setName(person.getName()); currentPerson.setAddress(person.getAddress()); currentPerson.setPhone(person.getPhone()); Person res = personService.save(person); return new ResponseEntity<Object>(res,HttpStatus.OK); } catch (Exception e) { map.put("message", e.getMessage()); return new ResponseEntity<>( map, HttpStatus.INTERNAL_SERVER_ERROR); } } @DeleteMapping("/persons/{id}") public ResponseEntity<Object> delete(@PathVariable Long id){ Map<String, Object> map = new HashMap<String, Object>(); try { Person currentPerson = personService.findById(id); personService.delete(currentPerson); map.put("deleted", true); return new ResponseEntity<Object>(map,HttpStatus.OK); } catch (Exception e) { map.put("message", e.getMessage()); return new ResponseEntity<>( map, HttpStatus.INTERNAL_SERVER_ERROR); } } }