博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring学习(四)
阅读量:4024 次
发布时间:2019-05-24

本文共 8099 字,大约阅读时间需要 26 分钟。

 
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团队建议使用注解的方式进行配置,这样配置文件显得精简,同时也会做到精确控制。

转载地址:http://rsfbi.baihongyu.com/

你可能感兴趣的文章
struts标签介绍大全
查看>>
logic:iterate用法详解
查看>>
关于导出数据为Excel的几种方式
查看>>
Display Tag使用小记
查看>>
如何给按钮加上链接功能
查看>>
深入MySQL数据库的索引
查看>>
Hashtable和HashMap的区别
查看>>
深入MySQL数据库的索引
查看>>
wml表单提交
查看>>
Log4J的配置详解
查看>>
JSP中EL表达式无效问题
查看>>
java中关于时间日期操作的常用函数
查看>>
Serializable java序列化
查看>>
用Eclipse MyEclipse WebLogic8.1开发第一个Web程序
查看>>
HTTP深入浅出
查看>>
http协议技术资料
查看>>
MyEclipse安装aptana插件的问题
查看>>
Android环境搭建_转载
查看>>
JS操作SELECT表单大全,赋默认值,取值,增,删等
查看>>
浅谈BigDecimal类在电子商务中至关重要的地位!
查看>>