牧场SZShepherd 2020-07-20
简单搭建一个mybatis环境实现转账的模拟操作
项目列表
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.3</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.2.RELEASE</version> </dependency> </dependencies>
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; DROP TABLE IF EXISTS `account`; CREATE TABLE `account` ( `id` int(11) NOT NULL AUTO_INCREMENT, `account_name` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `money` float NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; INSERT INTO `account` VALUES (1, ‘aa‘, 1000); INSERT INTO `account` VALUES (2, ‘bb‘, 1000); INSERT INTO `account` VALUES (3, ‘cc‘, 1000); SET FOREIGN_KEY_CHECKS = 1;
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="db.properties"> <!--加载外部properties文件--> <!--<property name="driverClass" value="com.mysql.jdbc.Driver123"/>--> </properties> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <typeAliases> <package name="com.qiliang.pojo"/> </typeAliases> <!--mybatis环境的配置--> <environments default="test"> <environment id="test"> <!--事务管理器:由JDBC来管理--> <transactionManager type="JDBC"/> <!--数据源的配置:mybatis自带的连接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <mappers> <mapper class="com.qiliang.dao.AccountDao"/> </mappers> </configuration> <!-- db.properties 文件信息 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/数据库名?allowMultiQueries=true(执行多条SQL) jdbc.username=root jdbc.password=root -->
log4j.rootLogger=debug, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
public class SessionFactoryUtils { //声明一个工厂对象 private static SqlSessionFactory factory; //在静态代码块中创建会话工厂 static { SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //得到输入流 try (InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml")) { factory = builder.build(inputStream); } catch (IOException e) { e.printStackTrace(); } } public static SqlSessionFactory getSessionFactory() { return factory; } public static SqlSession getSession() { return factory.openSession(); //自动提交事务 } }
@Configuration @ComponentScan("com.qiliang") public class Config { }
public class Account { private int id; private String accountName; private Float money; //省略set、get、toString }
public interface AccountDao { @Select("select * from account") List<Account> findAll(); @Update("update account set money=money - #{money} where account_name = #{name}") void out(@Param("name")String outName,@Param("money")float money); @Update("update account set money=money + #{money} where account_name = #{name}") void in(@Param("name")String inName,@Param("money")float money); }
@Service public class AccountService { private SqlSession session = SessionFactoryUtils.getSession(); private AccountDao mapper = session.getMapper(AccountDao.class); //查询测试 public List<Account> findAll() { return mapper.findAll(); } /** * @param outName 支出账户 * @param inName 收入账户 * @param money 转账金额 */ public boolean transfer(String outName, String inName, float money) { try { //转出 mapper.out(outName, money); int i=1/0; //模拟异常 //转入 mapper.in(inName, money); } catch (Exception e) { //事务回滚 session.rollback(); System.out.println("失败原因:"+e.getMessage()); return false; } //提交事务 session.commit(); return true; } }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = Config.class) public class AccountWeb { @Autowired private AccountService accountService; @Test public void test01(){ List<Account> list = accountService.findAll(); for (Account account : list) { System.out.println(account); } } /** * outName 支出账户 * inName 收入账户 * money 转账金额 */ @Test public void test02(){ boolean result = accountService.transfer("aa", "bb", 100); if(result){ System.out.println("转账成功"); } else { System.out.println("转账失败"); } } }
结果不做演示,可以多次把异常 和 回滚事务的代码注释掉,看运行的区别