连接器和 API 手册  / 第 3 章 MySQL Connector/J 开发人员指南  /  3.13 将 Connector/J 与 Spring 结合使用

3.13 将 Connector/J 与 Spring 结合使用

Spring Framework 是一个基于 Java 的应用程序框架,旨在通过提供一种配置组件的方式来协助应用程序设计。Spring 使用的技术是一种众所周知的设计模式,称为依赖注入(请参阅 控制容器的反转和依赖注入模式)。本文将重点介绍使用 Spring 2.0 对 MySQL 数据库进行面向 Java 的访问。对于那些想知道的人,有一个名为 Spring.NET 的 Spring 的 .NET 端口。

Spring 不仅是一个配置组件的系统,还包括对面向方面编程(AOP)的支持。这是 Spring 的资源和事务管理的主要好处和基础之一。Spring 还提供了用于将资源管理与 JDBC 和 Hibernate 集成的实用程序。

对于本节中的示例,将使用 MySQL world 示例数据库。第一个任务是通过 Spring 建立一个 MySQL 数据源。Spring 中的组件使用 bean术语。例如,要配置与支持 world 示例数据库的 MySQL 服务器的连接,您可以使用:

<util:map id="dbProps">
    <entry key="db.driver" value="com.mysql.cj.jdbc.Driver"/>
    <entry key="db.jdbcurl" value="jdbc:mysql://localhost/world"/>
    <entry key="db.username" value="myuser"/>
    <entry key="db.password" value="mypass"/>
</util:map>

在上面的示例中,我们将值分配给将在配置中使用的属性。对于数据源配置:

<bean id="dataSource"
       class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${db.driver}"/>
    <property name="url" value="${db.jdbcurl}"/>
    <property name="username" value="${db.username}"/>
    <property name="password" value="${db.password}"/>
</bean>

占位符用于为此 bean 的属性提供值。这意味着我们可以在一个地方指定配置的所有属性,而不是在每个 bean 上输入每个属性的值。然而,我们确实需要一个更多的 bean 来将这一切整合在一起。最后一个 bean 负责实际用属性值替换占位符。

<bean
 class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="properties" ref="dbProps"/>
</bean>

现在我们已经配置好 MySQL 数据源并准备就绪,我们可以编写一些 Java 代码来访问它。下面的示例将使用我们在 Spring 中配置的数据源检索三个随机城市及其对应的国家/地区。

// Create a new application context. this processes the Spring config
ApplicationContext ctx =
    new ClassPathXmlApplicationContext("ex1appContext.xml");
// Retrieve the data source from the application context
    DataSource ds = (DataSource) ctx.getBean("dataSource");
// Open a database connection using Spring's DataSourceUtils
Connection c = DataSourceUtils.getConnection(ds);
try {
    // retrieve a list of three random cities
    PreparedStatement ps = c.prepareStatement(
        "select City.Name as 'City', Country.Name as 'Country' " +
        "from City inner join Country on City.CountryCode = Country.Code " +
        "order by rand() limit 3");
    ResultSet rs = ps.executeQuery();
    while(rs.next()) {
        String city = rs.getString("City");
        String country = rs.getString("Country");
        System.out.printf("The city %s is in %s%n", city, country);
    }
} catch (SQLException ex) {
    // something has failed and we print a stack trace to analyse the error
    ex.printStackTrace();
    // ignore failure closing connection
    try { c.close(); } catch (SQLException e) { }
} finally {
    // properly release our connection
    DataSourceUtils.releaseConnection(c, ds);
}

这与普通的 JDBC 访问 MySQL 非常相似,主要区别在于我们使用 DataSourceUtils 而不是 DriverManager 来创建连接。

虽然这似乎是一个很小的差异,但其影响却有些深远。Spring 以类似于 J2EE 应用程序服务器中的容器管理数据源的方式管理此资源。打开连接后,如果它与事务同步,则随后可以在代码的其他部分访问它。这使得将应用程序的不同部分视为事务性而不是传递数据库连接成为可能。