Database Schema
Following diagram shows fields and relation between person and cars database table, where one person has more than one car, but one car must be owned by one person only.
|
One to Many Mapping between person and cars database table |
Configurations for database connections for Hibernate
We are doing hibernate configurations in application.properties file
# Database connection details
spring.datasource.url=jdbc:mysql://localhost:3306/here_your_db_name?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username=here_your_db_user_name
spring.datasource.password=here_your_db_user_password
# hibernate as JPA imlementation
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
# this to let the spring boot to perform database schema update when there is a changes in entity class
spring.jpa.hibernate.ddl-auto=update
Creating Entity classes
Here we need to create two entity classes for our database tables one is Person.java and another one is Car.java
@Entity
@Table(name = "person")
public class Person implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long pid;
@NotBlank(message = "Person name must not be empty")
private String pname;
private int pgender;
private Date pdob;
@OneToMany(mappedBy = "person_car", fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
@JsonManagedReference
private Set<Cars> cars = new HashSet<Cars>();
// add getter and seeter methods
// add hashCode and equal methods if required
}
Now were creating a Cars entity class
@Entity
@Table(name = "cars")
public class Cars implements Serializable {
@Column(name = "carid")
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long cid;
@Column(name = "carname")
String carname;
@Column(name="carcompany")
String manfac;
int pid;
@ManyToOne
@JsonBackReference
@JoinColumn(name = "ownerird")
Person person_car;
}
For better understanding while doing one to many mapping you can see the following figure
|
One to many mapping naming rules between entities |
1: mappedBy parameter value must be same as variable name of Person type in Cars class
2: JoinColumn name must be same as database column name ( FK name ) in cars table
DAO classes
We are going to crate DAO classes for Person and Cars
@Component
public interface CarsDAO {
Cars getCarByID(Long cid) throws Exception;
Cars addNewCar(Cars c );
}
@Component
public class CarsDAOImpl implements CarsDAO {
@Autowired
CarRepository carRepository;
@Override
public Cars getCarByID(Long cid) throws Exception {
// TODO Auto-generated method stub
return carRepository.findById(cid).orElseThrow(() -> new Exception("Couldn't find a person with id: " + cid));
}
@Override
public Cars addNewCar(Cars c) {
// TODO Auto-generated method stub
return carRepository.save(c);
}
}
@Component
public interface PersonsDAO<Person> {
List<Person> getAllPersons();
Person getPersonByID(long id) throws Exception;
Person addNewPerson(Person p);
void deletePersonByID(long id);
Person updatePerson(Person person);
}
@Component
public class PersonsDAOImpl implements PersonsDAO<Person> {
@Autowired
PersonRepository personRepository;
@Override
public List<Person> getAllPersons() {
// TODO Auto-generated method stub
return personRepository.findAll();
}
@Override
public Person getPersonByID(long id) throws Exception {
// TODO Auto-generated method stub
return personRepository.findById(id).orElseThrow(() -> new Exception("Couldn't find a person with id: " + id));
}
@Override
public Person addNewPerson(Person p) {
// TODO Auto-generated method stub
return personRepository.save(p);
}
@Override
public void deletePersonByID(long id) {
// TODO Auto-generated method stub
personRepository.deleteById(id);
}
@Override
public Person updatePerson(Person person) {
// TODO Auto-generated method stub
return personRepository.save(person);
}
}
Services Classes
@Service
public class PersonService<Person> {
@Autowired
PersonsDAO<Person> personsDAO;
@Autowired
PersonMapper personMapper;
public List<Person> getAllPersons() {
return personsDAO.getAllPersons();
}
public Person getPersonById(long id) throws Exception {
return personsDAO.getPersonByID(id);
}
public Person addNewPerson(Person p) {
return personsDAO.addNewPerson(p);
}
public void deletePersonByID(long id) {
personsDAO.deletePersonByID(id);
}
public Person updatePerson(Person person) {
return personsDAO.updatePerson(person);
}
public PersonDTO getPersonDTO(long pid) throws Exception {
Person sourcePerson = this.getPersonById(pid);
ModelMapper modelMapper = new ModelMapper();
modelMapper.addMappings(personMapper);
PersonDTO destinationPersonDTO = modelMapper.map(sourcePerson, PersonDTO.class);
return destinationPersonDTO;
}
}
@Service
public class CarService {
@Autowired
CarsDAOImpl carsDAOImpl;
@Autowired
PersonService<Person> personService;
public Cars getCarsByID(Long cid) throws Exception {
return carsDAOImpl.getCarByID(cid);
}
public Cars addNewCars(Cars cars) {
return carsDAOImpl.addNewCar(cars);
}
}
RestController
@RestController
@RequestMapping("/cars")
public class CarsController {
@Autowired
CarService carService;
@Autowired
PersonRepository personRepository;
@GetMapping("car/{id}")
public Cars getCarByID(@PathVariable(name = "id") Long cid) throws Exception {
return carService.getCarsByID(cid);
}
/**
* This handling method for adding new car by padding pid(personID) as a
* PathVariable is mandatory
*
* @param cars
* @param pid
* @return
*/
@PostMapping("/addNewCar/{ownerid}")
public Cars addNewCars(@RequestBody Cars cars, @PathVariable("ownerid") Long pid) {
return carService.addNewCars(personRepository.findById(pid).map((Person person1) -> {
cars.setPerson_car(person1);
return cars;
}).get());
}
/**
* This is the method for adding new car without passing pid( person_id ) as
* Pathvariable
*
* @param cars
* @return
*/
@PostMapping("/addNewCar")
public Cars addNewCars(@RequestBody Cars cars) {
return carService.addNewCars(personRepository.findById(cars.getPid()).map((Person person1) -> {
cars.setPerson_car(person1);
return cars;
}).get());
}
@PostMapping(value = { "/add", "/add/{ownerid}" })
public Cars addNewCar(@PathVariable(value = "ownerid", required = false) Long pid, @RequestBody Cars cars) {
pid = ((pid != null) ? pid : cars.getPid());
return carService.addNewCars(personRepository.findById(pid).map(p -> {
cars.setPerson_car(p);
return cars;
}).get());
}
/**
* Using Optional<T> as a pathvariable
* @param id
* @param cars
* @return
*/
@PostMapping(value = { "/addC", "/addC/{pid}" })
public Cars addNewCarsOptional(@PathVariable(value = "pid") Optional<Long> id, @RequestBody Cars cars) {
Long pid = (Long) (id.isPresent() ? id.get() : cars.getPid());
return carService.addNewCars(personRepository.findById(pid).map(p -> {
cars.setPerson_car(p);
return cars;
}).get());
}
/**
* Using Map<T,U> as a pathvariable
* @param id
* @param cars
* @return
*/
@PostMapping(value = { "/addCMap", "/addCMap/{pid}" })
public Cars addNewCarsMap(@PathVariable Map<String, String> id, @RequestBody Cars cars) {
Long pid = (id.get("pid")!=null ? Long.parseLong(id.get("pid")) : cars.getPid());
return carService.addNewCars(personRepository.findById(pid).map(p -> {
cars.setPerson_car(p);
return cars;
}).get());
}
}
Output screens
|
Adding new car with person id in path variable |
|
Adding new car where person id is a part of request body, that means not as pathavariable |
|
Get all persons details with cars owned |
Further Reading
Post a Comment
Post a Comment