Postgres с подключением к Glassfish - PullRequest
2 голосов
/ 10 июля 2011

Я новичок в мире Java EE и хочу использовать PostgreSQL в качестве базы данных в веб-приложении. Я использую Glassfish в качестве сервера приложений и добавил пул соединений через интерфейс администрирования (я использовал этот сайт для справки). Теперь я не знаю, каков «правильный» способ использования пула соединений в моем приложении (фактически я в настоящее время не знаю, как даже получить соединение из пула и написать простой запрос).

Нам нужно написать довольно сложные запросы, поэтому я не знаю, нужно ли мне создавать сопоставление для каждой таблицы и использовать сопоставления, или просто использовать sql и какой-то тип сопоставления строк для анализа результатов (мы использовали Spring RowMapper раньше).

Итак, мой вопрос:

  1. Какие существуют способы использования соединений из пула?
  2. Каковы (не) преимущества этих моделей?
  3. Как создать умное отображение, которое может обрабатывать сложные и высокопроизводительные запросы.
  4. Это работает с Hibernate? И если да, то как?

1 Ответ

5 голосов
/ 15 июля 2011

1 - Если ваш пул соединений сконфигурирован с использованием glassfish, вы можете разработать простой EJB и внедрить соединение с помощью аннотации, я думаю, что это лучший способ для обработки соединений из вашего пула.

(все примеры совместимы с hibernate и хорошо работают с базой данных postgresql)

например:

@Stateless
public class myEjb
{
    // inject the entityManager  
    @PersistenceContext(unitName = "myPu")
    private EntityManager em;

    public Car findCarById(Long carId)
    {
        Car aCar = (Car) em.find(Car.class, carId);
        return aCar;
    }
}

unitName "myPu" - это имя JNDI вашего ресурса JDBC, настроенное в консоли администрирования glassfish.

2 - преимущество этого шаблона в том, что он не зависит от кода, вы не можете изменять ресурсы JDBC в отношении среды разработки, тестирования или производства. URL-адрес, пользователь и пароль JDBC настраиваются на сервере, а не в XML-файле, который вы можете осторожно менять при каждом переключении из одной среды в другую. Таким образом, вам не нужно обрабатывать транзакцию, это сервер, который фиксирует или выполняет откат при исключении. Если вам нужно обработать транзакцию самостоятельно, вы можете добавить аннотацию в поле Stateless:

@TransactionManagement(value=TransactionManagementType.BEAN) 

вам необходимо самостоятельно обработать транзакцию, например:

em.getTransaction().begin();
try
{
    // do something with the entityManager
    em.getTransaction().commit();
}
catch(MyException ex)
{
    em.getTransaction().rollback();
}

3 - Если вам нужно создать сложный запрос, вы можете объявить несколько именованных запросов для вашей сущности. ниже возможной реализации объекта Car:

@Entity
public class Car 
{
    @NamedQueries(
    {
        @NamedQuery(name = "Car.findByBrandAndColor", query = "SELECT c FROM Car WHERE c.brand = :brand AND color = :color")
    })
}

ниже пример функции для добавления в ваш EJB, который использует предыдущий именованный запрос:

public List<Car> findAllCarByBrandAndColor(String aBrand, String aColor)
{
    List<Car> theCars;

    Query theQuery = em.createNamedQuery("Car.findByBrandAndColor");
    theQuery.setParameter("brand", aBrand);
    theQuery.setParameter("color", aColor);

    try
    {
        theCars = (List<Car>) query.getResultList();
    }
    catch(NoResultException ex)
    {
        theCars = null;
    }

    return theCars;
}

Конечно, вы можете писать именованные запросы настолько сложно, насколько вам нужно (именованные запросы кэшируются и могут быть более эффективными для производительности), но если вам действительно нужно напрямую запрашивать базу данных, вы можете использовать собственные запросы, как показано ниже:

// the query is native SQL
Query theQuery = em.createNativeQuery("SELECT * FROM car WHERE color = 'blue' AND brand = 'toyota'", Car.class);
Car aCar = (Car) query.getSingleResult();
...