Spring整合Mybatis+Spring事务快速入门(纯注解)
一、项目结构说明
1、config包下放的是Spring、jdbc、mybatis配置类
2、dao包放的是使用注解写的sql语句
3、pojo跳过…
4.service包放的是一个模拟银行转账的例子
5.resources包放的是数据库的一些信息
二、Maven坐标
<dependencies>
<!-- spring配置包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!-- mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- mybatis驱动-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- mybatis spring包用于整合-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!-- spring jdbc包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!-- spring事务管理-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!-- 数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<!--测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
三、Config
1.Spring_config
@Configuration
@EnableTransactionManagement //启用声明式事务管理功能,(需要PlatformTransactionManager的实现)
@ComponentScan("com.hxx") //扫描 com.hxx包下所有的bean
@Import({Jdbc_config.class,Mybatis_config.class}) //这个是加载我们的配置类,现在还没创建那些配置类可以注释掉先
@PropertySource("classpath:db.properties") //引入额外的属性文件
public class Spring_config {
}
2.resources包下的属性文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db?serverTimezone=UTC&\
characterEncoding=utf8&useUnicode=true&useSSL=false
jdbc.username=root
jdbc.password=123456
3.Jdbc_config
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
public class Jdbc_config {
@Value("${jdbc.driver}")
private String Driver;
@Value("${jdbc.url}")
private String Url;
@Value("${jdbc.username}")
private String Username;
@Value("${jdbc.password}")
private String Password;
// 配置数据源
@Bean
public DataSource getDataSoure()
{
DruidDataSource dataSource =new DruidDataSource();
// 设置数据源
dataSource.setDriverClassName(Driver);
dataSource.setUrl(Url);
dataSource.setUsername(Username);
dataSource.setPassword(Password);
return dataSource;
}
// 配置事务管理器
@Bean
public PlatformTransactionManager platformTransactionManager(DataSource dataSource)
{
DataSourceTransactionManager transactionManager =new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
1.配置数据源
配置数据源使用的是 DruidDataSource 类,它是 DataSource的实现类。
它是Java语言中流行的数据库连接池,支持多种数据库,包括MySQL。
我们添加提供数据库信息就可以了。
2.配置事务管理器
这边使用 DataSourceTransactionManager实现类来配置我们的事务管理器
我们只需要添加我们刚才配置号的数据源传入进去就ok了
注意:@Bean的注入是在方法参数中填写需要注入的东西
4.Mybatis_config
public class Mybatis_config {
// 配置mybatis和获得sqlsessionFactory
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource)
{
SqlSessionFactoryBean ssqf =new SqlSessionFactoryBean();
//设置别名用的
// ssqf.setTypeAliasesPackage();
//设置数据源
ssqf.setDataSource(dataSource);
return ssqf;
}
//这个是用来配置Mapper接口的扫描和注册的
@Bean
public MapperScannerConfigurer mapperScannerConfigurer()
{
MapperScannerConfigurer msc =new MapperScannerConfigurer();
msc.setBasePackage("com.hxx.dao");//我的sql语句写在这个包下,所有填的是这个
return msc;
}
}
SqlSessionFactoryBean是mybatis提供给我们整合用的一个对象用于简化配置,
内部实现了FactoryBean的接口。当Spring容器启动时,会检查并创建所有定义在容器中的Bean,
对于实现了FactoryBean接口的Bean,Spring容器不会直接返回其实例,而是返回该Bean的getObject()方法返回的对象,
而SqlSessionFactoryBean就是实现了FactoryBean并且他的getObject返回的是SqlSessionFactory。
ssqf.setTypeAliasesPackage();//就是跟xml配置mybatis中这句作用一样,我这边没有使用到
↓
<typeAliases>
<package name="com.hxx.pojo"/>
</typeAliases>
spring整合Mybatis完成
数据表
四、POJO
public class Account {
private int id;
private String username;
private double balance;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public double getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
}
五、Dao包
UserDao接口
@Repository
public interface UserDao {
@Update("UPDATE account set balance =balance+#{money} WHERE username=#{inuser.username}")
int Inuser(@Param("inuser") Account inuser,@Param("money") int money);
@Update("UPDATE account set balance =balance-#{money} WHERE username=#{outuser.username}")
int Outuser(@Param("outuser") Account outuser,@Param("money") int money);
}
六、Service包
Userservice接口
public interface Userservice {
//(@Transactional开启事务管理,Spring 框架会自动为该方法开启一个事务,如果方法执行成功,则事务会被提交,如果方法执行失败,则事务会被回滚,以保证数据的一致性和完整性。)
//@Transactional
void transfer(Account inuser,Account outuser,int money);
}
UserserviceImpl实现类
@Service
public class UserserviceImpl implements Userservice {
@Autowired
UserDao userDao;
@Override
public void transfer(Account inuser, Account outuser, int money) {
userDao.Inuser(inuser,money);
int a =1/0; //模拟方法执行失败
userDao.Outuser(outuser,money);
}
}
七、测试
public class Cs_transfer {
@Test
public void Test1()
{
ApplicationContext ac =new AnnotationConfigApplicationContext(Spring_config.class);
Userservice userservice = ac.getBean(Userservice.class);
Account inuser=new Account();
Account outuser=new Account();
inuser.setUsername("张三2");
outuser.setUsername("张三");
userservice.transfer(inuser,outuser,100);
}
}
测试大致说明:由张三给张三2汇款一百元
我们来看第一次没有添加@Transactional 并且有1/0的运行结果:
这边是1/0的错然后我们来看看数据库
可以看见这边张三2加了一百块而张三却没有扣,这是因为收款的方法在1/0前面已经执行了而汇款的方法还没执行前面已经有异常了
那我们把事务管理器开启再执行一次:
public interface Userservice {
//开启
@Transactional
void transfer(Account inuser,Account outuser,int money);
}
可以看到这边运行报错,而且张三2的钱也没有继续的添加,这就是事务的作用
把1/0删掉就可以正常运行了
[外链图片转存中…(img-WJfk5bpl-1714913118716)]
那我们把事务管理器开启再执行一次:
public interface Userservice {
//开启
@Transactional
void transfer(Account inuser,Account outuser,int money);
}
[外链图片转存中…(img-DpjP8S5d-1714913118716)]
可以看到这边运行报错,而且张三2的钱也没有继续的添加,这就是事务的作用
[外链图片转存中…(img-8wc0nCBE-1714913118716)]
把1/0删掉就可以正常运行了
注:事务还可以设置隔离级别、传播行为等等…(可查看本章绑定的资源有对事务管理的知识补充)