С наступающим Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы
Java EE (J2EE)
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
titans2011
302 / 263 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
1

Как и где правильно открывать метод

02.09.2012, 11:44. Просмотров 1558. Ответов 11
Метки нет (Все метки)

Всем привет. Интересует такой вопрос. Есть такой код:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Session session=HibernateUtil.getSessionFactory().openSession();
        try
        {
           while (true)
               {
                 //тут выбираем меню (в консоли).
                      if(a==1)
                      { 
                       //добавляем запись с помощью hibernate
                      }
                      if(a==1)
                      { 
                       //читаем базу с помощью запроса.
                      }
                      if(a==3)
                      { 
                       //отправляемся на выход
                        break; 
                      }
                }
                }catch(Exception e)
        {
            
        }finally
        {
            session.close();
        }
Как правильно делать, как выше, или как ниже (Я так понимаю, мы с начала создаем фабрику, и её НЕ нужно постоянно дергать, т.к. она долго создается, но с другой стороны, мне кажется, что таким образом соединение с базой постоянно будет открыто (или там Hibernate сам когда надо открывает и закрывает соединение?))
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
...
        try
        {
           while (true)
               {
                 //тут выбираем меню (в консоли).
                      if(a==1)
                      { 
                       Session session=HibernateUtil.getSessionFactory().openSession();
                       //добавляем запись с помощью hibernate
                       session.close();
                      }
                      if(a==1)
                      { 
                       Session session=HibernateUtil.getSessionFactory().openSession();
                       //читаем базу с помощью запроса.
                       session.close();
                      }
                      if(a==3)
                      { 
                       //отправляемся на выход
                        break; 
                      }
                }
                }catch(Exception e)
                {
                }
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.09.2012, 11:44
Ответы с готовыми решениями:

Посмотрите все ли правильно или можно где-то сделать как-то иначе:
Ребят посмотрите все ли правильно или можно где-то сделать как-то иначе: ...

Как правильно написать метод для обновления записи, чтобы он возвращал объект?
public Competition updateCompetition(Long id, Integer point, Integer place){ ...

Как открывать post запрос с апплета ?
Hi esli napisat tak: String servletname = 'DamAppendLogServlet?'; ...

Метод получает другой метод, как аргумент. Как это работает?
Добрый день, ребят. Есть такая программа: package javaapplication13;...

Метод main и как им вызвать другой метод
Доброго всем времени суток. У меня возникла проблема. Вобщем дело такое. У меня...

11
mutagen
2565 / 2238 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
02.09.2012, 12:40 2
фабрику создаём один раз, а сессию создаём, открываем транзакцию - выполняем всё что надо, комитим, и закрываем сессию.
Вопрос держать ли сессию открытой зависит от того как часто надо её открывать и закрывать, ну и от количества клиентов к БД. База не любит много сессий.
0
kmi
55 / 55 / 13
Регистрация: 26.04.2010
Сообщений: 173
04.09.2012, 10:32 3
Я сделал такой класс, назвал HibernateUtil:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package my.pack.dao;
 
import java.util.Date;
import java.text.SimpleDateFormat;
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;
 
public class HibernateUtil 
{
  private static SessionFactory sessionFactory;
  
  static 
  {
    try 
    {
      sessionFactory = new Configuration().configure().buildSessionFactory();
    }
    catch (Throwable ex) 
    {
      SimpleDateFormat sdf_dts = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss.SSS");
      String time = sdf_dts.format(new Date());
      String message = PlatformError.DBConnectionFail.message() + " Ошибка создания фабрики сессий.";
      System.out.println(time + message + " [" + ex + "]");
      ex.printStackTrace(System.out);
      // throw ex;
    }
  }
 
  public static SessionFactory getSessionFactory() 
  {
    return sessionFactory;
  }
}
Далее, когда мне нужно получить сессию, делаю так:

Java
1
Session session = HibernateUtil.getSessionFactory().openSession();
При первом вызове HibernateUtil создаёт фабрику, одну на экземпляр приложения. А далее эта фабрика используется во всех классах, работающих с DAO.

Добавлено через 14 минут
Далее работа с сессией выглядит так:

1. при чтении данных:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Session session = null;
    try
    {
      session = HibernateUtil.getSessionFactory().openSession();
      MyDAO dao = (MyDAO) session.get(MyDAO.class, new Long(id));
    }
    catch (Exception ex)
    {
      // обработка ошибок
    }
    finally
    {
      if (session != null && session.isOpen()) session.close();
    }
2. при работе с транзакциями

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Session session = null;
    try
    {
      session = HibernateUtil.getSessionFactory().openSession();
      MyDAO dao = new MyDAO();
      Transaction tx = session.beginTransaction();
      try
      {
        session.save(dao);
        session.flush(); // обязательно перед коммитом транзакции
        tx.commit();
      }
      catch (Exception ex)
      {
        if (tx != null) tx.rollback();
        // обрабатываем ошибку запроса
      }
    }
    catch (Exception ex)
    {
      // обработка остальных ошибок
    }
    finally
    {
      if (session != null && session.isOpen()) session.close();
    }
0
titans2011
302 / 263 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
04.09.2012, 10:42  [ТС] 4
спасибо, приму на вооружение
0
kmi
55 / 55 / 13
Регистрация: 26.04.2010
Сообщений: 173
04.09.2012, 10:43 5
Вопрос о том, когда закрывать сессию, зависит от нескольких моментов.
Важно помнить, что DAO после закрытия сессии с БД не связан, но может использоваться в коде. Это значит, что запрос связанных объектов по вторичным ключам может вернуть null, хотя в базе запись есть.
Также важно помнить, что операции сохранения/изменения/удаления могут происходить реально не в момент вызова соответствующего метода сессии, а в какой-то момент времени позже. Например, может получиться, что был вызван метод save(), но DAO при этом так и не получил значение id. Чтобы такого не было, я вызываю flush() после save(), но до коммита транзакции.
И всегда нужно помнить о содержимом кэша. Оно должно быть актуальным, если Вы планируете использовать DAO после закрытия сессии.
0
titans2011
302 / 263 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
04.09.2012, 18:59  [ТС] 6
Давайте я расскажу структуру "на пальцах" для чайников как я понимаю jpa. А вы меня, если что подправите.
Итак. jpa это рекомендации для обращении к ORM. Сначала существовал метод jpa, который был очень сложным. Т.к. все время нужно было прописывать подключение к базе данных, создавать сессии, потом делать транзакции и все закрывать. Потом появился Hibernate, который упростил задачу. В классах нужно было создать всего лишь аннотации или прописать в xml зависимости, и тогда уже hibernate сам проводил транзакции, работая с этими классами. Параллельно Hibernate существовал класс Entity Manager, который предоставлял методы для удобного создания, апдейта и т.д. объектов класса (или это тот же Hibernate?) . Потом появился DAO, который позволил уменьшить код, и в отдельной настройки прописать как создавать, удалять и т.д. объекты из БД.
Для удобства создали фреймворк Spring, который позволяет не зацикливаться на транзакциях, подключениях и т.д. В нем есть свой DAO, и есть все методы для автоматических транзакций.
Вопрос у меня только такой: Часто ли используется DAO в проектах. И почему если Spring такой распрекрасный, не все им пользуются?

Добавлено через 17 минут
А, и ещё есть такая вещь как JDBC. Которая просто может делать различные запросы к базе данных. Если не ошибаюсь, создавать объекты в БД с помощью него, не представляется возможным.
0
kmi
55 / 55 / 13
Регистрация: 26.04.2010
Сообщений: 173
04.09.2012, 20:37 7
Hibernate - надстройка над JDBC.
Создавать объекты в БД ни JDBC, ни Hibernate не могут, поскольку направлены на работу с реляционными СУБД. Hibernate предлагает лишь способ обращения к БД, при котором операции производятся не над записями, а над соответствующими объектами. Такой подход ускоряет разработку приложений баз данных ценой столь же значтельной потери их производительности.
Data Access Objects (DAO) - специальные классы приложения, соответствующие по своей структуре записям определённой таблицы БД. В разных технологиях их реализация разная. Но суть от этого не меняется. Используете ли Вы нативный клиент, или JDBC/ODBC, или Hibernate - DAO в том или ином виде присутствуют просто потому, что удобно внутри программы передавать и обрабатывать данные в виде объекта. Понятно, что внешние интерфейсы с объектами дружат далеко не всегда. И тут объекты уступают место протоколам.

Добавлено через 2 минуты
А Spring вовсе не распрекрасный. Это всего лишь один из фреймворков. Не более и не менее.
0
mutagen
2565 / 2238 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
04.09.2012, 22:02 8
Цитата Сообщение от kmi Посмотреть сообщение
Создавать объекты в БД ни JDBC, ни Hibernate не могут
ну вообщето хибер может

Не по теме:

hibernate.hbm2ddl.auto Automatically validates or exports schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly.

e.g. validate | update | create | create-drop
http://docs.jboss.org/hibernate/orm/...iguration.html

0
kmi
55 / 55 / 13
Регистрация: 26.04.2010
Сообщений: 173
05.09.2012, 13:11 9
Цитата Сообщение от mutagen Посмотреть сообщение
ну вообщето хибер может

Не по теме:

hibernate.hbm2ddl.auto Automatically validates or exports schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly.

e.g. validate | update | create | create-drop
http://docs.jboss.org/hibernate/orm/...iguration.html

Я не имел в виду метаданные, т.к. они остаются за пределами темы.
0
titans2011
302 / 263 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
05.09.2012, 14:38  [ТС] 10
Решил я на практике сделать Jpa+DAO.Как обычно ничего не получается. Пример был обрезанный.
Значит сам Enplement класс:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package test;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table (name="taxi")
public class Taxi {
    @Id
    @GeneratedValue 
    @Column(name="ID")
    private int ID;
    @Column(name="Name")
    private String Name;
    @Column(name="Numbercur")
    private String Numbercur;
    @Column(name="Mobile")
    private String Mobile;
    public int getID() {
        return ID;
    }
    public void setID(int iD) {
        ID = iD;
    }
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public String getNumbercur() {
        return Numbercur;
    }
    public void setNumbercur(String numbercur) {
        Numbercur = numbercur;
    }
    public String getMobile() {
        return Mobile;
    }
    public void setMobile(String mobile) {
        Mobile = mobile;
    }
    
}
Потом пример посоветовал создать интерфейс.
Java
1
2
3
4
5
6
7
8
package test;
 
public interface DAO<K,E> {
    void persist (E entity);
    void remove (E entity);
    E finDyId(K id);
 
}
От него имплементить абстрактный класс:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package test;
 
import javax.persistence.EntityManager;
import java.lang.reflect.ParameterizedType; 
import java.util.List; 
 
 
import javax.persistence.EntityManager; 
import javax.persistence.PersistenceException; 
import javax.persistence.Query;
 
 
 
public abstract class JpaDao<K,E> implements DAO<K,E> {
    protected Class<E> entityClass;
    protected EntityManager entityManager;
    
    public JpaDao()
    {
        ParameterizedType genericSuperclass= (ParameterizedType) getClass().getGenericSuperclass();
        this.entityClass=(Class<E>) genericSuperclass.getActualTypeArguments()[1];
    }
    public void persist (E entity) {entityManager.persist(entity);}
    public void remove (E entity) {entityManager.remove(entity);}
    public E findById (K id) {return entityManager.find(entityClass, id);}
 
}
Ну и главный класс (вообще дрова, т.к. я не понимаю что от куда вызывать):
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package test;
 
import java.util.List;
 
import org.hibernate.Query;
 
 
 
public class Main {
 
    /**
     * @param args
     */
    //@EJB(name="DAO")
    private DAO d;
    public static void main(String[] args) {
        
        Taxi base=new Taxi();
        base.setName("Ivan Ivanov");
        base.setNumbercur("XX7777XX");
        base.setMobile("1111111");
        d.persist(base);
        
        //читаем данные
        Query list=session.createQuery("from  taxi as base");
        List <Taxi> taxiList=list.list();
        for (Taxi e:taxiList)
        {
            System.out.println("Name: "+e.getName());
        }
        
 
    }
 
}
А также на всякий случай создал persistence.xml Но я его так ни к чему не присоеденил.
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="taxiDB" transaction-type="RESOURCE_LOCAL"> 
<!-- comment out to use the default provider  
<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>-->
 <class>test.Taxi</class>
     <properties>
     <property name="toplink.jdbc.url" value="jdbc:mysql://****:3306/taxi"/>
     <property name="toplink.jdbc.user" value="***"/>
     <property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
     <property name="toplink.jdbc.password" value="****"/>
     <property name="toplink.ddl-generation" value="drop-and-create-tables"/>
     </properties>
 </persistence-unit>
 </persistence>
Подскажите, как эту всю штуку заставить работать, чего тут не хватает? DAO сам открывает сессии, или где-то нужно их самому открывать?
Прошу заметить, что Spring я тут сознательно не исспользую.
0
mutagen
2565 / 2238 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
05.09.2012, 22:38 11
где вы берёте конфиг с топлинком, я ума не приложу, есть же в стандартной документации пример с подключением мускуля, да и по всему инету валом, нет вы находите самый сложный вариант завязки с оракловым топлинком и давай на нём учиться ???
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/SampleDB</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
 
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
 
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
 
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
 
        <!-- Mapping files -->
        <mapping resource="MyEntityMapping.hbm.xml"/>
    </session-factory>
</hibernate-configuration>
0
titans2011
302 / 263 / 109
Регистрация: 27.09.2010
Сообщений: 1,058
05.09.2012, 23:36  [ТС] 12
Цитата Сообщение от mutagen Посмотреть сообщение
где вы берёте конфиг с топлинком, я ума не приложу, есть же в стандартной документации пример с подключением мускуля, да и по всему инету валом, нет вы находите самый сложный вариант завязки с оракловым топлинком и давай на нём учиться ???
Я не специально. Я просто этого не знал.
0
05.09.2012, 23:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.09.2012, 23:36

Как правильно открывать и читать файлы?
Здравствуйте, не пойму из-за чего начала вылетать следующая ошибка при вызове...

Как правильно открывать файл и записывать/читать из него
Как правильно открывать файл и записывать/читать из него? На разных сайтах и...

Как открывать следующую форму правильно не нарушая принцыпы WPF(MVVM)?
Как открывать следующую форму правильно не нарушая принцыпы WPF(MVVM)? К...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru