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();