概述

本文将指导您如何使用Hibernate/JPA与JNDI数据源创建一个Spring应用程序。如果您想重新了解Spring和Hibernate的基础知识,请参阅这篇文章

2. 定义数据源

2.1. 系统环境

由于我们将使用JNDI数据源,我们不会在应用中定义它,而是在应用容器中定义。在这个示例中,我们将使用Apache Tomcat 8.5.x版本和PostgreSQL 9.5.x数据库。

使用其他Java应用容器和选择的数据库(只要提供相应的JDBC库即可)也可以实现类似步骤。

2.2. 在应用容器中定义数据源

我们在<tomcat_home>/conf/server.xml文件的<GlobalNamingResources>元素内声明数据源。假设数据库服务器与应用容器在同一台机器上,且数据库名为postgres,用户名为baeldung,密码为pass1234,资源定义如下:

<Resource name="jdbc/BaeldungDatabase" 
  auth="Container"
  type="javax.sql.DataSource" 
  driverClassName="org.postgresql.Driver"
  url="jdbc:postgresql://localhost:5432/postgres"
  username="baeldung" 
  password="pass1234" 
  maxTotal="20" 
  maxIdle="10" 
  maxWaitMillis="-1"/>

请注意,我们为资源命名为jdbc/BaeldungDatabase,这是在引用数据源时使用的名称。还需指定类型和数据库驱动类名。为了使其工作,需将对应的jar文件放置在<tomcat_home>/lib/目录下(例如,PostgreSQL的JDBC驱动)。

剩余配置参数包括:

  • auth="Container":表示容器代表应用程序与资源管理器进行身份验证。
  • maxTotal, maxIdle, 和 maxWaitMillis:是连接池的配置参数。

<tomcat_home>/conf/context.xml<Context>元素内,我们还需要定义一个ResourceLink

<ResourceLink 
  name="jdbc/BaeldungDatabase" 
  global="jdbc/BaeldungDatabase" 
  type="javax.sql.DataSource"/>

注意,这里使用的名称与server.xml中的Resource名称相同。

3. 使用资源

3.1. 配置应用

现在我们将使用纯Java配置创建一个简单的Spring + JPA + Hibernate应用。首先定义Spring上下文配置(这里专注于JNDI,假设您已经熟悉Spring的基本配置):

@Configuration
@EnableTransactionManagement
@PropertySource("classpath:persistence-jndi.properties")
@ComponentScan("com.baeldung.hibernate.cache")
@EnableJpaRepositories(basePackages = "com.baeldung.hibernate.cache.dao")
public class PersistenceJNDIConfig {

    @Autowired
    private Environment env;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() 
      throws NamingException {
        LocalContainerEntityManagerFactoryBean em 
          = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        
        // rest of entity manager configuration
        return em;
    }

    @Bean
    public DataSource dataSource() throws NamingException {
        return (DataSource) new JndiTemplate().lookup(env.getProperty("jdbc.url"));
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    // rest of persistence configuration
}

有关完整配置示例,请参考Spring 4和JPA与Hibernate文章。

为了创建dataSource bean,我们需要在应用容器中查找我们定义的JNDI资源。这将在persistence-jndi.properties键(以及其他属性)中存储:

jdbc.url=java:comp/env/jdbc/BaeldungDatabase

注意,在jdbc.url属性中,我们定义了查找的根名称:java:comp/env/(这是默认值,对应组件和环境),然后是我们在server.xml中使用的名称jdbc/BaeldungDatabase

3.2. JPA配置 - 模型、DAO和Service

我们将使用一个带有生成的idname的简单模型,带有@Entity注解:

@Entity
public class Foo {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;
 
    @Column(name = "NAME")
    private String name;

    // default getters and setters
}

接下来定义一个简单的仓库:

@Repository
public class FooDao {

    @PersistenceContext
    private EntityManager entityManager;

    public List<Foo> findAll() {
        return entityManager
          .createQuery("from " + Foo.class.getName()).getResultList();
    }
}

最后,创建一个简单的服务:

@Service
@Transactional
public class FooService {

    @Autowired
    private FooDao dao;

    public List<Foo> findAll() {
        return dao.findAll();
    }
}

有了这些,您就可以在Spring应用中使用JNDI数据源了。

4. 总结

在这篇文章中,我们创建了一个示例Spring应用,它使用JPA + Hibernate与JNDI数据源一起工作。关键部分在于在应用容器中定义资源以及在配置中查找JNDI资源。完整的项目代码可以在GitHub上找到。