Spring + Hibernate для новичков

от автора


Вместо дисклеймера

На Хабре уже есть множество статей на тему работы с Hibernate, однако, как мне показалось, все они довольно сложные для новичков. Эта статья направлена на разъяснение основ работы с ORM и будет полезна в первую очередь тем, кто только начинает разрабатывать собственные приложения и имеет мало опыта работы с базами данных в общем, и с инструментами, вроде Hibernate, в частности. Матерые разработчики вряд ли найдут в статье для себя что-то новенькое; всех остальных прошу под кат.

Что такое ORM?

Ни одно современное веб-приложение не обходится без хранения огромного количества различной информации. Эту задачу обычно возлагают на специальные программы — Систему Управления Базами Данных СУБД. По схеме организации базы данных делятся на несколько видов, и так сложилось, что самым распространенным видом оказались реляционные.

В реляционных базах, данные организованны в виде сущностный (таблиц) и связей между ними. Программисты, работающие с объектно-ориентированными языками программирования, зачастую сталкиваются с задачей преобразования данных из формы, понятной СУБД в привычную объектную форму. Почти всегда решение этих задач занимает огромное количество времени и заставляет писать такие конструкции:

public ArrayList<BookBean> getBooksByGenreId (int genre_id)     {         ArrayList<BookBean> result = new ArrayList<>();         try         {             int i = 1;             String query = "SELECT * FROM books " +                     "LEFT JOIN genres2books " +                     "ON genres2books.book_id=books.id " +                     "WHERE genre_id=? AND books.approved = 1 " +                     "ORDER BY user_rating DESC LIMIT 250";             connection = getConnection();             ps = connection.prepareStatement(query);             ps.setInt(i++, genre_id);             resultSet = ps.executeQuery();             while (resultSet.next())             {                 String name = resultSet.getString("name");                 String summary = resultSet.getString("summary");                 String cover_url = resultSet.getString("cover_url");                 String cover_min_url = resultSet.getString("cover_min_url");                 String example = resultSet.getString("example");                 String isbn = resultSet.getString("isbn");                 String foreign_id = resultSet.getString("foreign_id");                 double rev_rating = resultSet.getDouble("rev_rating");                 double usr_rating = resultSet.getDouble("user_rating");                 int user_id = resultSet.getInt("user_id");                 int id = resultSet.getInt("id");                 int approved = resultSet.getInt("approved");                 int top = resultSet.getInt("top");                 int partner_id = resultSet.getInt("partner_id");                 long sum_mark = resultSet.getLong("sum_mark");                 long votes_num = resultSet.getLong("votes_num");                 result.add( new BookBean(id, name, summary, cover_url, cover_min_url, example, rev_rating, usr_rating,                         user_id, top, approved, sum_mark, votes_num, isbn, foreign_id, partner_id) );             }         } catch (SQLException | IllegalArgumentException e) {             e.printStackTrace();         } finally {             try {                 if (ps!=null)                     ps.close();                 if (connection!=null)                     connection.close();             } catch (Exception e) {                 e.printStackTrace();             }         }         return result;     } 

И это только один SELECT, а ведь нужно еще и организовать правильное подключение к СУБД и обеспечить нормальную одновременную работу нескольких пользователей.

Облегчить жизнь программистам и освободить нас от рутины призвана технология Object-Relational Mapping (ORM), которую реализует популярная библиотека Hibernate. Hibernate берет на себя задачу преобразования данных их реляционного вида в объектный, для чтения, и из объектного вида в реляционный — для записи. Кроме того, библиотека позволяет легко настроить подключение к СУБД и с помощью нее очень легко управлять транзакциями.

Быстрый старт

Сейчас мы попробуем с помощью с помощью Hibernate создать отображение в объектную форму вот такой таблицы, которая используется для хранения сессий:

image

Создадим Bean SessionBean. Бин — это класс, у которого есть констурктор без параметров, конструктор со всеми параметрами и определены get- и set- методы для всех полей.

@Entity //аннотация, регистрирующая класс как сущность БД @Table(name = "sessions") //связываем с конкретной таблицей по названию public class SessionBean implements Serializable{      @Column(name = "username") //название таблицы в БД     private String username; //название поля класса     @Id //указывает на то, что следующее поле является ID и будет использоваться для поиска по умолчанию     @Column(name = "series")     private String series;     @Column(name = "token")     private String token;     @Column(name = "last_used")     private Timestamp lastUsed;      public SessionBean() {}      public SessionBean(String username, String series, String token, Timestamp lastUsed) {         this.username = username;         this.series = series;         this.token = token;         this.lastUsed = lastUsed;     }      public String getUsername() {         return username;     }      public void setUsername(String username) {         this.username = username;     }      public String getSeries() {         return series;     }      public void setSeries(String series) {         this.series = series;     }      public String getToken() {         return token;     }      public void setToken(String token) {         this.token = token;     }      public Timestamp getLastUsed() {         return lastUsed;     }      public void setLastUsed(Timestamp last_used) {         this.lastUsed = last_used;     } } 

Также создадим DAO (Data Access Object) — специальный класс, который будет обеспечивать для нас операции чтения и записи в базу данных

public class NEXEntityDAO<Bean> {     protected final Class<Bean> typeParameterClass;   	public NEXEntityDAO(Class<Bean> typeParameterClass) 	{         this.typeParameterClass = typeParameterClass;     }      @Override     public void delete(int id) {         Session session = HibernateUtil.getSessionFactory().openSession();         session.beginTransaction();         Bean del = (Bean) session.get(typeParameterClass, id);         session.delete(del);         session.getTransaction().commit();         if (session.isOpen()) {             session.close();         }     }      @Override     public ArrayList<Bean> getAll() {         Session session = HibernateUtil.getSessionFactory().openSession();         session.beginTransaction();         String hql = String.format("from %s",typeParameterClass.getCanonicalName());         Query SQLQuery = session.createQuery(hql);         ArrayList<Bean> result = (ArrayList<Bean>) SQLQuery.list();         session.getTransaction().commit();         if (session.isOpen()) {             session.close();         }         return result;     }      public Bean getById(int id) {         Session session = HibernateUtil.getSessionFactory().openSession();         session.beginTransaction();         Bean result = (Bean) session.get(typeParameterClass, id);         session.getTransaction().commit();         if (session.isOpen()) {             session.close();         }         return result;     }      @Override     public void update(Bean object) {         Session session = HibernateUtil.getSessionFactory().openSession();         session.beginTransaction();         session.update(object);         session.getTransaction().commit();         if (session.isOpen()) {             session.close();         }     }      @Override     public void add(Bean object) {         Session session = HibernateUtil.getSessionFactory().openSession();         session.beginTransaction();         session.save(object);         session.getTransaction().commit();         if (session.isOpen()) {             session.close();         }     }      @Deprecated     public void clear()     {         Session session = HibernateUtil.getSessionFactory().openSession();         session.beginTransaction();         String hql = String.format("delete from %s",typeParameterClass.getCanonicalName());         Query query = session.createQuery(hql);         query.executeUpdate();         session.getTransaction().commit();         if (session.isOpen()) {             session.close();         }     } } 

После чего становится очень просто извлекать, редактировать и добавлять данные в БД.

 NEXEntityDAO<SessionBean> sessionDAO = new NEXEntityDAO<>(SessionBean.class);  SessionBean session = sessionDAO.getById(5) //Получить сессию с ид = 5  ArrayList<SessionBean> allSessions = sessionDAO.getAll(); //получить список всех сессий  session.setToken(“21313”);  sessionDAO.update(session); //обновить существующую запись  SessionBean adding = new SessionBean(“st”,”ri”,”ng”,ts);  sessionDAO.add(adding); //добавить новую запись 

На этом закончим знакомство с ORM. В следующих статьях мы рассмотрим наиболее интересные тонкости работы с этой технологией, а также приёмы тестирования баз данных.

ссылка на оригинал статьи http://habrahabr.ru/post/255829/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *