好玩Spring之編程式配置數據源及事務的使用

xml配置數據源

先來看一個數據庫操作的簡單下例子,一般情況下,我們採用xml來配置數據源,如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- enable the configuration of transactional behavior based on annotations -->
    <!-- 等同於@EnableTransactionManagement -->
    <tx:annotation-driven/>

    <bean id="jdbcFooRepository" class="com.fs.spring.chapter1.JdbcFooRepository">
        <constructor-arg ref="dataSource"/>
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg ref="dataSource"/>
    </bean>

</beans>
public class JdbcFooRepository {

    private DataSource dataSource;

    public JdbcFooRepository(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Transactional
    public void add() {
        Connection connection = DataSourceUtils.getConnection(dataSource);
        try {
            // 這裏只有把autoCommit設置爲false,才能體現事務的作用
            connection.setAutoCommit(false);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.execute("insert into test (title, author) values('title1', 'author1')");
    }
}
public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        JdbcFooRepository jdbcFooRepository = (JdbcFooRepository) context.getBean("jdbcFooRepository");
        jdbcFooRepository.add();
    }

結果,正常插入數據。

編程式數據源

但最近就不想用xml配置數據源,能否編程式?答案是肯定的,如下(參考@EnableTransactionManagement的官網例子):

@Configuration
@EnableTransactionManagement
public class MySpringConfig {
    @Bean
    public JdbcFooRepository jdbcFooRepository() {
        // configure and return a class having @Transactional methods
        return new JdbcFooRepository(dataSource());
    }

    @Bean
    public DataSource dataSource() {
        // configure and return the necessary JDBC DataSource
        SingleConnectionDataSource ds = new SingleConnectionDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/test?useSSL=false");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }

    @Bean
    public PlatformTransactionManager txManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}

以上內容的效果,跟xml的配置是一樣的。

public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MySpringConfig.class);
        JdbcFooRepository jdbcFooRepository = (JdbcFooRepository) context.getBean("jdbcFooRepository");
        jdbcFooRepository.add();
    }

這種方式,也可以正常插入。

預告

爲啥要寫這個小例子呢,已盯上@Transactional很久了,想了解下,它的運行流程,在下一篇中,來學習@Transactional究竟是怎麼實現事務的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章