Merhaba, bu yazımızda spring boot projesi ile jpa repositoryi kullanarak mysql veritabanına nasıl erişebileceğimizden bahsediyor olacağım.
Öncelikle kullandığınız ide üzerinden spring initializr ile bir proje oluşturalım. Eğer spring üzerinde çok fazla hakimiyetiniz yoksa Spring Tool Suite kullanabilirsiniz. Spring Tool Suite spring teknolojilerine özelleştirilmiş bir idedir.
Oluşturduğumuz projede pom.xml dosyasını açarak dependency etiketlerinin arasına aşağıdaki maven dependencyleri ekliyoruz.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
src/main/resources dosyası içinde application.properties adında bir dosya oluşmuştur. Ben properties yerine yaml uzantılı dosyayı tercih ediyorum. Çünkü yaml uzantılı dosyada hiyerarşiyi daha net bir şekilde görebiliyoruz.
Application.yaml dosyasına aşağıdaki bilgileri ekliyoruz.
spring:
application:
name: Jpa Repository
jpa:
generate-ddl: true
show-sql: true
hibernate:
ddl-auto: update
dialect: org.hibernate.dialect.MySQL5Dialect
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://MySqlDatabaseUrl:3306/DatabaseName?requireSSL=false&useSSL=false
username: username
password: password
Url alanındaki MySqlDatabaseUrl yerine database ip ve url bilgisini ekliyoruz. DatabaseName yerineyse database adını ekliyoruz. username ve password alanlarını dolduruyoruz.
Tüm alanlarımızı doldurduktan sonra konfigurasyonumuzu tamamlamış bulunmaktayız. Projemiz içerisinde repository adında bir dosya oluşturuyoruz. Bunun içerisine entity ve service adında iki dosya daha oluşturuyoruz.
Entity dosyamızın içerisine UserInfos adında aşağıdaki gibi bir sınıf oluşturuyoruz. Sınıfın üzerine @Entity anotasyonu ekliyoruz. Bu anotasyon bu sınıfın bir veritabanı tablosu olduğu anlamına gelmektedir.
package com.caglartelef.jparepository.repository.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
* This class is the table on database.
* */
@Entity
public class UserInfos {
/**
* id is auto generated value.
*
* */
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String password;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Repository dosyası içerisine IRepository adında bir interface oluşturup bunuda JpaRepository interfaceden extends ediyoruz. @Repository anotasyonu bu sınıfın bir dao yada persistence olduğunu belirtir. Spring metotlarımızı eklemek istediğimizde spring bize metot isimlerini önerecektir ve metotların isimlerine göre database işlemini gerçekleştirecektir.
package com.caglartelef.jparepository.repository;
import com.caglartelef.jparepository.repository.entity.UserInfos;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface IRepository extends JpaRepository<UserInfos, Integer> {
/**
* We extended our interface from JpaRepository
* Library will recommend query parameters to us.
* */
UserInfos findUserByEmailAndPassword(String email, String password);
}
Service dosyasının içerisine RepositoryService adında bir sınıf oluşturuyoruz. @Service anotasyonunu sınıfın en üstüne ekliyoruz. @Service anotasyonu sınıfın servise katmanında çalışacak bir sınıf olduğu anlamına gelmektedir.
Service katmanında diğer alt katmanlardan gelen exceptionları handle ederek daha anlamlı bir hale getirebiliriz. Bunun için getUser metotunda database katmanında herhangi bir hata olduğu durumda üst katmanlara daha anlamlı olabilecek bir exception ve mesajı gönderiyoruz.
package com.caglartelef.jparepository.repository.service;
import com.caglartelef.jparepository.exceptions.exceptions.RepositoryException;
import com.caglartelef.jparepository.repository.entity.UserInfos;
import com.caglartelef.jparepository.repository.IRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class RepositoryService {
@Autowired
private IRepository userRepository;
/**
* This method goes to the database on the our repository and retrieves user information.
* */
public boolean getUser(String email, String password) {
try {
UserInfos userInfo = userRepository.findUserByEmailAndPassword(email, password);
return email.equals(userInfo.getEmail()) && password.equals(userInfo.getPassword());
} catch (Exception ex) {
/**
* When the database throws an error message, we catch it.
* We throw a special error message by turning it into a meaningful message.
* */
throw new RepositoryException("User not found!");
}
}
}
Projemiz içerisinde exception ve controller adında iki tane daha dosya oluşturuyoruz. Exception dosyası içerisine exceptions ve handling adında iki tane daha dosya oluşturuyoruz. Exceptions dosyasının içerisine aşağıdaki gibi bir exception tanımlıyoruz.
package com.caglartelef.jparepository.exceptions.exceptions;
public class RepositoryException extends RuntimeException {
/**
* Custom exception class
* */
public RepositoryException(String message) {
super(message);
System.out.println(message); // Loglama işlemi
}
}
Exception sınıfında yapıcı metodun içerisinde gelen mesajı loglamak için çok uygun bir yer. Böylelikle bu exception neden alınmış takip etmeniz daha kolay olacaktır.
Handling dosyası içerisine aşağıdaki gibi bir GlobalExceptionsHandler sınıfı tanımlıyoruz.
package com.caglartelef.jparepository.exceptions.handling;
import com.caglartelef.jparepository.exceptions.exceptions.RepositoryException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/***
* Global exception handler.
* This catcher only captures the error message from classes that use @RestController annotation.
*/
@RestControllerAdvice
public class GlobalExceptionsHandler {
/**
* When the system throws an RepositoryException, we catch it.
* We throw a special error message by turning it into a meaningful message.
* */
@ResponseStatus(HttpStatus.BAD_REQUEST)/*Exception response status*/
@ExceptionHandler(RepositoryException.class) /*Custom exception class*/
public String handleRepositoryException(RepositoryException exception) {
return exception.getMessage();
}
}
@RestControllerAdvice anotasyonunu GlobalExceptionsHandler sınıfının en üstüne ekliyoruz. Bu anotasyon @RestController anotasyonunu kullanan controllerlardan ve alt sınıflarında gelen exceptionları yakalar. Böylelikle exceptionlarımızı global olarak handle edebilme şanşımız olacaktır.
Son olarak controller dosyası içerisine bir aşağıdaki gibi bir sınıf ekliyoruz.
package com.caglartelef.jparepository.controller;
import com.caglartelef.jparepository.repository.service.RepositoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/login")
public class LoginController {
@Autowired
RepositoryService repositoryService;/*Respository servisini controller içerisine create ediyoruz.*/
@GetMapping
public boolean login(@RequestParam(name = "email") String email, @RequestParam(name = "password") String password) {
return repositoryService.getUser(email, password);
}
}
Controller ekledikten sonra projemiz çalıştırılmak için hazırdır. Projemizi shift+F10 ile run ediyoruz. Projemiz ayağa kalktıktan sonra browserdan localhost:8080/login?email=info@caglartelef.com&password=12345 url ile erişilebiliriz.
Sonuç olarak projemiz ayağa kalktığı zaman MySql databasemizde UserInfos adında bir tablo oluşturacaktır. Proje içerisinden de IRepository interface aracılığla istediğimiz gibi sorgular ekleyebiliriz.
Projenin Github linki için TIKLAYINIZ.
İyi günler, iyi kodlamalar. 🙂