Spring学习04

Sprint之事务

0,导包spring-tx包

1,User实体类UserDao接口(增删查改方法)

实现类UserDaoImp(私有字段private JdbcTemplate jt;通过set注入)

实现类方法(通过JdbcTemplate操作数据库):

a,增

@Override
    public void save(User u) {
        String sql = "insert into user values(null,?,?,?,?)";
        jt.update(sql, u.getName(), u.getPassword(), u.getSex(), u.getBirthday());
    }

b,根据id查找

@Override
    public User getById(Integer id) {
        String sql = "select * from user where uid=?";
        return jt.queryForObject(sql, new RowMapper<User>() {

            @Override
            public User mapRow(ResultSet rs, int arg1) throws SQLException {
                User u = new User();
                u.setId(rs.getInt("uid"));
                u.setName(rs.getString("uname"));
                u.setPassword(rs.getString("upassword"));
                u.setSex(rs.getString("sex"));
                u.setBirthday(rs.getString("birthday"));
                return u;
            }

        }, id);
    }
c,查找全部User

@Override
    public List<User> getAll() {
        String sql = "select * from user";
        List<User> list = jt.query(sql, new RowMapper<User>() {

            @Override
            public User mapRow(ResultSet rs, int arg1) throws SQLException {
                User u = new User();
                u.setId(rs.getInt("uid"));
                u.setName(rs.getString("uname"));
                u.setPassword(rs.getString("upassword"));
                u.setSex(rs.getString("sex"));
                u.setBirthday(rs.getString("birthday"));
                return u;
            }
        });
        return list;
    }

2,xml文件配置

导入连接池配置

<context:property-placeholder location="classpath:db.properties"/>

连接池放入容器

<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>

连接池注入jdbcTemplate,注意property的name不要写错,可以去翻源码

<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>

jdbcTemplate注入Dao

<bean name="userDao" class="com.cl.jdbcTemplate.UserDaoImp">
<property name="jt" ref="jdbcTemplate"></property>
</bean>

3,测试类

完全手动方法:啥也不需要,一个类一个方法即可。

@Test
    public void fun1() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql:///mybase");
        dataSource.setUser("root");
        dataSource.setPassword("root");
        // 创建jdbc模板对象
        JdbcTemplate jt = new JdbcTemplate();
        jt.setDataSource(dataSource);
        String sql = "insert into user values('110','hehe','123456','male','1999-09-09')";
        jt.update(sql);
    }

配置好了的测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
    @Resource(name = "userDao")
    private UserDao ud;
    @Test
    public void fun() {
        User u = new User();
        u.setBirthday("1998-09-09");
        u.setName("lily");
        u.setPassword("mypassword");
        u.setSex("female");
        ud.save(u);
    }
    }

---------------------------------------------------------------------------------------------------------------

PlateformTransactionManager,事务核心管理器,封装事务操作,依赖连接池

Dao的实现类继承JdbcDaoSupport可以直接调用getJdbcTemplate方法获得JdbcTemplate处理sql语句。

Service的实现类,如

public class ServiceImp implements AccountService {
    private AccountDao ad;
    private TransactionTemplate tt;

    public void setTt(TransactionTemplate tt) {
        this.tt = tt;
    }

    public void setAd(AccountDao ad) {
        this.ad = ad;
    }

    @Override//下面使用注解配置事务通知,方便多了
    @Transactional(isolation=Isolation.REPEATABLE_READ,readOnly=false,propagation=Propagation.REQUIRED)
    public void transfer(Integer from, Integer to, Double money) {
        tt.execute(new TransactionCallbackWithoutResult() {

            @Override // 封装了try-catch和回滚操作
            protected void doInTransactionWithoutResult(TransactionStatus arg0) {
                ad.minusMoney(from, money);
                ad.addMoney(to, money);
            }
        });
    }
}

xml配置文件中先配置DataSource,然后将DataSource注入transactionManager

<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

配置事务模板对象

<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean>

使用注解配置事务通知,这里感觉注解方便许多

<tx:annotation-driven/>

连接池注入Dao

<bean name="accountDao" class="com.cl.springtx.AccountImp">
<property name="dataSource" ref="dataSource"></property>
</bean>

Dao和transactionTemplate注入Service

<bean name="accountService" class="com.cl.springtx.ServiceImp">
<property name="ad" ref="accountDao"></property>
<property name="tt" ref="transactionTemplate"></property>
</bean>

如果不用注解,事务通知的配置如下

<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- get和find设置为只读 -->
<tx:method name="get*" propagation="REQUIRED" isolation="REPEATABLE_READ" read-only="true"></tx:method>
<tx:method name="find*" propagation="REQUIRED" isolation="REPEATABLE_READ" read-only="true"></tx:method>
</tx:attributes>
</tx:advice>
<!-- 织入 -->
<aop:config>
<aop:pointcut expression="execution(* com.cl.springtx.*ServiceImp.*(..))" id="account-tx"/>        
<aop:advisor advice-ref="txAdvice" pointcut-ref="account-tx"/><!-- 切面 -->
</aop:config>

总之,jdbc模板封装了数据库的操作,而transaction模板又封装了jdbc的操作,使得try-catch和回滚操作不用手动处理。


猜你喜欢

转载自blog.csdn.net/qq_26567507/article/details/78781178