I den här artikeln kommer du att bli bekant med ett av de mest populära företagsramverken för Java och skapa din första Hibernate-applikation. Aldrig hört talas om Hibernate? Eller kanske du har hört talas om det, men inte använt det? Eller kanske du försökte använda den, men misslyckades? I alla tre fallen - välkommen till under snittet :)
Hej alla! I den här artikeln kommer jag att prata om Hibernate-ramverkets huvudfunktioner och hjälpa dig att skriva din första miniapplikation. För detta behöver vi:
Som du kan se, inget komplicerat. 6 klasser + 1 fil med konfigurationer. Skapa först ett nytt Maven-projekt i IntelliJ IDEA. Arkiv -> Nytt projekt. Välj Maven bland de föreslagna projekttyperna och gå vidare till nästa steg.
Apache Maven är ett ramverk för att automatiskt bygga projekt baserat på en beskrivning av deras struktur i POM-filer. Hela strukturen för ditt projekt kommer att beskrivas i pom.xml, en fil som IDEA själv kommer att skapa i roten av ditt projekt. I projektinställningarna måste du ange följande Maven-inställningar: groupId och artifactId. I projekt är groupId vanligtvis en beskrivning av företaget eller affärsenheten. Företagets eller webbplatsens domännamn kan gå här. I sin tur är artifactId namnet på projektet. För groupdId kan du ange
På den sista skärmen bekräftar du helt enkelt tidigare inmatade data.
Så vi skapade projektet. Nu återstår bara att skriva lite kod och få det att fungera :) Först och främst: om vi vill skapa en applikation som fungerar med en databas så klarar vi oss definitivt inte utan en databas! Ladda ner PostgreSQL härifrån ( jag använder version 9). PostgreSQL har en standardanvändare "postgres" — du måste komma på ett lösenord för det när du installerar. Glöm inte lösenordet. Vi behöver det senare! (I allmänhet är det dålig praxis att använda standarddatabasen i applikationer, men vi kommer att göra det för att minska antalet sår orsakar genom att skapa din egen databas). Om du inte är vän med kommandoraden och SQL-frågor finns det goda nyheter. IntelliJ IDEA ger ett helt passande användargränssnitt för att arbeta med databasen.
(finns på IDEAs högra fönster, fliken Databas). För att skapa en anslutning, klicka på "+" och välj vår datakälla (PostgeSQL). Fyll i fälten för användaren och databasen ("postgres" för båda) och ange lösenordet som angavs under installationen av PostgreSQL. Om det behövs, ladda ner Postgres-drivrutinen. Du kan göra detta på samma sida. Klicka på "Testa anslutning" för att verifiera att databasanslutningen är upprättad. Om du ser "Lyckad", gå vidare. Nu ska vi skapa de tabeller vi behöver. Det kommer att finnas totalt två: användare och bilar. Parametrar för användartabellen:
Observera att id är den primära nyckeln. Om du inte vet vad primärnyckeln är i SQL, googla det. Det här är viktigt. Inställningar för biltabell:
För biltabellen måste du konfigurera en främmande nyckel. Det kommer att tjäna till att länka våra tabeller. Jag rekommenderar att du läser mer om det. Enkelt uttryckt refererar det till en extern tabell, i vårt fall användare. Om en bil tillhör användaren med id = 1, så kommer fältet user_id för bilarna att vara lika med 1. Det är så vi associerar användare med deras bilar i vår applikation. I vår biltabell kommer fältet user_id att fungera som främmande nyckel. Det kommer att referera till id-fältet i användartabellen.
Så vi har skapat en databas med två tabeller. Det som återstår är att förstå hur man hanterar det från Java-kod. Vi börjar med filen pom.xml, där vi måste inkludera de nödvändiga biblioteken (i Maven kallas de beroenden). Alla bibliotek lagras i det centrala Maven-förrådet. Biblioteken du anger i pom.xml är tillgängliga för dig att använda i projektet. Din pom.xml ska se ut så här:
Inget komplicerat, som du kan se. Vi har bara lagt till två beroenden — för att använda PostgreSQL och Hibernate. Låt oss nu gå vidare till Java-koden. Skapa alla nödvändiga paket och klasser i projektet. För att börja behöver vi en datamodell: klasserna
@OneToMany-kommentaren hänger ovanför listan. Det betyder att flera bilar kan motsvara samma objekt i användarklassen. Elementet "mappedBy" refererar till klassens användarfält
Hibernate.cfg.xml läses här: ![Din första Hibernate-applikation - 13]()
Låt oss försöka byta namn på vår användare. Rensa användartabellen och kör koden
Vad händer om du tar bort användaren? Rensa användartabellen (autos rensar sig själv) och kör koden

- IntelliJ IDEA Ultimate Edition
Ladda ner den från den officiella webbplatsen och aktivera 30-dagars provversionen. - PostgreSQL - ett av de mest populära moderna databashanteringssystemen (DBMS)
- Maven (redan kopplad till IDEA)
- Lite tålamod.
Vad är Hibernate?
Det är en av de mest populära implementeringarna av objektrelationell mappning (ORM). En objektrelationell mappning definierar förhållandet mellan programvaruobjekt och databasposter. Naturligtvis har Hibernate mycket bred funktionalitet, men vi kommer att fokusera på de enklaste funktionerna. Vårt mål är att skapa en CRUD-applikation (Create, Read, Update, Delete) som kommer att kunna:- Skapa användare (Användare), sök efter dem i databasen med ID, uppdatera deras data i databasen och ta bort dem från databasen.
- Tilldela bilobjekt (Auto) till användare. Skapa, uppdatera, hitta och ta bort bilar från databasen.
- Dessutom bör applikationen automatiskt ta bort "ägarelösa" bilar från databasen. Med andra ord, när en användare raderas måste alla bilar som tillhör den användaren också tas bort från databasen.


com.yourNickname.codegym
. Detta kommer inte att ha någon effekt på applikationen. För artifactId, välj vilket projektnamn du vill. Versionen kan lämnas oförändrad. 






User
och .Auto
package models;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table (name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "name")
private String name;
// You can omit the Column attribute if the name property matches the column name in the table
private int age;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Auto> autos;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
autos = new ArrayList<>();
}
public void addAuto(Auto auto) {
auto.setUser(this);
autos.add(auto);
}
public void removeAuto(Auto auto) {
autos.remove(auto);
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<Auto> getAutos() {
return autos;
}
public void setAutos(List<Auto> autos) {
this.autos = autos;
}
@Override
public String toString() {
return "models.User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
package models;
import javax.persistence.*;
@Entity
@Table(name = "autos")
public class Auto {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column (name = "model")
private String model;
// You can omit the Column attribute if the name property matches the column name in the table
private String color;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
public Auto() {
}
public Auto(String model, String color) {
this.model = model;
this.color = color;
}
public int getId() {
return id;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return color + " " + model;
}
}
Som du kan se, klasser har med en massa obskyra kommentarer. Låt oss börja gräva i dem. För oss är huvudkommentaren @Entity. Läs om det på Wikipedia och lär dig allt utantill. Detta är grunden för stiftelsen. Den här anteckningen låter objekt i din Java-klass mappas till en databas. För att en klass ska vara en enhet måste den uppfylla följande krav:
- Den måste ha en tom konstruktor (
public
ellerprotected
) - Det kan inte vara kapslat, ett gränssnitt eller en
enum
- Det kan inte vara
final
och kan inte hafinal
fält/egenskaper - Den måste ha minst ett @Id-fält.
- Den kan ha icke-tomma konstruktörer
- Det kan ärva och gå i arv
- Den kan ha andra metoder och implementera gränssnitt.
User
är klassen väldigt lik användartabellen. Den har id
, name
, ochage
fält. Anteckningarna ovanför dem behöver ingen särskild förklaring: det är tydligt att @Id indikerar att fältet är en identifierare för objekt av denna klass. @Table-kommentaren ovanför klassen anger namnet på tabellen där objekten är skrivna. Notera kommentaren ovanför åldersfältet: om namnet på fältet i klassen är detsamma som namnet på tabellen kan du utelämna @Column-kommentaren så fungerar det. När det gäller den del som anges i klammerparenteserna ("strategy = GenerationType.IDENTITY"): det finns flera strategier för att generera ID:n. Du kan Google dem, men för vår ansökan behöver du inte bry dig. Huvudsaken är att för våra objekt kommer värdet av id att genereras automatiskt. Följaktligen finns det ingen setter för id, och vi ställer inte in den i konstruktorn heller. Dock,User
klass sticker ut. Den har en lista över bilar! 
Auto
. Således är bilar och användare relaterade. Elementet orphanRemoval anger om borttagningsåtgärden ska tillämpas på enheter som inte längre har en relation. Om vi tar bort en användare från databasen kommer även alla bilar som är kopplade till den att raderas. I sin tur iAuto
klass kommer du att se användarfältet med @ManyToOne-kommentaren (en användare kan motsvara många Autos) och @JoinColumn-kommentaren. Den indikerar vilken kolumn i autos-tabellen som används för att referera till användartabellen (dvs. den främmande nyckeln som vi pratade om tidigare). Efter att ha skapat datamodellen är det dags att lära vårt program att utföra operationer med data i databasen. Låt oss börja med verktygsklassen HibernateSessionFactoryUtil. Den har bara ett jobb — att skapa en sessionsfabrik för vår applikation att fungera med databasen (säg hej till Factory designmönster!). Den vet inte hur man gör något annat.
package utils;
import models.Auto;
import models.User;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateSessionFactoryUtil {
private static SessionFactory sessionFactory;
private HibernateSessionFactoryUtil() {}
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
Configuration configuration = new Configuration().configure();
configuration.addAnnotatedClass(User.class);
configuration.addAnnotatedClass(Auto.class);
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
} catch (Exception e) {
System.out.println("Исключение!" + e);
}
}
return sessionFactory;
}
}
I den här klassen skapar vi ett nytt konfigurationsobjekt och skickar det de klasser som det ska behandla som entiteter: User
och Auto
. Var uppmärksam på configuration.getProperties()
metoden. Vilka andra fastigheter finns det? Var kommer de ifrån? Egenskaper är vilolägesinställningarna som anges i den speciella hibernate.cfg.xml-filen. 
new Configuration().configure();
Som du ser är det inget speciellt med det: det innehåller parametrarna för att ansluta till databasen, såväl som parametern show_sql. Detta krävs för att alla sql-frågor som körs av Hibernate ska visas på konsolen. På så sätt kommer du att se exakt vad Hibernate gör vid varje givet ögonblick, vilket eliminerar all känsla av "magi". Därefter behöver viUserDAO
klass. Den bästa praxisen är att programmera genom gränssnitten — skapa ett separat UserDAO
gränssnitt och UserDAOImpl
implementering, men jag kommer att hoppa över detta för att minska mängden kod. Gör inte detta i riktiga projekt! DAO (data access object) designmönster är ett av de vanligaste. Tanken är enkel – skapa ett applikationslager som bara ansvarar för åtkomst till data, inget mer. Hämta data från databasen, uppdatera data, radera data — det är allt. Läs mer om DAO. Du kommer att använda dataåtkomstobjekt ständigt i ditt arbete. Vad kan vår UserDao
klass göra? Tja, som alla DAO:er kan det bara fungera med data. Hitta en användare med id, uppdatera dess data, ta bort den, få en lista över alla användare från databasen eller spara en ny användare i databasen – det är hela dess funktionalitet.
package dao;
import models.Auto;
import models.User;
import org.hibernate.Session;
import org.hibernate.Transaction;
import utils.HibernateSessionFactoryUtil;
import java.util.List;
public class UserDao {
public User findById(int id) {
return HibernateSessionFactoryUtil.getSessionFactory().openSession().get(User.class, id);
}
public void save(User user) {
Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
Transaction tx1 = session.beginTransaction();
session.save(user);
tx1.commit();
session.close();
}
public void update(User user) {
Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
Transaction tx1 = session.beginTransaction();
session.update(user);
tx1.commit();
session.close();
}
public void delete(User user) {
Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
Transaction tx1 = session.beginTransaction();
session.delete(user);
tx1.commit();
session.close();
}
public Auto findAutoById(int id) {
return HibernateSessionFactoryUtil.getSessionFactory().openSession().get(Auto.class, id);
}
public List<User> findAll() {
List<User> users = (List<User>) HibernateSessionFactoryUtil.getSessionFactory().openSession().createQuery("From User").list();
return users;
}
}
UserDao
s metoder liknar varandra. I de flesta av dem får vi ett Session -objekt (databasanslutningssession) med vår Session Factory, skapar en enda transaktion inom denna session, utför nödvändiga datamanipulationer, sparar resultatet av transaktionen i databasen och stänger sedan sessionen. Metoderna i sig, som du kan se, är ganska enkla. DAO är "hjärtat" i vår ansökan. Vi kommer dock inte att skapa en DAO direkt och anropa dess metoder i vår main()
metod. All logik kommer att flyttas till UserService
klassen.
package services;
import dao.UserDao;
import models.Auto;
import models.User;
import java.util.List;
public class UserService {
private UserDao usersDao = new UserDao();
public UserService() {
}
public User findUser(int id) {
return usersDao.findById(id);
}
public void saveUser(User user) {
usersDao.save(user);
}
public void deleteUser(User user) {
usersDao.delete(user);
}
public void updateUser(User user) {
usersDao.update(user);
}
public List<User> findAllUsers() {
return usersDao.findAll();
}
public Auto findAutoById(int id) {
return usersDao.findAutoById(id);
}
}
En tjänst är ett applikationsdatalager som ansvarar för att utföra affärslogik. Om ditt program behöver utföra någon form av affärslogik, gör det det genom tjänster. En tjänst innehåller en UserDao
och anropar DAO-metoder i sina metoder. Det kan tyckas som att vi duplicerar funktioner här (varför inte bara anropa metoderna från ett DAO-objekt?), men med många objekt och komplex logik ger skiktning av applikationen enorma fördelar (det är bra att göra det – kom ihåg detta i framtiden och läs om "applikationslager"). Vår tjänst har enkel logik, men servicemetoder i verkliga projekt innehåller mycket mer än en kodrad :) Nu har vi allt du behöver för att köra applikationen! I main()
metoden, låt oss skapa en användare och dess bil, associera den ena med den andra och spara dem i databasen.
import models.Auto;
import models.User;
import services.UserService;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws SQLException {
UserService userService = new UserService();
User user = new User ("Jenny", 26);
userService.saveUser(user);
Auto ferrari = new Auto("Ferrari", "red");
ferrari.setUser(user);
user.addAuto(ferrari);
Auto ford = new Auto("Ford", "black");
ford.setUser(user);
user.addAuto(ford);
userService.updateUser(user);
}
}
Som du kan se har användartabellen sin egen post, och biltabellen har sin egen post. 

import models.Auto;
import models.User;
import services.UserService;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws SQLException {
UserService userService = new UserService();
User user = new User ("Jenny", 26);
userService.saveUser(user);
Auto ferrari = new Auto("Ferrari", "red");
user.addAuto(ferrari);
Auto ford = new Auto("Ford", "black");
ford.setUser(user);
user.addAuto(ford);
userService.updateUser(user);
user.setName ("Benny");
userService.updateUser(user);
}
}
Det fungerar! 
import models.Auto;
import models.User;
import services.UserService;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws SQLException {
UserService userService = new UserService();
User user = new User ("Jenny", 26);
userService.saveUser(user);
Auto ferrari = new Auto("Ferrari", "red");
user.addAuto(ferrari);
Auto ford = new Auto("Ford", "black");
ford.setUser(user);
user.addAuto(ford);
userService.updateUser(user);
user.setName ("Benny");
userService.updateUser(user);
userService.deleteUser(user);
}
}
Och våra bord är helt tomma (var uppmärksam på konsolen - alla förfrågningar som utförs av Hibernate kommer att visas där). Du kan leka med applikationen och prova alla dess funktioner. Till exempel, skapa en användare med bilar, spara den i databasen, titta på det id som tilldelats användaren och försök använda detta id imain()
metod för att hämta användaren från databasen och visa en lista över dess bilar på konsolen. Naturligtvis har vi bara sett en liten del av Hibernates funktionalitet. Dess möjligheter är mycket breda, och det har länge varit ett standardverktyg för Java-utveckling. Om du vill studera det i detalj kan jag rekommendera boken "Java Persistence API and Hibernate". Jag recenserade i en tidigare artikel. Jag hoppas att den här artikeln har varit till hjälp för läsarna. Om du har frågor, ställ dem i kommentarerna. Jag svarar gärna :) Glöm inte heller att stötta författaren i tävlingen genom att lägga upp ett "Gilla". Eller ännu bättre — "Love it" :) Lycka till i dina studier!
GO TO FULL VERSION