Spring学习(四)

 
Spring学习笔记( 17 )----使用Spring注解方式管理事务
--------------------------------------------------
使用Spring+JDBC集成步骤如下:
  
  *配置数据源,例如:
  
 
 
Xml代码 
1 .<bean id= "dataSource"  class = "org.apache.commons.dbcp.BasicDataSource"  destroy-method= "close"
2 .            <property name= "driverClassName"  value= "com.mysql.jdbc.Driver" /> 
3 .            <property name= "url"  value= "jdbc:mysql://localhost:3306/test" /> 
4 .            <property name= "username"  value= "root" /> 
5 .            <property name= "password"  value= "123456" /> 
6 .            <!-- 连接池启动时的初始值 --> 
7 .            <property name= "initialSize"  value= "1" /> 
8 .            <!-- 连接池的最大值 --> 
9 .            <property name= "maxActive"  value= "100" /> 
10 .            <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 --> 
11 .            <property name= "maxIdle"  value= "2" /> 
12 .            <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 --> 
13 .            <property name= "minIdle"  value= "1" /> 
14 .        </bean> 
  
  *配置事务,配置事务时,需要在xml配置文件中引入用于声明事务的tx命名空间,事务的配置有两种方式:注解方式和基于XML配置的方式
  
  
  
下面演示下使用Spring注解方式管理事务
  
首先在配置文件中配置Spring提供的事务管理器
  
 
 
Xml代码 
1 .<bean id= "txManager"  class = "org.springframework.jdbc.datasource.DataSourceTransactionManager"
2 .            <!-- 指定数据源 --> 
3 .            <property name= "dataSource"  ref= "dataSource" /> 
4 .        </bean> 
  
  由于会使用注解方式,因此我们要打开注解处理器,对注解进行解析
  
 
 
Xml代码 
1 .<tx:annotation-driven transaction-manager= "txManager" /> 
  
  
  
这样我们的配置文件配置完成,下面我们在Mysql中建立一张表,
  
 
 
Sql代码 
1 .create table users 
2 .(                    
3 . id int ( 11 ) not null  auto_increment,   
4 . username varchar( 20 ) not null ,        
5 . primary key (id)                    
6 .)  
  
  
  
根据数据库,我们创建javabean
  
 
 
Java代码 
1 . package  com.szy.spring.bean; 
2 . /**
3. * @author  coolszy
4. * @time    Dec 6, 2009 2:13:33 PM
5. */ 
6 . public  class  User 
7 .{ 
8 .    private  int  id; 
9 .    private  String username; 
10 .    public  int  getId() 
11 .    { 
12 .        return  id; 
13 .    } 
14 .    public  void  setId( int  id) 
15 .    { 
16 .        this .id = id; 
17 .    } 
18 .    public  String getUsername() 
19 .    { 
20 .        return  username; 
21 .    } 
22 .    public  void  setUsername(String username) 
23 .    { 
24 .        this .username = username; 
25 .    } 
26 .}    
  
  
  
然后创建DAO接口,在DAO中提供几个方法:
  
 
 
Java代码 
1 . package  com.szy.spring.dao; 
2
3 . import  java.util.List; 
4
5 . import  com.szy.spring.bean.User; 
6
7 . public  interface  UserDAO 
8 .{ 
9 .    public  void  save(User user); 
10 .    public  void  update(User user); 
11 .    Public User  getUser( int  id); 
12 .    public  void  delete( int  id); 
13 .    public  List<User> getAllUsers(); 
14 .}    
  
  
  
实现这个接口
  
  
  
 
 
Java代码 
1 . package  com.szy.spring.dao.impl; 
2
3 . import  java.util.List; 
4
5 . import  com.szy.spring.bean.User; 
6 . import  com.szy.spring.service.UserService; 
7
8 . /**
9. * @author  coolszy
10. * @time    Dec 6, 2009 2:19:22 PM
11. */ 
12 . public  class  UserDAOImpl implements  UserDAO 
13 .{ 
14
15 .    public  void  delete( int  id) 
16 .    { 
17
18 .    } 
19
20 .    public  List<User> getAllUsers() 
21 .    { 
22 .        return  null
23 .    } 
24
25 .    public  User getUser( int  id) 
26 .    { 
27
28 .    } 
29
30 .    public  void  save(User user) 
31 .    { 
32
33 .    } 
34
35 .    public  void  update(User user) 
36 .    { 
37
38 .    } 
39
40 .}    
  
  
  
下面把这个类交给Spring管理
  
 
 
Xml代码 
1 .<bean id= "userDAO"  class = "com.szy.spring.dao.impl.UserDAOImpl" />   
  
  由于要通过数据源对表进行操作,因此在DAO中添加数据源。
  
 
 
Java代码 
1 . private  DataSource dataSource; 
2
3 .    public  void  setDataSource(DataSource dataSource) 
4 .    { 
5 .        this .dataSource = dataSource; 
6 .    }    
  
  
  
然后在配置文件中进行配置
  
 
 
Xml代码 
1 .<bean id= "userDAO"  class = "com.szy.spring.service.impl.UserDAOImpl"
2 .            <property name= "dataSource"  ref= "dataSource" /> 
3 .        </bean>    
  
  
  
这样我们就把数据源注入到类中。
  
在UserDAOImpl类中我们提供了dataSource,这样我们就可以对数据库进行操作,但是不推荐直接使用dataSource,建议使用JdbcTemplate
  
 
 
Java代码 
1 . private  JdbcTemplate jdbcTemplate; 
2 .    public  void  setDataSource(DataSource dataSource) 
3 .    { 
4 .        //this.dataSource = dataSource; 
5 .        this .jdbcTemplate= new  JdbcTemplate(dataSource); 
6 .    }    
  
  下面我们使用jdbcTemplate对数据库进行增删改查,详细代码见附件。
  
 
 
Java代码 
1 . package  com.szy.spring.dao.impl; 
2
3 . import  java.util.List; 
4
5 . import  javax.sql.DataSource; 
6
7 . import  org.springframework.jdbc.core.JdbcTemplate; 
8
9 . import  com.szy.spring.bean.User; 
10 . import  com.szy.spring.dao.UserDAO; 
11
12 . /**
13. * @author  coolszy
14. * @time    Dec 6, 2009 2:19:22 PM
15. */ 
16 . public  class  UserDAOImpl implements  UserDAO 
17 .{ 
18 .    //private DataSource dataSource; 
19 .    private  JdbcTemplate jdbcTemplate; 
20 .    public  void  setDataSource(DataSource dataSource) 
21 .    { 
22 .        //this.dataSource = dataSource; 
23 .        this .jdbcTemplate= new  JdbcTemplate(dataSource); 
24 .    } 
25
26 .    public  void  delete( int  id) 
27 .    { 
28 .        jdbcTemplate.update( "delete from users where id=?" , new  Object[]{id}, 
29 .                new  int []{java.sql.Types.INTEGER}); 
30 .    } 
31
32 .    public  List<User> getAllUsers() 
33 .    { 
34 .        return  (List<User>)jdbcTemplate.query( "select * from users" , new  UserRowMapper()); 
35 .    } 
36
37 .    public  User getUser( int  id) 
38 .    { 
39 .        return  (User)jdbcTemplate.queryForObject( "select * from users where id=?" , new  Object[]{id},  
40 .                new  int []{java.sql.Types.INTEGER}, new  UserRowMapper()); 
41
42 .    } 
43
44 .    public  void  save(User user) 
45 .    {  
46 .        jdbcTemplate.update( "insert into users(username) values(?)" , new  Object[]{user.getUsername()}, 
47 .                new  int []{java.sql.Types.VARCHAR}); 
48
49 .    } 
50
51 .    public  void  update(User user) 
52 .    { 
53 .        jdbcTemplate.update( "update users set username=? where id=?" , new  Object[]{user.getUsername(),user.getId()}, 
54 .                new  int []{java.sql.Types.VARCHAR, java.sql.Types.INTEGER}); 
55
56 .    } 
57
58 .}    
  
  编写测试代码,代码运行正常。
  
在我们实现的每个方法中如delete()方法,如果delete方法是这样
  
 
 
Java代码 
1 . public  void  delete( int  id) 
2 .    { 
3 .        jdbcTemplate.update( "delete from users where id=?" , new  Object[]{id}, 
4 .                new  int []{java.sql.Types.INTEGER}); 
5 .jdbcTemplate.update( "delete from users where id=?" , new  Object[]{id}, 
6 .                new  int []{java.sql.Types.INTEGER}); 
7
8 .    } 
9 .     
  
  这样每条语句都会在各自的事务中执行,并不能保证在同一使用中执行,为了保证在同一事务中执行,我们应使用Spring容器提供的声明事务,我们在UserDAOImpl 类上加入 @Transactional ,表示该类受Spring事务管理。如果该类中每个方法不需要事务管理,如getUser方法,则在该方法前加入
  
 
 
Java代码 
1 . @Transactional (propagation=Propagation.NOT_SUPPORTED) 
  
  
  
  
  
PS:在上面的配置文件中我们在配置文件中指明了驱动类等信息,如果我们想写在配置文件中要怎么配置能,首先我们编写配置文件,
  
 
 
Jdbc.properties代码 
1 .driverClassName=com.mysql.jdbc.Driver 
2 .url=jdbc\:mysql\: //localhost\:3306/test 
3 .username=root 
4 .password= 123456 
5 .initialSize= 1 
6 .maxActive= 100 
7 .maxIdle= 2 
8 .minIdle= 1    
  
  然后Spring的配置文件需进行如下配置:
  
 
 
Xml代码 
1 .<context:property-placeholder location= "classpath:jdbc.properties" /> 
2 .        <bean id= "dataSource"  class = "org.apache.commons.dbcp.BasicDataSource"  destroy-method= "close"
3 .            <property name= "driverClassName"  value= "${driverClassName}" /> 
4 .            <property name= "url"  value= "${url}" /> 
5 .            <property name= "username"  value= "${username}" /> 
6 .            <property name= "password"  value= "${password}" /> 
7 .            <property name= "initialSize"  value= "${initialSize}" /> 
8 .            <property name= "maxActive"  value= "${maxActive}" /> 
9 .            <property name= "maxIdle"  value= "${maxIdle}" /> 
10 .            <property name= "minIdle"  value= "${minIdle}" /> 
11 .        </bean>    
  
   这样就可以从属性文件中读取到配置信息。
  
  
 
 
 
 
 
Spring学习笔记( 18 )----使用Spring配置文件实现事务管理
-------------------------------------------------------
由于我们要拦截UserDAOImpl中的方法,因此我们需要在配置文件中配置信息,在配置文件中使用了AOP技术来拦截方法。
  
 
 
Xml代码 
1 .<aop:config> 
2 .    <aop:pointcut id= "transactionPointcut"  expression= "execution(* com.szy.spring.dao.impl..*.*(..))" /> 
3 .    <aop:advisor advice-ref= "txAdvice"  pointcut-ref= "transactionPointcut" /> 
4 .  </aop:config>  
5 .  <tx:advice id= "txAdvice"  transaction-manager= "txManager"
6 .     <tx:attributes> 
7 .      <!-- 如果连接的方法是以get开头的方法,则不使用事务 --> 
8 .       <tx:method name= "get*"  read-only= "true"  propagation= "NOT_SUPPORTED" /> 
9 .       <tx:method name= "*" /> 
10 .     </tx:attributes> 
11 .  </tx:advice> 
  
   
  
这样Spring就能对这个类进行事务管理。
  
  
  
下面我们测试下数据库操作是否在同一事务中执行。
  
假设我们的delete方法如下:
  
 
 
Java代码 
1 . public  void  delete( int  id) 
2 . { 
3 .  jdbcTemplate.update( "delete from users where id=?" , new  Object[]{id}, 
4 .    new  int []{java.sql.Types.INTEGER}); 
5 .  jdbcTemplate.update( "delete from users1 where id=10" ); 
6 . } 
  
  
  
  
  
在第二条删除语句中,users1表是不存在的,如果两次update语句是在两个事务中执行,则第一条能成功执行,并且数据库中该id的记录已经被删除,而第二条由于不存在该表不能正常删除。如果在同一事务中执行,由于第二条update出错,数据库中不能删除任何记录。
  
测试代码:
  
 
 
Java代码 
1 . @Test 
2 . public  void  testDelete() 
3 . { 
4 .  userDAO.delete( 5 ); 
5 . } 
  
  
  程序报错,同时id= 5 的记录没有被删除。如果我们把配置文件中关于事务配置的信息给注释掉,再次测试,程序同样报错,但是id= 5 的记录被成功删除掉,这说明这两条update语句是在两个不同的事务中运行。
  
  
  
PS:在平时开发中,Spring团队建议使用注解的方式进行配置,这样配置文件显得精简,同时也会做到精确控制。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值