【Spring框架09】spring数据库及事务
思维导图
一、整合jdbc查询数据库
1.数据库环境配置
2.添加maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lcy</groupId>
<artifactId>spring08-AOP</artifactId>
<version>1.0-SNAPSHOT</version>
<name>spring08-AOP</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- Aop依赖 只支持xml(spring自带)-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- 支持注解(第三方)-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>
<!-- mysql驱动-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- c3p0连接池-->
<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- spring jdbc-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!-- spring事物-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
</dependencies>
<build>
</build>
</project>
3.配置dp.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mygame?useUnicode=true&characterEncoding=utf8
jdbc.user=root
jdbc.password=root
4.bean.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<context:component-scan base-package="com.lcy"/>
<!-- 开启aop代理-->
<aop:aspectj-autoproxy/>
<!-- 加载数据库配置-->
<context:property-placeholder location="dp.properties"></context:property-placeholder>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- jdbcTemplate 配置-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
如果不配置xml,也可以用
ResourceBundle resourceBundle =ResourceBundle.getBundle("dp");
String driver = resourceBundle.getString("jdbc.driver");
5.测试整合结果
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class TestJdbc {
private JdbcTemplate template;
//是单元测试的before
@Before
public void init(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
template=(JdbcTemplate) context.getBean("jdbcTemplate");
}
@Test
public void test01(){
String sql="select count(*) from user";
Integer total = template.queryForObject(sql,Integer.class);
System.out.println("Total:"+total);
}
}
二、利用上诉整合实现转账功能模拟
1.配置dao层接口和方法,实现数据库语句
@Repository
public class AccountDao {
@Autowired
private JdbcTemplate template;
// 出账
public void outMonet(Integer accountId,Integer money){
//更行操作
String sql="UPDATE account set money=money-? where id=?";
template.update(sql,money,accountId);
}
// 转账
public void inMonet(Integer accountId,Integer money){
//更行操作
String sql="UPDATE account set money=money+? where id=?";
template.update(sql,money,accountId);
}
}
2.配置service,处理用户的请求
@Service
public class AccountService {
@Autowired
/**
* 转账操作
* outAccount:转出账户
* inAccount: 转入用户
* money:转账金额
*/
private AccountDao accountDao;
public void exchange(Integer outAccount,Integer inAccount,Integer money){
accountDao.outMonet(outAccount,money);
accountDao.inMonet(inAccount,money);
}
}
3.编写测试类,模拟转账过程
public class TestJdbc {
private AccountService accountService;
//是单元测试的before
@Before
public void init(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
accountService = (AccountService)context.getBean("accountService");
}
@Test
public void test02(){
accountService.exchange(1,2,100);
}
}
三、 spring事务
现在我们改变上诉代码,令转账功能出现报错,发现转出功能还是执行了
public void updateExchange(Integer outAccount,Integer inAccount,Integer money){
accountDao.outMonet(outAccount,money);
int i=1/0;
accountDao.inMonet(inAccount,money);
}
我们就可以利用aop的事务回滚功能,实现如果系统错误,则不进行事务处理的功能
(1)配置xml文件,实现aop的事务回滚功能
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
">
<context:component-scan base-package="com.lcy"/>
<!-- 开启aop代理-->
<aop:aspectj-autoproxy/>
<!-- 加载数据库配置-->
<context:property-placeholder location="dp.properties"></context:property-placeholder>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- jdbcTemplate 配置-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事物管理器配置-->
<bean id="txManage" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置通知-->
<tx:advice id="txAdvice" transaction-manager="txManage">
<tx:attributes>
<!-- 匹配save,del,update开头的service方法均加入到事物中-->
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<!-- 匹配query开头的service方法为只读模式-->
<tx:method name="query*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- aop切面定义-->
<aop:config>
<!-- 对事物进行回滚-->
<aop:pointcut id="cut" expression="execution(* com.lcy.service..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="cut"/>
</aop:config>
</beans>
现在再来执行代码,就可以很清楚地看到,系统报错,数据库中的转账和进账功能均不执行。
(2)用注解功能来实现
只需要配置事务管理,和开启注解功能
<bean id="txManage" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启注解功能-->
<tx:annotation-driven transaction-manager="txManage"/>
在需要执行数据库语句的类添加注解
@Transactional(propagation = Propagation.REQUIRED)
public void exchange(Integer outAccount,Integer inAccount,Integer money){
accountDao.outMonet(outAccount,money);
accountDao.inMonet(inAccount,money);
}