Spring框架进阶3

测试spring_jdbc和spring对事务的管理

Spring框架进阶3-LMLPHP

先配置相应的pom

<?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.spring</groupId>
<artifactId>spring_3</artifactId>
<version>1.0-SNAPSHOT</version> <!-- 属性 -->
<properties>
<!-- 设置编译版本为1.7 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<!-- 可以绑定版本号 -->
<spring.version>4.3.5.RELEASE</spring.version>
</properties> <!-- 锁定版本,struts2-2.3.24、spring4.2.4、hibernate5.0.7 -->
<dependencyManagement>
<dependencies>
<!-- 核心包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency> <!-- pring IOC的基础实现,包含访问配置文件、创建和管理bean等 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</dependencyManagement> <!-- 依赖管理 -->
<dependencies>
<!-- spring相关包 -->
<!-- 核心包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency> <!-- pring IOC的基础实现,包含访问配置文件、创建和管理bean等 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency> <!-- 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency> <!-- c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency> <!-- junit,4.12支持注解测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency> <!-- aop联盟 -->
<dependency>
<groupId>org.aopalliance</groupId>
<artifactId>com.springsource.org.aopalliance</artifactId>
<version>1.0.0</version>
</dependency> <!-- weaver织入包 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>com.springsource.org.aspectj.weaver</artifactId>
<version>1.6.4.RELEASE</version>
</dependency> </dependencies>
</project>

相应的连接池和配置文件

#加jdbc前缀的目的是为了避免后面的名字与其他地方名字冲突
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
jdbc.username=root
jdbc.password=admins
<?xml version="1.0" encoding="UTF-8"?>
<!-- 头部约束的作用:beans:最基本;context:读取资源文件;aop:配置aop;tx:配置事务通知 -->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
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-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd "> <!-- 读取连接池配置文件 -->
<context:property-placeholder location="jdbc.properties"/> <!-- 1.将连接池放入spring容器 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- set注入 -->
<!--<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///test"/>
<property name="user" value="root"/>
<property name="password" value="admins"/>--> <!-- 资源文件配置 -->
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean> <!-- 2.将JdbcTemplate放入spring容器 -->
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean> <!-- 3.将UserDao放入spring容器 -->
<bean name="userDao" class="com.dao.UserDaoImpl">
<property name="jt" ref="jdbcTemplate"/>
</bean> <!-- 无需依赖JdbcTemplate -->
<!-- 2.AccountDao放入spring容器 -->
<bean name="accountDao" class="com.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean> <!-- 3.AccountService放入spring容器 -->
<bean name="accountService" class="com.service.AccountServiceImpl">
<property name="dao" ref="accountDao"/>
<property name="template" ref="transactionTemplate"/>
</bean> <!-- 3种事务管理方式 -->
<!-- 事务核心管理器,封装了事务的所有操作,依赖连接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 依赖注入 -->
<property name="dataSource" ref="dataSource"/>
</bean> <!-- 1:编码方式;事务模板对象 -->
<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean> <!-- 2:xml配置;配置事务通知 -->
<tx:advice transaction-manager="transactionManager" id="txAdvice">
<tx:attributes>
<!-- isolation:隔离级别;propagation:传播行为 ;read-only:只读-->
<!-- 以方法名为单位进行配置 -->
<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<!-- 通常都会加通配符进行配置 -->
<tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
<tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice> <!-- 配置织入 -->
<aop:config>
<!-- 目标对象 -->
<aop:pointcut id="txPc" expression="execution(* com.service.*ServiceImpl.*(..))"/>
<!-- 配置切面:advice-ref:通知;pointcut-ref:切入点 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
</aop:config> <!-- 开启使用注解管理aop事务 -->
<tx:annotation-driven/>
</beans>

数据库不提供了,先来个bean

package com.bean;

/**
* @author: XDZY
* @date: 2018/9/9 14:55
* @description: 实体bean
*/
public class User {
private int id;
private String name; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}

测试jdbc模板

package com.dao;

import com.bean.User;

import java.util.List;

/**
* @author: XDZY
* @date: 2018/9/9 14:56
* @description: 操作user接口
*/
public interface UserDao {
/**
* 增
*
* @param user
*/
void save(User user); /**
* 根据用户ID删除
*
* @param id
*/
void delUserById(Integer id); /**
* 改
*
* @param user
*/
void update(User user); /**
* 根据用户ID查询
*
* @param id
* @return
*/
User findUserById(Integer id); /**
* 查询用户数量
*
* @return
*/
int findCount(); /**
* 查询所有用户
*
* @return
*/
List<User> findUserList();
}
package com.dao;

import com.bean.User;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List; /**
* @author: XDZY
* @date: 2018/9/9 15:02
* @description: 使用jdbc模板实现增删改查
*/
public class UserDaoImpl implements UserDao {
private JdbcTemplate jt; public void setJt(JdbcTemplate jt) {
this.jt = jt;
} @Override
public void save(User user) {
String sql = "insert into user_info values(0,?)";
jt.update(sql, user.getName());
} @Override
public void delUserById(Integer id) {
String sql = "delete from user_info where id=?";
jt.update(sql, id);
} @Override
public void update(User user) {
String sql = "update user_info set name=? where id=?";
jt.update(sql, user.getName(), user.getId());
} @Override
public User findUserById(Integer id) {
String sql = "select * from user_info where id=?";
return jt.queryForObject(sql, new RowMapper<User>() {//匿名内部类
//ResultSet:结果集;int i:第几行,即第几个数据
@Override
public User mapRow(ResultSet rs, int i) throws SQLException {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
return user;
}
}, id);
} @Override
public int findCount() {
String sql = "select count(*) from user_info";
Integer count = jt.queryForObject(sql, Integer.class);
return count;
} @Override
public List<User> findUserList() {
String sql = "select * from user_info";
List<User> list = jt.query(sql, new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int i) throws SQLException {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
return user;
}
});
return list;
}
}
package com.jabcDemo;

import com.bean.User;
import com.dao.UserDao;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; /**
* @author: XDZY
* @date: 2018/9/9 13:50
* @description: 演示jdbc模板
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
@Resource(name = "userDao")
private UserDao userDao; @Test
public void test() throws Exception {
//准备连接池
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///test");
dataSource.setUser("root");
dataSource.setPassword("admins"); //创建jdbc模板对象
JdbcTemplate jt = new JdbcTemplate();
jt.setDataSource(dataSource); //书写sql,并执行
String sql = "insert into user_info values(0,'day')";
jt.update(sql);
} @Test
public void test1() throws Exception {
User user = new User();
user.setName("tom");
userDao.save(user);
} @Test
public void test2() throws Exception {
User u = new User();
u.setId(2);
u.setName("jack");
userDao.update(u); } @Test
public void fun4() throws Exception {
userDao.delUserById(2);
} @Test
public void fun5() throws Exception {
System.out.println(userDao.findCount());
} @Test
public void fun6() throws Exception {
System.out.println(userDao.findUserById(1));
} @Test
public void fun7() throws Exception {
System.out.println(userDao.findUserList());
}
}

测试事务管理方式

package com.dao;

/**
* @author: XDZY
* @date: 2018/9/9 16:54
* @description: 事务的操作
*/
public interface AccountDao {
/**
* 加钱
*
* @param id
* @param money
*/
void increaseMoney(Integer id, double money); /**
* 减钱
*
* @param id
* @param money
*/
void decreaseMoney(Integer id, double money);
}
package com.dao;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

/**
* @author: XDZY
* @date: 2018/9/9 16:57
* @description: 不用jdbc模板,扩展知识(继承JdbcDaoSupport直接依赖连接池就行)
*/
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
@Override
public void increaseMoney(Integer id, double money) {
getJdbcTemplate().update("update t_acount set money=money+? where id=?", money, id);
} @Override
public void decreaseMoney(Integer id, double money) {
getJdbcTemplate().update("update t_acount set money=money-? where id=?", money, id);
}
}
package com.service;

/**
* @author: XDZY
* @date: 2018/9/9 17:03
* @description: 逻辑运算
*/
public interface AccountService {
/**
* 转账方法
*
* @param from
* @param to
* @param money
*/
void transfer(Integer from, Integer to, double money);
}
package com.service;

import com.dao.AccountDao;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate; /**
* @author: XDZY
* @date: 2018/9/9 17:06
* @description: 逻辑运算
* 注解也可以加在类上;个别情况个别写
*/
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, readOnly = true)
public class AccountServiceImpl implements AccountService {
private AccountDao dao;
/**
* 事务模板
*/
private TransactionTemplate template; public void setDao(AccountDao dao) {
this.dao = dao;
} public void setTemplate(TransactionTemplate template) {
this.template = template;
} //转账操作;匿名内部类要访问外部数据要加final
//事务模板已经封装好,只需提供操作
//模板过程(1.打开事务 2.调用doInTransactionWithoutResult方法 3.提交事务)
/*@Override
public void transfer(final Integer from,final Integer to,final double money) {
//根据不同的模板调用相应的接口
//不同的框架对事务的操作是不同的,但是事务的操作流程是一样的;所以spring提供接口来管理事务
template.execute(new TransactionCallbackWithoutResult() {
//实现对事务的管理
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
//减钱
dao.decreaseMoney(from,money);
//制造异常,测试事务是否有效;就是出现异常还会不会转钱
//int i=1/0;
//加钱
dao.increaseMoney(to,money);
}
});
}*/ //xml方式管理事务
//注解方式管理事务
@Override
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, readOnly = false)
public void transfer(Integer from, Integer to, double money) {
//减钱
dao.decreaseMoney(from, money);
//制造异常,测试事务是否有效;就是出现异常还会不会转钱
//int i=1/0;
//加钱
dao.increaseMoney(to, money);
}
}
package com.jabcDemo;

import com.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; /**
* @author: XDZY
* @date: 2018/9/9 13:50
* @description: 事务的操作
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo2 {
@Resource(name = "accountService")
private AccountService as; @Test
public void test() {
//1给2转账500元
as.transfer(1, 2, 500d);
}
}
05-11 15:19