Postgres与Glassfish连接池

时间:2011-07-10 11:03:39

标签: java postgresql java-ee glassfish connection-pooling

我是Java EE World的新手,希望在Web应用程序中使用PostgreSQL作为我的数据库。我使用Glassfish作为我的应用程序服务器,并通过管理界面添加了一个连接池(我使用此site 求助)。现在我不知道在我的应用程序中使用连接池的“正确”方法是什么(实际上我目前还不知道如何从池中获取连接并编写简单的查询)。

我们需要编写非常复杂的查询,所以我不知道是否应该为每个表创建一个映射并使用映射,或者只是使用sql和某种行映射器来解析结果(我们使用了Spring RowMapper之前)。

所以我的问题是:

  1. 使用池中的连接有哪些不同的方式?
  2. 这些模式的(dis)优势是什么?
  3. 如何创建一个可以处理复杂和性能密集型查询的聪明映射。
  4. 这适用于Hibernate吗?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:5)

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”是在glassfish管理控制台中配置的JDBC资源的JNDI名称。

2 - 此模式的优点是它不依赖于代码,您可能无法更改有关开发,测试或生产环境的JDBC资源。 JDBC URL,用户和传递是在服务器上配置的,而不是在每次从环境切换到另一个环境时都可以仔细更改的XML文件中。这样您就不必处理事务,这是提交或回滚异常的服务器。 如果您需要自己处理事务,可以在无状态下添加注释:

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