Postgres与Glassfish连接池

iui*_*uiz 2 java postgresql connection-pooling glassfish java-ee

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

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

所以我的问题是:

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

Ale*_*DET 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

unitName"myPu"是在glassfish管理控制台中配置的JDBC资源的JNDI名称.

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

@TransactionManagement(value=TransactionManagementType.BEAN) 
Run Code Online (Sandbox Code Playgroud)

你需要自己处理交易,如:

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

3 - 如果需要创建复杂请求,可以在实体上声明一些命名查询.下面是Car实体的可能实现:

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

下面是一个添加到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;
}
Run Code Online (Sandbox Code Playgroud)

当然,您可以根据需要编写命名查询(命名查询被缓存并且可能更好地提高性能),但如果您确实需要直接查询数据库,则可以使用如下的本机查询:

// 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();
Run Code Online (Sandbox Code Playgroud)