Добавлен Hybernate и реализован прототип БД
This commit is contained in:
@@ -2,15 +2,27 @@ version: '3.8'
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
db:
|
db:
|
||||||
image: postgres:latest
|
image: postgres:16-alpine
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: your_database
|
POSTGRES_DB: rosetta_db
|
||||||
POSTGRES_USER: your_user
|
POSTGRES_USER: rosetta_user
|
||||||
POSTGRES_PASSWORD: your_password
|
POSTGRES_PASSWORD: rosetta_password
|
||||||
ports:
|
ports:
|
||||||
- "5432:5432"
|
- "5432:5432"
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U rosetta_user"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
adminer:
|
adminer:
|
||||||
image: adminer
|
image: adminer
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
22
pom.xml
22
pom.xml
@@ -16,13 +16,31 @@
|
|||||||
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.java-websocket</groupId>
|
<groupId>org.java-websocket</groupId>
|
||||||
<artifactId>Java-WebSocket</artifactId>
|
<artifactId>Java-WebSocket</artifactId>
|
||||||
<version>1.6.0</version>
|
<version>1.6.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Hibernate ORM -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate.orm</groupId>
|
||||||
|
<artifactId>hibernate-core</artifactId>
|
||||||
|
<version>6.4.0.Final</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- PostgreSQL JDBC Driver -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.7.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Jakarta Persistence API -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.persistence</groupId>
|
||||||
|
<artifactId>jakarta.persistence-api</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
29
src/main/java/com/rosetta/im/database/BaseEntity.java
Normal file
29
src/main/java/com/rosetta/im/database/BaseEntity.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package com.rosetta.im.database;
|
||||||
|
|
||||||
|
public class BaseEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сохраняет сущность в базе данных.
|
||||||
|
* @param entity Сущность для сохранения.
|
||||||
|
*/
|
||||||
|
public void save(Object entity) {
|
||||||
|
DatabaseManager.save(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обновляет сущность в базе данных.
|
||||||
|
* @param entity Сущность для обновления.
|
||||||
|
*/
|
||||||
|
public void update(Object entity) {
|
||||||
|
DatabaseManager.update(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Удаляет сущность из базы данных.
|
||||||
|
* @param entity Сущность для удаления.
|
||||||
|
*/
|
||||||
|
public void delete(Object entity) {
|
||||||
|
DatabaseManager.delete(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
80
src/main/java/com/rosetta/im/database/DatabaseManager.java
Normal file
80
src/main/java/com/rosetta/im/database/DatabaseManager.java
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package com.rosetta.im.database;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DatabaseManager {
|
||||||
|
|
||||||
|
public static <T> T save(T entity) {
|
||||||
|
Session session = HibernateUtil.openSession();
|
||||||
|
Transaction transaction = null;
|
||||||
|
try {
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
session.persist(entity);
|
||||||
|
transaction.commit();
|
||||||
|
return entity;
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (transaction != null) {
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Error saving entity: " + e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T update(T entity) {
|
||||||
|
Session session = HibernateUtil.openSession();
|
||||||
|
Transaction transaction = null;
|
||||||
|
try {
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
session.merge(entity);
|
||||||
|
transaction.commit();
|
||||||
|
return entity;
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (transaction != null) {
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Error updating entity: " + e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T findById(Class<T> entityClass, Long id) {
|
||||||
|
Session session = HibernateUtil.openSession();
|
||||||
|
try {
|
||||||
|
return session.find(entityClass, id);
|
||||||
|
} finally {
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> findAll(Class<T> entityClass) {
|
||||||
|
Session session = HibernateUtil.openSession();
|
||||||
|
try {
|
||||||
|
return session.createQuery("FROM " + entityClass.getSimpleName(), entityClass).list();
|
||||||
|
} finally {
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void delete(T entity) {
|
||||||
|
Session session = HibernateUtil.openSession();
|
||||||
|
Transaction transaction = null;
|
||||||
|
try {
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
session.remove(entity);
|
||||||
|
transaction.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (transaction != null) {
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Error deleting entity: " + e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/main/java/com/rosetta/im/database/HibernateUtil.java
Normal file
33
src/main/java/com/rosetta/im/database/HibernateUtil.java
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package com.rosetta.im.database;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
|
||||||
|
public class HibernateUtil {
|
||||||
|
private static final SessionFactory sessionFactory;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
sessionFactory = new Configuration().configure().buildSessionFactory();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ExceptionInInitializerError("Error initializing Hibernate: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SessionFactory getSessionFactory() {
|
||||||
|
return sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Session getCurrentSession() {
|
||||||
|
return sessionFactory.getCurrentSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Session openSession() {
|
||||||
|
return sessionFactory.openSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void shutdown() {
|
||||||
|
sessionFactory.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.rosetta.im.database.converters;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jakarta.persistence.AttributeConverter;
|
||||||
|
import jakarta.persistence.Converter;
|
||||||
|
|
||||||
|
@Converter
|
||||||
|
public class StringListConverter implements AttributeConverter<List<String>, String> {
|
||||||
|
@Override
|
||||||
|
public String convertToDatabaseColumn(List<String> attribute) {
|
||||||
|
if (attribute == null || attribute.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return String.join(",", attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> convertToEntityAttribute(String dbData) {
|
||||||
|
if (dbData == null || dbData.isBlank()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
return new ArrayList<>(Arrays.asList(dbData.split(",")));
|
||||||
|
}
|
||||||
|
}
|
||||||
229
src/main/java/com/rosetta/im/database/entity/User.java
Normal file
229
src/main/java/com/rosetta/im/database/entity/User.java
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
package com.rosetta.im.database.entity;
|
||||||
|
|
||||||
|
import com.rosetta.im.database.BaseEntity;
|
||||||
|
import com.rosetta.im.database.HibernateUtil;
|
||||||
|
import com.rosetta.im.database.converters.StringListConverter;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Convert;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Index;
|
||||||
|
import jakarta.persistence.PrePersist;
|
||||||
|
import jakarta.persistence.PreUpdate;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "users", indexes = {
|
||||||
|
@Index(name = "idx_users_publickey", columnList = "publicKey", unique = true)
|
||||||
|
})
|
||||||
|
public class User extends BaseEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "privateKey", nullable = false)
|
||||||
|
private String privateKey;
|
||||||
|
|
||||||
|
@Column(name = "username")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Column(name = "title")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Column(name = "publicKey", nullable = false, unique = true)
|
||||||
|
private String publicKey;
|
||||||
|
|
||||||
|
@Column(name = "timestamp", nullable = false)
|
||||||
|
private long timestamp;
|
||||||
|
|
||||||
|
@Column(name = "createdTime", nullable = false, updatable = false)
|
||||||
|
private Date createdTime;
|
||||||
|
|
||||||
|
@Column(name = "verified", nullable = false)
|
||||||
|
private int verified;
|
||||||
|
|
||||||
|
@Convert(converter = StringListConverter.class)
|
||||||
|
@Column(name = "notificationsTokens", nullable = false)
|
||||||
|
private List<String> notificationsTokens = new ArrayList<>();
|
||||||
|
|
||||||
|
@PrePersist
|
||||||
|
protected void onCreate() {
|
||||||
|
createdTime = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreUpdate
|
||||||
|
protected void onUpdate() {
|
||||||
|
if (createdTime == null) {
|
||||||
|
createdTime = new Date();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivateKey(String privateKey) {
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPublicKey() {
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublicKey(String publicKey) {
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(long timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreatedTime() {
|
||||||
|
return createdTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVerified() {
|
||||||
|
return verified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVerified(int verified) {
|
||||||
|
this.verified = verified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getNotificationsTokens() {
|
||||||
|
return notificationsTokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNotificationsTokens(List<String> notificationsTokens) {
|
||||||
|
this.notificationsTokens = notificationsTokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static User getByPrivateKey(String privateKey) {
|
||||||
|
try (Session session = HibernateUtil.openSession()) {
|
||||||
|
return session.createQuery(
|
||||||
|
"from User where privateKey = :privateKey", User.class)
|
||||||
|
.setParameter("privateKey", privateKey)
|
||||||
|
.uniqueResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static User getByUsername(String username) {
|
||||||
|
try (Session session = HibernateUtil.openSession()) {
|
||||||
|
return session.createQuery(
|
||||||
|
"from User where username = :username", User.class)
|
||||||
|
.setParameter("username", username)
|
||||||
|
.uniqueResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static User getByPublicKey(String publicKey) {
|
||||||
|
try (Session session = HibernateUtil.openSession()) {
|
||||||
|
return session.createQuery(
|
||||||
|
"from User where publicKey = :publicKey", User.class)
|
||||||
|
.setParameter("publicKey", publicKey)
|
||||||
|
.uniqueResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addNotificationToken(String privateKey, String token) {
|
||||||
|
Session session = HibernateUtil.openSession();
|
||||||
|
Transaction transaction = null;
|
||||||
|
try {
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
User user = session.createQuery(
|
||||||
|
"from User where privateKey = :privateKey", User.class)
|
||||||
|
.setParameter("privateKey", privateKey)
|
||||||
|
.uniqueResult();
|
||||||
|
if (user != null) {
|
||||||
|
if (!user.notificationsTokens.contains(token)) {
|
||||||
|
user.notificationsTokens.add(token);
|
||||||
|
session.merge(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transaction.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (transaction != null) {
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Error adding notification token: " + e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeNotificationToken(String privateKey, String token) {
|
||||||
|
Session session = HibernateUtil.openSession();
|
||||||
|
Transaction transaction = null;
|
||||||
|
try {
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
User user = session.createQuery(
|
||||||
|
"from User where privateKey = :privateKey", User.class)
|
||||||
|
.setParameter("privateKey", privateKey)
|
||||||
|
.uniqueResult();
|
||||||
|
if (user != null) {
|
||||||
|
user.notificationsTokens = new ArrayList<>(user.notificationsTokens.stream()
|
||||||
|
.filter(t -> !t.equals(token))
|
||||||
|
.toList());
|
||||||
|
session.merge(user);
|
||||||
|
}
|
||||||
|
transaction.commit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (transaction != null) {
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Error removing notification token: " + e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> getNotificationTokensByPrivateKey(String privateKey) {
|
||||||
|
User user = getByPrivateKey(privateKey);
|
||||||
|
if (user != null) {
|
||||||
|
return user.notificationsTokens;
|
||||||
|
}
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> getNotificationsTokensByPublicKey(String publicKey) {
|
||||||
|
User user = getByPublicKey(publicKey);
|
||||||
|
if (user != null) {
|
||||||
|
return user.notificationsTokens;
|
||||||
|
}
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/main/resources/hibernate.cfg.xml
Normal file
17
src/main/resources/hibernate.cfg.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.5//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.5.dtd">
|
||||||
|
<hibernate-configuration>
|
||||||
|
<session-factory>
|
||||||
|
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
|
||||||
|
<property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/rosetta_db</property>
|
||||||
|
<property name="hibernate.connection.username">rosetta_user</property>
|
||||||
|
<property name="hibernate.connection.password">rosetta_password</property>
|
||||||
|
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
|
||||||
|
<property name="hibernate.hbm2ddl.auto">update</property>
|
||||||
|
<property name="hibernate.show_sql">true</property>
|
||||||
|
<property name="hibernate.format_sql">true</property>
|
||||||
|
<!--Зарегистрированные таблицы-->
|
||||||
|
<mapping class="com.rosetta.im.database.entity.User"/>
|
||||||
|
|
||||||
|
</session-factory>
|
||||||
|
</hibernate-configuration>
|
||||||
Reference in New Issue
Block a user