В данном уроке я бы хотел вам показать как работать с базой данных используя JPA API.
В уроке ‘Работа с базами данных с помощью JDBC драйвера‘ мы уже разбирали, как можно работать с БД прямыми SQL запросами, а также в ‘Как работать с MySQL в Java — Hibernate XML Mapping‘.
JPA облегчает работу программисту, так как берет на себя все заботы по работе с базой данных.
В этом уроке я покажу, как на основе классов строить базу данных, как выполнять CRUD(Create Read Update Delete) операции не используя SQL запросов.
Шаг 1
Создаем maven проект и добавляем следующую зависимость:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>JPAHiberanateExample</groupId> <artifactId>JPAHiberanateExample</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.25</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.2.1.Final</version> </dependency> <dependency> <groupId>org.hibernate.javax.persistence</groupId> <artifactId>hibernate-jpa-2.0-api</artifactId> <version>1.0.1.Final</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> </dependencies> </project>
Вы наверное заметили, что в зависимостях используется JUnit, с его помощью мы будем тестировать наши CRUD методы.
Шаг 2
Одной из крутых возможностей JPA – это создание таблиц в базе данных на основе существующий классов сущностей.
Entity – это сущность какого-то объекта, который можно описать некоторыми атрибутами.
В качестве предметной области мы возьмем магазин по продаже автомобилей.
Первая сущность это Автомобиль:
package com.devcolibri.entity; import java.util.Date; public class Car { private String name; //Название авто private Date releaseDate; //дата выпуска private float cost; //стоимость public Car(String name, Date releaseDate, float cost) { this.name = name; this.releaseDate = releaseDate; this.cost = cost; } public Car() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getReleaseDate() { return releaseDate; } public void setReleaseDate(Date releaseDate) { this.releaseDate = releaseDate; } public float getCost() { return cost; } public void setCost(float cost) { this.cost = cost; } @Override public String toString() { return "Car{" + "name='" + name + '\'' + ", releaseDate=" + releaseDate + ", cost=" + cost + '}'; } }
В сущности Car мы переопределили метод toString(), чтобы выводя объект в консоль мы видели его в человеческом виде.
Вторая сущность – это продавец:
package com.devcolibri.entity; public class Seller { private String fullName; // Полное имя private int age; // Возвраст private float salary; // Зар. плата public Seller(String fullName, int age, float salary) { this.fullName = fullName; this.age = age; this.salary = salary; } public Seller() { } public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public float getSalary() { return salary; } public void setSalary(float salary) { this.salary = salary; } @Override public String toString() { return "Seller{" + "fullName='" + fullName + '\'' + ", age=" + age + ", salary=" + salary + '}'; } }
Шаг 3
Теперь давайте создадим базу данных:
CREATE SCHEMA `carshop` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Шаг 4
Теперь нужно проаннотировать наши сущности я на примере Car класса.
package com.devcolibri.entity; import javax.persistence.*; import java.util.Date; @Entity @Table(name = "cars") @NamedQuery(name = "Car.getAll", query = "SELECT c from Car c") public class Car { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @Column(name = "name", length = 32) private String name; //Название авто @Column(name = "date") @Temporal(TemporalType.TIMESTAMP) private Date releaseDate; //дата выпуска @Column(name = "cost") private float cost; //стоимость public Car(String name, Date releaseDate, float cost) { this.name = name; this.releaseDate = releaseDate; this.cost = cost; } public Car() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getReleaseDate() { return releaseDate; } public void setReleaseDate(Date releaseDate) { this.releaseDate = releaseDate; } public float getCost() { return cost; } public void setCost(float cost) { this.cost = cost; } public long getId() { return id; } @Override public String toString() { return "Car{" + "id=" + id + ", name='" + name + '\'' + ", releaseDate=" + releaseDate + ", cost=" + cost + '}'; } }
В строке 8 вы увидите NamedNativeQuery – это запрос, который относится к сущности Car и с его помощью мы будем получать список всех машин в базе.
Шаг 4
Теперь создадим конфигурационный файл для JPA называется он ‘src\main\resources\META-INF\persistence.xml‘:
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="COLIBRI" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/carshop"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value="root"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit> </persistence>
Рассмотри параметры:
hibernate.connection.driver_class
– здесь мы говорим какой драйвер использовать для работы с базой данных;
hibernate.connection.url
– тут указываем URL к базе;
hibernate.connection.username
– имя пользователя этой базы;
hibernate.connection.password
– и его пароль;
hibernate.dialect
– тут мы устанавливаем диалект текущей БД, он дает возможность использовать возможность генерации ключей, он автоматизирует всю эту работу;
hibernate.hbm2ddl.auto
– тут статус работы JPA:
update – база будет просто обновлять свою структуру;
validate – проверяет структуру базы но не вносит изменения;
create – создает таблицы, но уничтожает предыдущие данные;
create-drop – создает таблицы в начале сеанса и удаляет их по окончанию сеанса.
Внимание!
Обратите внимание на тег persistence-unit атрибут name=”COLIBRI”, на это имя мы в дальнейшем будем создавать EntityManager для работы с Entity.
Теперь посмотрим структуру проекта:
Шаг 5
Создаем класс-сервис, который будет обеспечивать работу с БД CarService.java:
package com.devcolibri.crud; import com.devcolibri.entity.Car; import javax.persistence.EntityManager; import javax.persistence.Persistence; import javax.persistence.TypedQuery; import java.util.List; public class CarService { public EntityManager em = Persistence.createEntityManagerFactory("COLIBRI").createEntityManager(); public Car add(Car car){ em.getTransaction().begin(); Car carFromDB = em.merge(car); em.getTransaction().commit(); return carFromDB; } public void delete(long id){ em.getTransaction().begin(); em.remove(get(id)); em.getTransaction.commit(); } public Car get(long id){ return em.find(Car.class, id); } public void update(Car car){ em.getTransaction().begin(); em.merge(car); em.getTransaction().commit(); } public List<Car> getAll(){ TypedQuery<Car> namedQuery = em.createNamedQuery("Car.getAll", Car.class); return namedQuery.getResultList(); } }
В строке 36 мы вызываем NamedNativeQuery по его имени.
Если вы используете IntellijIdea, то должны увидеть, что в строке 36 подчеркивается красным Car.getAll так как ваш проект еще не знает, что вы используете JPA он не опознает эту запись.
Давайте укажем для нашего проекта, что мы используем JPA:
Заходим в File->Project Structure->Modules и в списке где ваш проект нажимаете по нему и выбираете New->JPA:
После жмем плюс и выбираем persistence.xml.
После этого у вас должно пропасть подчеркивание.
Шаг 6
Для класса CarService мы напишем следующий тестовый класс который проверит работоспособность методов:
package com.devcolibri.testing; import com.devcolibri.crud.CarService; import com.devcolibri.entity.Car; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.Date; import java.util.List; public class CarServiceTest { CarService service = new CarService(); @Test public void testSaveRecord() throws Exception { //Создаем автомобиль для записи в БД Car car1 = new Car(); car1.setName("BMW"); car1.setCost(20000); car1.setReleaseDate(new Date()); //Записали в БД Car car = service.add(car1); //Вывели записанную в БД запись System.out.println(car); } @Test public void testDeleteRecord() throws Exception { //Создаем автомобиль для записи в БД Car car1 = new Car(); car1.setName("Ferrari"); car1.setCost(100000); car1.setReleaseDate(new Date()); //Записуем его в БД Car car = service.add(car1); //Удвлем его с БД service.delete(car.getId()); } @Test public void testSelect() throws Exception { //Создаем автомобиль для записи в БД Car car1 = new Car(); car1.setName("Citroen"); car1.setCost(30000); car1.setReleaseDate(new Date()); //Записываем в БД Car car = service.add(car1); //Получние с БД Citroen Car carFromDB = service.get(car.getId()); System.out.println(carFromDB); } @Test public void testUpdate() throws Exception { //Создаем автомобиль для записи в БД Car car1 = new Car(); car1.setName("Lambordshini"); car1.setCost(5000000); car1.setReleaseDate(new Date()); //Записываем в БД car1 = service.add(car1); car1.setCost(0); //Обновляем service.update(car1); //Получаем обновленую запись Car car2 = service.get(car1.getId()); System.out.println(car2); } public void testGetAll(){ //Создаем автомобиль для записи в БД Car car1 = new Car(); car1.setName("Lexus"); car1.setCost(300000); car1.setReleaseDate(new Date()); //Создаем автомобиль для записи в БД Car car2 = new Car(); car2.setName("Fiat"); car2.setCost(20000); car2.setReleaseDate(new Date()); //Создаем автомобиль для записи в БД Car car3 = new Car(); car3.setName("Porsche"); car3.setCost(458000); car3.setReleaseDate(new Date()); //Сохраняем все авто service.add(car1); service.add(car2); service.add(car3); //Получаем все авто с БД List<Car> cars = service.getAll(); //Выводим полученый список авто for(Car c : cars){ System.out.println(c); } } }
ПОХОЖИЕ ПУБЛИКАЦИИ
- None Found
33 комментариев к статье "JPA работа с базой данных"